-- 作者:bhwhui
-- 发布时间:2009/11/23 21:44:16
--
作为著名的系统交易规则,海龟法则一直是程序化爱好者的必修课,
以上是简介,读者感兴趣可以自己下载电子版阅读。
金字塔系统所带的法则仅是多头版本,试着改写了一下多空版本,不对之处请指教。
input:trn(20,5,30),hn(20,5,30),ln(10,5,20);
VARIABLE:dayCount=1,PositionCount=1,SellSign=0,dK=0;//加多空标志,1:多,-1:空 0:空仓 VARIABLE:EntAndExitSign=1,EntPoint=0,ExitPoint=0; VARIABLE:N=0;
N:=MA(TR,trn); BUYHHV:=HHV(H,hn); SELLLLV:=LLV(L,ln);
sellshortllv:=llv(l,hn); buyshorthhv:=hhv(h,ln);
IF BARPOS>=hn THEN BEGIN IF BARPOS=hn THEN IF DayCount=hn/2 OR BARPOS=hn THEN BEGIN{hn/2天调整N值} N:=((hn-1)*N+TR)/hn;{计算N值} DayCount:=2; END DayCount:=DayCount+1; EntPoint:=ENTERBARS+1; IF EntPoint=EntAndExitSign THEN BEGIN{说明STOP指令买进头寸成功} PositionCount:=PositionCount+1;{头寸计数} SellSign:=True;{可以平仓信号,如果达到指定的价格} END IF PositionCount=1 THEN BEGIN{第一头寸} HOW:=CASH(0)*0.01/N;{波动性百分比决定头寸规模} if high=buyhhv then BEGIN dk:=1; 多开1:BUY(1,HOW,STOP,BUYHHV);{在20日新高STOP指令买进} END; if low=sellshortllv then begin dk:=-1; 空开1:buyshort(1,HOW,STOP,sellshortllv);{在20日新低STOP指令空开} end; END
IF PositionCount=2 THEN BEGIN{如到第二头寸} HOW:=CASH(0)*0.01/N;{波动性百分比决定头寸规模} if dk=1 then 多开2:BUY(1,HOW,STOP,ENTERPRICE+0.5*N);{在上头寸(即第一头寸)+0.5个N以STOP指令买进} if dk=-1 then 空开2:buyshort(1,HOW,STOP,ENTERPRICE-0.5*N); END
IF PositionCount=3 THEN BEGIN{如到第三头寸} HOW:=CASH(0)*0.01/N; if dk=1 then 多开3:BUY(1,HOW,STOP,ENTERPRICE+0.5*N);{在上头寸(即第二头寸)+0.5个N以STOP指令买进} if dk=-1 then 空开3:buyshort(1,HOW,STOP,ENTERPRICE-0.5*N); END
IF PositionCount=4 THEN BEGIN HOW:=CASH(0)*0.01/N; if dk=1 then 多开4:BUY(1,HOW,STOP,ENTERPRICE+0.5*N); if dk=-1 then 空开4:buyshort(1,HOW,STOP,ENTERPRICE-0.5*N); END
IF SellSign=True THEN BEGIN ExitPoint:=EXITBARS+1; if dk=1 then begin IF ExitPoint=EntAndExitSign THEN BEGIN {说明卖出成功} PositionCount:=1;{头寸计算复原} SellSign:=False; dk:=0; END IF ENTERPRICE-2*N then SELL(1,100%,STOP,SELLLLV);{退出离盈利头寸} ELSE SELL(1,100%,STOP,ENTERPRICE-2*N);{退出亏损头寸} end; if dk=-1 then begin IF ExitPoint=EntAndExitSign THEN BEGIN PositionCount:=1; SellSign:=False; dk:=0; END IF ENTERPRICE+2*N then sellSHORT(1,100%,STOP,BUYSHORTHHV); ELSE sellSHORT(1,100%,STOP,ENTERPRICE+2*N); END; END END;
|
-- 作者:bhwhui
-- 发布时间:2009/11/23 23:18:56
--
奇怪,我的编译器能通过。。。。
那就替换一下ln吧:
input:trn(20,5,30),hn(20,5,30),lown(10,5,20);
VARIABLE:dayCount=1,PositionCount=1,SellSign=0,dK=0;//加多空标志,1:多,-1:空 0:空仓 VARIABLE:EntAndExitSign=1,EntPoint=0,ExitPoint=0; VARIABLE:N=0;
N:=MA(TR,trn); BUYHHV:=HHV(H,hn); SELLLLV:=LLV(L,lown);
sellshortllv:=llv(l,hn); buyshorthhv:=hhv(h,lown);
IF BARPOS>=hn THEN BEGIN IF BARPOS=hn THEN IF DayCount=hn/2 OR BARPOS=hn THEN BEGIN{hn/2天调整N值} N:=((hn-1)*N+TR)/hn;{计算N值} DayCount:=2; END DayCount:=DayCount+1; EntPoint:=ENTERBARS+1; IF EntPoint=EntAndExitSign THEN BEGIN{说明STOP指令买进头寸成功} PositionCount:=PositionCount+1;{头寸计数} SellSign:=True;{可以平仓信号,如果达到指定的价格} END IF PositionCount=1 THEN BEGIN{第一头寸} HOW:=CASH(0)*0.01/N;{波动性百分比决定头寸规模} if high=buyhhv then BEGIN dk:=1; 多开1:BUY(1,HOW,STOP,BUYHHV);{在20日新高STOP指令买进} END; if low=sellshortllv then begin dk:=-1; 空开1:buyshort(1,HOW,STOP,sellshortllv);{在20日新低STOP指令空开} end; END
IF PositionCount=2 THEN BEGIN{如到第二头寸} HOW:=CASH(0)*0.01/N;{波动性百分比决定头寸规模} if dk=1 then 多开2:BUY(1,HOW,STOP,ENTERPRICE+0.5*N);{在上头寸(即第一头寸)+0.5个N以STOP指令买进} if dk=-1 then 空开2:buyshort(1,HOW,STOP,ENTERPRICE-0.5*N); END
IF PositionCount=3 THEN BEGIN{如到第三头寸} HOW:=CASH(0)*0.01/N; if dk=1 then 多开3:BUY(1,HOW,STOP,ENTERPRICE+0.5*N);{在上头寸(即第二头寸)+0.5个N以STOP指令买进} if dk=-1 then 空开3:buyshort(1,HOW,STOP,ENTERPRICE-0.5*N); END
IF PositionCount=4 THEN BEGIN HOW:=CASH(0)*0.01/N; if dk=1 then 多开4:BUY(1,HOW,STOP,ENTERPRICE+0.5*N); if dk=-1 then 空开4:buyshort(1,HOW,STOP,ENTERPRICE-0.5*N); END
IF SellSign=True THEN BEGIN ExitPoint:=EXITBARS+1; if dk=1 then begin IF ExitPoint=EntAndExitSign THEN BEGIN {说明卖出成功} PositionCount:=1;{头寸计算复原} SellSign:=False; dk:=0; END IF ENTERPRICE-2*N then SELL(1,100%,STOP,SELLLLV);{退出离盈利头寸} ELSE SELL(1,100%,STOP,ENTERPRICE-2*N);{退出亏损头寸} end; if dk=-1 then begin IF ExitPoint=EntAndExitSign THEN BEGIN PositionCount:=1; SellSign:=False; dk:=0; END IF ENTERPRICE+2*N then sellSHORT(1,100%,STOP,BUYSHORTHHV); ELSE sellSHORT(1,100%,STOP,ENTERPRICE+2*N); END; END END;
|
-- 作者:bhwhui
-- 发布时间:2009/11/23 23:21:55
--
大家有空可以研究一下第一代的Turtle和现在的不同:
作者的说明:
This is the original Turtle Trader System as described on the German website
http://keplerweb.oeh.uni-linz.ac.at/trading/turtletradingrules.htm
The only difference is: The position is not calculated with N.
Best regards Odelys
哦,不是用金字塔写的,语法类似。
var N, L1, S1, L2, S2, L3, S3, L4, S4, SE, LE, SL: float; var BAR, P : integer;
for Bar := 20 to BarCount - 1 do begin //ApplyAutoStops(bar); if PriceClose(bar) > 5000 then setpositionsize(priceclose(bar)*1.1); N := ATR( Bar, 20 ); L1 := Highest( Bar, #High, 20); S1 := Lowest( Bar, #Low, 20); L2 := L1 +0.5*N; S2 := S1 -0.5*N; L3 := L2 +0.5*N; S3 := S2 -0.5*N; L4 := L3 +0.5*N; S4 := S3 -0.5*N; SE := Highest( Bar, #High, 10); LE := Lowest( Bar, #Low, 10);
if ActivePositionCount=3 then begin BuyAtStop( Bar + 1, L4, \'L4\'); ShortAtStop (Bar + 1, S4, \'S4\'); end; if ActivePositionCount=2 then begin BuyAtStop( Bar + 1, L3, \'L3\'); ShortAtStop (Bar + 1, S3, \'S3\'); end; if ActivePositionCount=1 then begin BuyAtStop( Bar + 1, L2, \'L2\'); ShortAtStop (Bar + 1, S2, \'S2\'); end; if ActivePositionCount = 0 then begin BuyAtStop( Bar + 1, L1, \'L1\'); ShortAtStop (Bar + 1, S1, \'S1\'); end; for p := 0 to PositionCount -1 do begin if PositionActive(p) then if Positionlong(p) then SL := PositionEntryPrice(p)-2*N else SL := PositionEntryPrice(p)+2*N; end; for p := 0 to PositionCount -1 do begin if PositionActive(p) then if Positionlong(p) then SellAtStop( Bar + 1, SL, p, \'LongStop\') else CoverAtStop( Bar + 1, SL, p, \'ShortStop\'); if PositionActive(p) then if Positionlong(p) then SellAtStop( Bar + 1, LE, p, \'LongExit\') else CoverAtStop( Bar + 1, SE, p, \'ShortExit\'); end; end;
|
-- 作者:bhwhui
-- 发布时间:2009/11/23 23:24:15
--
Ver2.0
Same as V1, but N is kept constant after a position has been opened.
var N, L1, S1, L2, S2, L3, S3, L4, S4, SE, LE, SL: float; var BAR, P : integer;
for Bar := 20 to BarCount - 1 do begin //ApplyAutoStops(bar); if PriceClose(bar) > 5000 then setpositionsize(priceclose(bar)*1.1); SE := Highest( Bar, #High, 10); LE := Lowest( Bar, #Low, 10);
if ActivePositionCount=3 then begin BuyAtStop( Bar + 1, L4, \'L4\'); ShortAtStop (Bar + 1, S4, \'S4\'); end; if ActivePositionCount=2 then begin BuyAtStop( Bar + 1, L3, \'L3\'); ShortAtStop (Bar + 1, S3, \'S3\'); end; if ActivePositionCount=1 then begin BuyAtStop( Bar + 1, L2, \'L2\'); ShortAtStop (Bar + 1, S2, \'S2\'); end; if ActivePositionCount = 0 then begin N := ATR( Bar, 20 ); L1 := Highest( Bar, #High, 20); S1 := Lowest( Bar, #Low, 20); L2 := L1 +0.5*N; S2 := S1 -0.5*N; L3 := L2 +0.5*N; S3 := S2 -0.5*N; L4 := L3 +0.5*N; S4 := S3 -0.5*N; BuyAtStop( Bar + 1, L1, \'L1\'); ShortAtStop (Bar + 1, S1, \'S1\'); end; for p := 0 to PositionCount -1 do begin if PositionActive(p) then if Positionlong(p) then SL := PositionEntryPrice(p)-2*N else SL := PositionEntryPrice(p)+2*N; end; for p := 0 to PositionCount -1 do begin if PositionActive(p) then if Positionlong(p) then SellAtStop( Bar + 1, SL, p, \'LongStop\') else CoverAtStop( Bar + 1, SL, p, \'ShortStop\'); if PositionActive(p) then if Positionlong(p) then SellAtStop( Bar + 1, LE, p, \'LongExit\') else CoverAtStop( Bar + 1, SE, p, \'ShortExit\'); end; end;
|
-- 作者:bhwhui
-- 发布时间:2009/11/23 23:27:37
--
var ChannelUp, ChannelDn, LongExit, ShrtExit, FailsafeUp, FailsafeDn : integer; var N, L1, S1, L2, S2, L3, S3, L4, S4, SE, LE, SL, FU, FD, Account, Tick: float; var topSL, lowSL : float; var Bar, p, SinceLast : integer; var LeadBars : integer; var cond20 : boolean;
{ Parameters input } ChannelUp := 20 ; ChannelDn := 20 ; LongExit := 10 ; ShrtExit := 10 ; FailsafeUp := 55 ; FailsafeDn := 55 ; Account := 1000000 ; //This is the notional account
{ Cosmetics and general info } HideVolume ; EnableNotes(false); tick := GetTick ;
{ Indicators plotting } PlotSeries( HighestSeries( #High, ChannelUp ), 0, #blue, #Thin ); PlotSeries( LowestSeries( #Low, ChannelDn ), 0, #fuchsia, #Thin ); PlotSeries( HighestSeries( #High, ShrtExit ), 0, #green, #Dotted ); PlotSeries( LowestSeries( #Low, LongExit ), 0, #red, #Dotted ); PlotSeries( HighestSeries( #High, FailsafeUp ), 0, #purple, #Dotted ); PlotSeries( LowestSeries( #Low, FailsafeDn ), 0, #purple, #Dotted );
{ MAIN CYCLE } LeadBars := Trunc(max(FailsafeUp, FailsafeDn)); // Failsafe > Channel and Failsafe > Exit for Bar := LeadBars to BarCount - 1 do begin SE := Highest( Bar, #High, ShrtExit) + tick ; LE := Lowest( Bar, #Low, LongExit) - tick ;
{ Entering the first position } if PositionCount = 0 then begin N := ATR( Bar, 20 ); // N calculation SetShareSize(Int( (Account * 0.01) / (N * GetPointValue))); // Unit L1 := Highest( Bar, #High, ChannelUp); S1 := Lowest( Bar, #Low, ChannelDn); L2 := L1 + 0.5 * N ; S2 := S1 - 0.5 * N ; L3 := L2 + 0.5 * N ; S3 := S2 - 0.5 * N ; L4 := L3 + 0.5 * N ; S4 := S3 - 0.5 * N ; BuyAtStop( Bar + 1, L1, \'L1 \' + FormatFloat( \'#0.00\', L1)); ShortAtStop (Bar + 1, S1, \'S1 \' + FormatFloat( \'#0.00\', S1)); end; // of \'if PositionCount = 0 then\' { Entering next positions } if PositionCount > 0 then begin if ActivePositionCount=3 then begin BuyAtStop( Bar + 1, L4, \'L4 \'+ FormatFloat( \'#0.00\', L4)); ShortAtStop (Bar + 1, S4, \'S4 \'+ FormatFloat( \'#0.00\', S4)); end; if ActivePositionCount=2 then begin BuyAtStop( Bar + 1, L3, \'L3 \'+ FormatFloat( \'#0.00\', L3)); ShortAtStop (Bar + 1, S3, \'S3 \'+ FormatFloat( \'#0.00\', S3)); end; if ActivePositionCount=1 then begin BuyAtStop( Bar + 1, L2, \'L2 \'+ FormatFloat( \'#0.00\', L2)); ShortAtStop (Bar + 1, S2, \'S2 \'+ FormatFloat( \'#0.00\', S2)); end; if ActivePositionCount = 0 then begin { cond20 will be set true if any of the conditions listed on page 19 has been met } cond20 := false ; N := ATR( Bar, 20 ); // N calculation
{ Condition 1: last position was unprofitable } if PositionProfit( LastPosition ) < 0 then cond20 := true;
{ Condition 2 and 3: last position = long and price has moved against it > 2N or last position = short and price has moved against it > 2N} SinceLast := (Bar - PositionExitBar(LastPosition) + 1) ; topSL := Highest( Bar, #High, SinceLast) ; lowSL := Lowest( Bar, #Low, SinceLast) ; if ( PositionLong(LastPosition) and lowSL < PositionExitPrice(LastPosition) + 2*N ) then cond20 := true; if ( PositionShort(LastPosition) and topSL > PositionExitPrice(LastPosition) + 2*N ) then cond20 := true; end; // of cond20 setting
if ActivePositionCount = 0 then begin if cond20 = true then begin SetShareSize(Int( (Account * 0.01) / (N * GetPointValue))); // Unit L1 := Highest( Bar, #High, ChannelUp); S1 := Lowest( Bar, #Low, ChannelDn); L2 := L1 + 0.5 * N ; S2 := S1 - 0.5 * N ; L3 := L2 + 0.5 * N ; S3 := S2 - 0.5 * N ; L4 := L3 + 0.5 * N ; S4 := S3 - 0.5 * N ; BuyAtStop( Bar + 1, L1, \'L1 \'+ FormatFloat( \'#0.00\', L1)); ShortAtStop (Bar + 1, S1, \'S1 \'+ FormatFloat( \'#0.00\', S1)); end // of cases where cond20 = true else begin SetShareSize(Int( (Account * 0.01) / (N * GetPointValue))); // Unit FU := Highest( Bar, #High, FailsafeUp); FD := Lowest( Bar, #Low, FailsafeDn); L2 := FU + 0.5 * N ; S2 := FD - 0.5 * N ; L3 := L2 + 0.5 * N ; S3 := S2 - 0.5 * N ; L4 := L3 + 0.5 * N ; S4 := L3 - 0.5 * N ; BuyAtStop( Bar + 1, FU, \'FU\'); ShortAtStop (Bar + 1, FD, \'FD\'); end; // of cases where cond20 = false end; // of entering positions ActivePositionCount = 0 end; // of buying rules when PositionCount > 0 and ActivePositions = 0
{ Define the stop loss level } if PositionCount > 0 then if PositionActive(LastPosition) then if PositionLong(LastPosition) then SL := PositionEntryPrice(LastPosition) - 2 * N else SL := PositionEntryPrice(LastPosition) + 2 * N ;
{ Check for position exit conditions } for p := 0 to PositionCount -1 do begin if PositionActive(p) then if Positionlong(p) then SellAtStop( Bar + 1, SL, p, \'LongStop\') else CoverAtStop( Bar + 1, SL, p, \'ShortStop\'); if PositionActive(p) then if Positionlong(p) then SellAtStop( Bar + 1, LE, p, \'LongExit\') else CoverAtStop( Bar + 1, SE, p, \'ShortExit\'); end; // of position exits end; // OF THE MAIN CYCLE
|