平均趨向ADX指標是我喜歡觀察的一個好指標,它是輔助我判斷是否有趨勢運動的關鍵性指標,大家可以對它很熟悉了,我也不再這里細說什么了,這次直接解讀TB系統(tǒng)里編寫的基于ADX及EMA的交易系統(tǒng)怔揩,當然我對交易結(jié)果感覺一般,所以后面按我個人意愿脯丝,給它改了一下商膊,變成一個新的系統(tǒng)。
我改寫的系統(tǒng)暫且放下巾钉,先來看這TB系統(tǒng)操作的規(guī)則要素:
1. 計算30根k線最高價和最低價的EMA價差;
2. 計算12根k線的ADX.
入場條件:
1.滿足上根K線的收盤價收于EMA30之上,且ADX向上的條件 在EntryBarBAR內(nèi)該條件成立;
2.當前價大于等于BuySetup,做多,當條件滿足超過EntryBarBAR后,取消入場.
出場條件:
1.當前價格下破30根K線最高價的EMA.
好了翘狱,讓我們來看看這系統(tǒng)編寫的程序化代碼及解讀:(個人覺得那些參數(shù)名,變量名可以跳過砰苍,直接讀正文好的潦匈,要不然這一大堆的參數(shù)名阱高,變量名誰能記得住的,我都是用的時候返回來寫的)
Params
Numeric DMI_N(14); //聲明數(shù)值型參數(shù)名DMI_N,初始值為14.//
Numeric DMI_M(30); //聲明數(shù)值型參數(shù)名DMI_M,初始值為30.//
Numeric AvgLen(30); //聲明數(shù)值型參數(shù)名為AvgLen,初始值為30.//
Numeric EntryBar(2);//聲明數(shù)值型參數(shù)名為EntryBar茬缩,初始值為2.//
Vars
//DMI最終算出結(jié)果需要的變量名赤惊。//
NumericSeries oDMIPlus;//聲明數(shù)值序列變量名為oDMIPlus.//
NumericSeries oDMIMinus;//聲明數(shù)值序列變量名為oDMIMinus.//
NumericSeries oDMI;//聲明數(shù)值序列變量名為oDMI.//
NumericSeries oADX;//聲明數(shù)值序列變量名為oADX.//
NumericSeries oADXR;//聲明數(shù)值序列變量名為oADXR.//
NumericSeries oVolty;//聲明數(shù)值序列變量名為oVolty.//
//DMI過程計算中需要的變量名。//
NumericSeries sDMI;//聲明數(shù)值序列變量名sDMI.//
NumericSeries sADX;//聲明數(shù)值序列變量名sADX.//
NumericSeries cumm;//聲明數(shù)值序列變量名cumm凰锡。//
NumericSeries sVolty;//聲明數(shù)值序列變量名sVilty未舟。//
Numeric PlusDM;//聲明數(shù)值變量名PlusDM。//
Numeric MinusDM;//聲明數(shù)值變量名MinusDM掂为。//
Numeric UpperMove;//聲明數(shù)值變量名UpperMove裕膀。//
Numeric LowerMove;//聲明數(shù)值變量名LowerMove。//
Numeric SumPlusDM(0);//聲明數(shù)值變量名SumPlusDM,賦值為0.//
Numeric SumMinusDM(0);//聲明數(shù)值變量名SumMinusDM,賦值為0.//
Numeric SumTR(0);//聲明數(shù)值變量名SumTR,賦值為0.//
NumericSeries AvgPlusDM;//聲明數(shù)值序列變量名AvgPlusDM.//
NumericSeries AvgMinusDM;//聲明數(shù)值序列變量名AvgMinusDM.//
Numeric SF;//聲明數(shù)值變量名SF勇哗。//
Numeric Divisor;聲明數(shù)值變量名Divisor昼扛。//
Numeric i;//聲明數(shù)值變量名i。//
NumericSeries TRValue;//聲明數(shù)值序列變量名TRValue欲诺。//
//計算EMA用的變量名抄谐。//
NumericSeries UpperMA(0); //聲明數(shù)值序列變量UpperMA,賦值為0.//
NumericSeries LowerMA(0); //聲明數(shù)值序列變量LowerMA,賦值為0.//
NumericSeries ADXValue(0); //聲明數(shù)值序列變量ADXValue扰法,賦值為0.//
NumericSeries ChanSpread(0); //聲明數(shù)值序列變量ChanSpread,賦值為0.//
Bool BuySetup(False); //聲明布爾型變量名BuySetup蛹含,初始判斷為假。//
NumericSeries BuyTarget(0); //聲明數(shù)值變量名BuyTarget,賦值為0.//
NumericSeries MROBS(0); //聲明數(shù)值變量名MROBS,賦值為0.//
BoolSeries Con1;//聲明布爾型序列變量名Con1.//
Numeric Minpoint;//聲明數(shù)值型變量名Minpoint塞颁。//
Begin
If(!CallAuctionFilter()) Return;// 集合競價和小節(jié)休息過濾浦箱。//
Minpoint=Minmove*PriceScale;//這兩句一般固定的直接調(diào)用就行,一個過濾祠锣,一個計算最小變動價位憎茂。//
//DMI指標計算, 最終將輸出ADX指標//
//--------------------------DMI計算開始-----------------------------------//
SF = 1/DMI_N;//變量SF是一個隨周期而變化的系數(shù),根據(jù)上面的賦值锤岸,可以直接得出SF=1/14。//
TRValue = TrueRange; //變量TRValue值板乙,直接調(diào)用以前我們解讀過的求真實波動函數(shù)TrueRange的值是偷。//
If(CurrentBar == DMI_N)//假如當前k線數(shù)位等于14,按照下列語句來計算募逞。//
{
For i = 0 To DMI_N - 1//循環(huán)語句蛋铆,就是下列計算方程 i 值從0-13給它計算一遍。//
{
PlusDM = 0 ;//先直接等于0了//
MinusDM = 0 ;//先等于0//
UpperMove = High[i] - High[ i + 1 ] ;//開始從UpperMove = 最高價High[0]-最高價High[1],一直計算到High[13]-High[14],相當于反復算了14次//
LowerMove = Low[ i + 1 ] - Low[i] ;//同上的放接,算這變量LowerMove刺啦,也來14次,但記住了纠脾,循環(huán)計算也是按照順序邏輯來的玛瘸,就像我們小學記的九九乘法表那樣蜕青,先把1乘以到9,再2乘以到9糊渊,程序也是這么一步步按語句來讀的右核,所以從這FOR下邊的這花括號反復計算,當條件不滿足了渺绒,才直接就跳過這括號贺喝,接著讀下面的。//
If (UpperMove > LowerMove and UpperMove > 0 )//假如算得的變量UpperMove大于LowerMove宗兼,而且UpperMove大于0.//
{
PlusDM = UpperMove;//變量PlusDM就等于變量UpperMove值躏鱼。//
}Else if (LowerMove > UpperMove and LowerMove > 0)//并列語句,當條件變成這樣的時候殷绍,變量LowerMove大于變量UpperMove值染苛,而且LowerMove大于0.//
{
MinusDM = LowerMove ;//變量MinusDM值等于變量LowerMove值。//
}
SumPlusDM = SumPlusDM + PlusDM ;//累加起來的意思篡帕,從變量SumPlusDM等于0逐步加上計算所得的PlusDM值殖侵。//
SumMinusDM = SumMinusDM + MinusDM ;//同上解讀,這個是累加變量SumMinusDM總值镰烧。//
SumTR = SumTR + TRValue[i] ;//同上拢军,把真實波動值計算出來,累加到變量SumTR總值里怔鳖。//
}
AvgPlusDM = SumPlusDM / DMI_N ;//變量AvgPlusDM值等于變量SumPlusDM總值除以周期數(shù)14.//
AvgMinusDM = SumMinusDM / DMI_N ;//同上的解讀茉唉。//
sVolty = SumTR / DMI_N ;//同上解讀的。//
}//循環(huán)到這只要還在0-13里的结执,就往回重新算一次度陆,直到條件不滿足了,才開始讀下列語句献幔。//
Else if(CurrentBar > DMI_N)//看著明白了吧懂傀,當k線數(shù)位大于了周期數(shù)14.就是上邊循環(huán)跳出來了,開始執(zhí)行下列語句蜡感。//
{
PlusDM = 0 ;//先等于0.你要問我那14根k線里循環(huán)計算得到的變量PlusDM值呢蹬蚁?我只能跟你說,那個值是針對前14根k線計算的郑兴,但是從第15根到開始一直到當前跳動的K線犀斋,變量PlusDM都是從0新算起。//
MinusDM = 0 ; //同上解讀的情连。先等于0.//
UpperMove = High - High[1] ;//變量UpperMove值等于當前的最高價減去前一個的最高價叽粹。//
LowerMove = Low[1] -Low ;//變量LowerMove值等于前一個最低價減去當前的最低價。//
If (UpperMove > LowerMove and UpperMove > 0 )//假如了UpperMove大于LowerMove,并且大于0的虫几。//
{
PlusDM = UpperMove;//把變量UpperMove值賦值給變量PlusDM锤灿,變成一個新值了,這時不再等于0了持钉。//
}Else if (LowerMove > UpperMove and LowerMove > 0 )//假如LowerMove大于UpperMove衡招,并且大于0的。//
{
MinusDM = LowerMove ;//也是賦予變量MinusDM新的值每强,即等于變量LowerMove值始腾。//
}
AvgPlusDM = AvgPlusDM[1] + SF * ( PlusDM - AvgPlusDM[1] ) ;//照公式直接解讀,變量AvgPlusDM[1]意思是前一個空执,對第15根k線來說浪箭,就是前14根k線算得的值。所以記住這[1]就是從當前數(shù)位倒退一個數(shù)位的意思辨绊。//
AvgMinusDM = AvgMinusDM[1] + SF * ( MinusDM - AvgMinusDM[1] ) ;//這個也直接照公式解讀了奶栖。//
sVolty = sVolty[1] + SF * ( TRValue - sVolty[1] ) ;//同上的,直接照公式解讀门坷。//
}
Else//其實這最后這個else就是上面CurrentBar不是大于或等于14時宣鄙,那就是小于14了,執(zhí)行下列語句默蚌,變量都是返回無效值的冻晤。//
{
oDMIPlus = InvalidNumeric;//返回無效值。//
oDMIMinus = InvalidNumeric;//返回無效值绸吸。//
oDMI = InvalidNumeric;//返回無效值鼻弧。//
oADX = InvalidNumeric;//返回無效值。//
oADXR = InvalidNumeric;//返回無效值锦茁。//
oVolty = InvalidNumeric;//返回無效值攘轩。//
}
If (sVolty > 0)//假如計算得的變量sVolty值大于0.//
{
oDMIPlus = 100 * AvgPlusDM / sVolty ;//變量0DMIPlus = 100 * 變量AvgPlusDM / 變量sVolty。//
oDMIMinus = 100 * AvgMinusDM / sVolty ;//直接照公式解讀了码俩。//
}Else//這就是假如當變量sVolty小于0時度帮。//
{
oDMIPlus = 0 ;//變量oDMIPlus=0.//
oDMIMinus = 0 ;//變量oDMIMinus=0.//
}
Divisor = oDMIPlus + oDMIMinus ;//變量Divisor =變量oDMIPlus +變量oDMIMinus//
if (Divisor > 0)//假如算得的變量Divisor值大于0的。//
{
sDMI = 100 * Abs( oDMIPlus - oDMIMinus ) / Divisor; //函數(shù)Abs()意思是返回參數(shù)的絕對值稿存,通俗的說不管括號里計算得到的是大于還是小于0够傍,它返回的都是正整數(shù)。所以照公式解讀挠铲,算出變量sDMI值了。//
}else//假如算得的變量Divisor小于0的寂诱。//
{
sDMI = 0 ;//變量sDMI等于0.//
}
cumm=Cum( sDMI );//函數(shù)Cum(),意思是求累計值拂苹,所以這個Cum( sDMI )就是計算從第一個k線以來sDMI值的累計值,把它賦值給變量cumm的。//
If(CurrentBar > 0)//假如k線數(shù)位大于0的瓢棒,其實就是從第二根開始了浴韭。//
{
If (CurrentBar <= DMI_N)//這里再給個限定條件,k線數(shù)位小于或等于周期數(shù)14的脯宿。//
{
sADX = Cumm / CurrentBar ;//變量sADX等于變量Cumm值除以k線數(shù)位值的念颈。//
oADXR = ( sADX + sADX[ CurrentBar - 1 ] ) * 0.5 ;//變量oADXR = (變量sADX + 變量sADX[k線數(shù)位值-1])* 固定系數(shù)0.5//
}Else//這個呢就是假如CurrentBar大于14的。//
{
sADX = sADX[1] + SF * ( sDMI - sADX[1] ) ;//變量sADX又是一個新算法连霉,直接照公式來解讀了榴芳。//
oADXR = ( sADX + sADX[ DMI_M - 1 ] ) * 0.5 ;//同樣的,照公式算出新的oADXR值跺撼。//
}
}
oVolty = sVolty;//變量oVolty = 變量sVolty窟感。//
oDMI = sDMI;//變量oDMI = 變量sDMI。//
oADX = sADX;//變量oADX = 變量sADX歉井。//
//--------------------------DMI計算結(jié)束-----------------------------------//
ADXValue = oADX; //變量ADXValue = 變量 oADX柿祈,其實這就是ADX均線了。//
UpperMA = XAverage(High, AvgLen); //計算30根K線最高價的EMA哩至。//
LowerMA = XAverage(Low, AvgLen); //計算30根K線最低價的EMA躏嚎。//
ChanSpread = (UpperMA - LowerMA) / 2; //通過EMA計算出通道寬度。//
BuySetup = Close > UpperMA and ADXValue > ADXValue[1]; //當ADX向上且當前價大于30根K線最高價的EMA滿足買入準備條件菩貌。//
IF (BuySetup )//假如滿足買入條件了卢佣,執(zhí)行下列語句。//
{
BuyTarget = Close + ChanSpread; //滿足買入準備條件時,用當前k線價格計算出多頭觸發(fā)價菜谣,即為當前價 + 通道值珠漂。//
}
MROBS = NthCon(BuySetup, 1); //上次滿足買入準備條件距離當前k線的距離數(shù)目 .//
If(MROBS > EntryBar) //假如這個距離數(shù)目大于參數(shù)EntryBar初值2的。//
{
MROBS = 0; //距離上次買入準備條件超過參數(shù)ENTRYBAR的數(shù)目后,重置尾膊。//
}
//系統(tǒng)入場條件媳危。//
IF( MROBS[1] <> 0 and MarketPosition == 0 and CurrentBar > 100) //滿足買入準備條件后,在ENTRYBAR數(shù)目內(nèi),且大于等于買入多頭觸發(fā)價,多單入場冈敛。//
{
If(High >= BuyTarget[1] And Vol > 0)//高價突破變量BuyTarget[1]待笑,而且成交量大于0的。//
{
Buy(0,max(Open,BuyTarget[1]));//取最大值開盤價買入1手抓谴。//
}
}
//系統(tǒng)出場條件暮蹂。//
If(MarketPosition==1 and BarsSinceEntry >0 And Vol > 0) //當持有多單且當前價格下破30根K線最高價的EMA,多單出場。//
{
If(Low <= UpperMA[1] - Minpoint )//低價小于或者等于UpperMA[1] - 最小變動價Minpoint癌压。//
{
Sell(0,min(Open,UpperMA[1] - minpoint));//取最小值賣出平倉仰泻。//
}
}
End
很一般,再看賣空的代碼其實都差不多滩届,就是改一下條件集侯,代碼及結(jié)果如下:
Params
Numeric DMI_N(14);
Numeric DMI_M(30);
Numeric AvgLen(30);
Numeric EntryBar(2);
Vars
NumericSeries oDMIPlus;
NumericSeries oDMIMinus;
NumericSeries oDMI;
NumericSeries oADX;
NumericSeries oADXR;
NumericSeries oVolty;
NumericSeries sDMI;
NumericSeries sADX;
NumericSeries cumm;
NumericSeries sVolty;
Numeric PlusDM;
Numeric MinusDM;
Numeric UpperMove;
Numeric LowerMove;
Numeric SumPlusDM(0);
Numeric SumMinusDM(0);
Numeric SumTR(0);
NumericSeries AvgPlusDM;
NumericSeries AvgMinusDM;
Numeric SF;
Numeric Divisor;
Numeric i;
NumericSeries TRValue;
NumericSeries UpperMA(0);
NumericSeries LowerMA(0);
NumericSeries ADXValue(0);
NumericSeries ChanSpread(0);
Bool SellSetup(False);
NumericSeries SellTarget(0);
NumericSeries MROSS(0);
Numeric Minpoint;
Begin
// 集合競價和小節(jié)休息過濾
If(!CallAuctionFilter()) Return;
Minpoint=Minmove*PriceScale;
//--------------------------DMI計算開始-----------------------------------//
SF = 1/DMI_N;
TRValue = TrueRange;
If(CurrentBar == DMI_N)
{
For i = 0 To DMI_N - 1
{
PlusDM = 0 ;
MinusDM = 0 ;
UpperMove = High[i] - High[ i + 1 ] ;
LowerMove = Low[ i + 1 ] - Low[i] ;
If (UpperMove > LowerMove and UpperMove > 0 )
{
PlusDM = UpperMove;
}Else if (LowerMove > UpperMove and LowerMove > 0)
{
MinusDM = LowerMove ;
}
SumPlusDM = SumPlusDM + PlusDM ;
SumMinusDM = SumMinusDM + MinusDM ;
SumTR = SumTR + TRValue[i] ;
}
AvgPlusDM = SumPlusDM / DMI_N ;
AvgMinusDM = SumMinusDM / DMI_N ;
sVolty = SumTR / DMI_N ;
}Else if(CurrentBar > DMI_N)
{
PlusDM = 0 ;
MinusDM = 0 ;
UpperMove = High - High[1] ;
LowerMove = Low[1] -Low ;
If (UpperMove > LowerMove and UpperMove > 0 )
{
PlusDM = UpperMove;
}Else if (LowerMove > UpperMove and LowerMove > 0 )
{
MinusDM = LowerMove ;
}
AvgPlusDM = AvgPlusDM[1] + SF * ( PlusDM - AvgPlusDM[1] ) ;
AvgMinusDM = AvgMinusDM[1] + SF * ( MinusDM - AvgMinusDM[1] ) ;
sVolty = sVolty[1] + SF * ( TRValue - sVolty[1] ) ;
}Else
{
oDMIPlus = InvalidNumeric;
oDMIMinus = InvalidNumeric;
oDMI = InvalidNumeric;
oADX = InvalidNumeric;
oADXR = InvalidNumeric;
oVolty = InvalidNumeric;
}
If (sVolty > 0)
{
oDMIPlus = 100 * AvgPlusDM / sVolty ;
oDMIMinus = 100 * AvgMinusDM / sVolty ;
}Else
{
oDMIPlus = 0 ;
oDMIMinus = 0 ;
}
Divisor = oDMIPlus + oDMIMinus ;
if (Divisor > 0)
{
sDMI = 100 * Abs( oDMIPlus - oDMIMinus ) / Divisor;
}else
{
sDMI = 0 ;
}
cumm=Cum( sDMI );
If(CurrentBar > 0)
{
If (CurrentBar <= DMI_N)
{
sADX = Cumm / CurrentBar ;
oADXR = ( sADX + sADX[ CurrentBar - 1 ] ) * 0.5 ;
}Else
{
sADX = sADX[1] + SF * ( sDMI - sADX[1] ) ;
oADXR = ( sADX + sADX[ DMI_M - 1 ] ) * 0.5 ;
}
}
oVolty = sVolty;
oDMI = sDMI;
oADX = sADX;
//PlotNumeric("oADX",oADX);
//--------------------------DMI計算結(jié)束-----------------------------------//
ADXValue = oADX;
UpperMA = XAverage(High, AvgLen);
LowerMA = XAverage(Low, AvgLen);
ChanSpread = (UpperMA - LowerMA) / 2;
SellSetup = Close < LowerMA and ADXValue > ADXValue[1]; //當ADX向上且當前價下于30根K線最低價的EMA滿足賣出準備條件。//
If (SellSetup)
{
SellTarget = Close - ChanSpread; //滿足賣出準備條件時,用前bar價格計算出空頭觸發(fā)價。//
}
MROSS = NthCon(SellSetup, 1); //上次滿足賣出準備條件距離當前BAR的數(shù)目//
If(MROSS > EntryBar)
{
MROSS = 0; //距離上次賣出準備條件超過ENTRYBAR的數(shù)目后,重置//
}
//系統(tǒng)入場規(guī)則//
If( MROSS[1] <>0 and MarketPosition == 0 and CurrentBar > 100) //滿足賣出準備條件后ENTRYBAR數(shù)目內(nèi),且小于等于空頭觸發(fā)價,空單入場 //
{
If(Low <= SellTarget[1] And Vol > 0)
{
Sellshort(0,Min(Open,SellTarget[1]));
}
}
//系統(tǒng)出場規(guī)則//
If(MarketPosition==-1 and BarsSinceEntry >0 And Vol > 0) //當持有空單且當前價格上破30根K線最低價的EMA,多單出場//
{
If(High >= LowerMA[1] + minpoint )
{
BuyToCover(0,max(Open,LowerMA[1] + minpoint));
}
}
End
看這做空的棠枉,多差的收益浓体,所以我就照著心中想的,買賣規(guī)則很簡單辈讶,兩條移動均價命浴,ADX值大于25的,兩均線交叉的買入;ADX大于25贱除,兩均線交叉賣出杏死。代碼及結(jié)果如下:
Params
Numeric DMI_N(14);
Numeric DMI_M(30);
Numeric AvgLen(30);
Numeric FastLength(5);
Numeric SlowLength(20);
Numeric TrailingStart1(50); // 跟蹤止盈啟動設置1//
Numeric TrailingStart2(80); // 跟蹤止盈啟動設置2//
Numeric TrailingStop1(30); // 跟蹤止盈設置1//
Numeric TrailingStop2(20); // 跟蹤止盈設置2//
Numeric StopLossSet(30); //固定止損30個點//
Vars
NumericSeries oDMIPlus;
NumericSeries oDMIMinus;
NumericSeries oDMI;
NumericSeries oADX;
NumericSeries oADXR;
NumericSeries oVolty;
NumericSeries sDMI;
NumericSeries sADX;
NumericSeries cumm;
NumericSeries sVolty;
Numeric PlusDM;
Numeric MinusDM;
Numeric UpperMove;
Numeric LowerMove;
Numeric SumPlusDM(0);
Numeric SumMinusDM(0);
Numeric SumTR(0);
NumericSeries AvgPlusDM;
NumericSeries AvgMinusDM;
Numeric SF;
Numeric Divisor;
Numeric i;
NumericSeries TRValue;
Numeric Minpoint;
NumericSeries AvgValue1;
NumericSeries AvgValue2;
NumericSeries HighestAfterEntry;
NumericSeries LowestAfterEntry;
Numeric MyEntryPrice;
Numeric myprice;
Numeric myexitprice;
Begin
AvgValue1 = AverageFC(Close,FastLength);
AvgValue2 = AverageFC(Close,SlowLength);
PlotNumeric("MA1",AvgValue1);
PlotNumeric("MA2",AvgValue2);
If(!CallAuctionFilter()) Return;
Minpoint=Minmove*PriceScale;
//--------------------------DMI計算開始-----------------------------------//
SF = 1/DMI_N;
TRValue = TrueRange;
If(CurrentBar == DMI_N)
{
For i = 0 To DMI_N - 1
{
PlusDM = 0 ;
MinusDM = 0 ;
UpperMove = High[i] - High[ i + 1 ] ;
LowerMove = Low[ i + 1 ] - Low[i] ;
If (UpperMove > LowerMove and UpperMove > 0 )
{
PlusDM = UpperMove;
}Else if (LowerMove > UpperMove and LowerMove > 0)
{
MinusDM = LowerMove ;
}
SumPlusDM = SumPlusDM + PlusDM ;
SumMinusDM = SumMinusDM + MinusDM ;
SumTR = SumTR + TRValue[i] ;
}
AvgPlusDM = SumPlusDM / DMI_N ;
AvgMinusDM = SumMinusDM / DMI_N ;
sVolty = SumTR / DMI_N ;
}Else if(CurrentBar > DMI_N)
{
PlusDM = 0 ;
MinusDM = 0 ;
UpperMove = High - High[1] ;
LowerMove = Low[1] -Low ;
If (UpperMove > LowerMove and UpperMove > 0 )
{
PlusDM = UpperMove;
}Else if (LowerMove > UpperMove and LowerMove > 0 )
{
MinusDM = LowerMove ;
}
AvgPlusDM = AvgPlusDM[1] + SF * ( PlusDM - AvgPlusDM[1] ) ;
AvgMinusDM = AvgMinusDM[1] + SF * ( MinusDM - AvgMinusDM[1] ) ;
sVolty = sVolty[1] + SF * ( TRValue - sVolty[1] ) ;
}Else
{
oDMIPlus = InvalidNumeric;
oDMIMinus = InvalidNumeric;
oDMI = InvalidNumeric;
oADX = InvalidNumeric;
oADXR = InvalidNumeric;
oVolty = InvalidNumeric;
}
If (sVolty > 0)
{
oDMIPlus = 100 * AvgPlusDM / sVolty ;
oDMIMinus = 100 * AvgMinusDM / sVolty ;
}Else
{
oDMIPlus = 0 ;
oDMIMinus = 0 ;
}
Divisor = oDMIPlus + oDMIMinus ;
if (Divisor > 0)
{
sDMI = 100 * Abs( oDMIPlus - oDMIMinus ) / Divisor;
}else
{
sDMI = 0 ;
}
cumm=Cum( sDMI );
If(CurrentBar > 0)
{
If (CurrentBar <= DMI_N)
{
sADX = Cumm / CurrentBar ;
oADXR = ( sADX + sADX[ CurrentBar - 1 ] ) * 0.5 ;
}Else
{
sADX = sADX[1] + SF * ( sDMI - sADX[1] ) ;
oADXR = ( sADX + sADX[ DMI_M - 1 ] ) * 0.5 ;
}
}
oVolty = sVolty;
oDMI = sDMI;
oADX = sADX;
If(MarketPosition <>1 && AvgValue1[1] > AvgValue2[1] && oADX[1] > 25)
{
Buy(1,Open);
}
If(MarketPosition <>-1 && AvgValue1[1] < AvgValue2[1] && oADX[1]>25)
{
SellShort(1,Open);
}
If(BarsSinceentry == 0)
{
HighestAfterEntry = Close;
LowestAfterEntry = Close;
If(MarketPosition <> 0)
{
HighestAfterEntry = Max(HighestAfterEntry,AvgEntryPrice); // 開倉的Bar衙吩,將開倉價和當時的收盤價的較大值保留到HighestAfterEntry//
LowestAfterEntry = Min(LowestAfterEntry,AvgEntryPrice); // 開倉的Bar,將開倉價和當時的收盤價的較小值保留到LowestAfterEntry//
}
}else
{
HighestAfterEntry = Max(HighestAfterEntry,High); // 記錄下當前Bar的最高點,用于下一個Bar的跟蹤止損判斷//
LowestAfterEntry = Min(LowestAfterEntry,Low); // 記錄下當前Bar的最低點汇四,用于下一個Bar的跟蹤止損判斷//
}
Commentary("HighestAfterEntry="+Text(HighestAfterEntry));
Commentary("LowestAfterEntry="+Text(LowestAfterEntry));
Commentary("MyEntryPrice="+Text(MyEntryPrice));
MinPoint = MinMove*PriceScale;
MyEntryPrice = AvgEntryPrice;
If(MarketPosition==1) // 有多倉的情況//
{
If(HighestAfterEntry[1] >= MyEntryPrice + TrailingStart2*MinPoint) // 第二級跟蹤止損的條件表達式//
{
If(Low <= HighestAfterEntry[1] - TrailingStop2*MinPoint)
{
MyExitPrice = HighestAfterEntry[1] - TrailingStop2*MinPoint;
Sell(0,MyExitPrice);
}
}else if(HighestAfterEntry[1] >= MyEntryPrice + TrailingStart1*MinPoint)// 第一級跟蹤止損的條件表達式//
{
If(Low <= HighestAfterEntry[1] - TrailingStop1*MinPoint)
{
MyExitPrice = HighestAfterEntry[1] - TrailingStop1*MinPoint ;
Sell(0,MyExitPrice);
}
}else if(Low <= MyEntryPrice - StopLossSet*MinPoint)//可以在這里寫上初始的止損處理//
{
MyExitPrice = MyEntryPrice - StopLossSet*MinPoint;
Sell(0,MyExitPrice);
}
}else if(MarketPosition==-1) // 有空倉的情況//
{
If(LowestAfterEntry[1] <= MyEntryPrice - TrailingStart2*MinPoint) // 第二級跟蹤止損的條件表達式//
{
If(High >= LowestAfterEntry[1] + TrailingStop2*MinPoint)
{
MyExitPrice = LowestAfterEntry[1] + TrailingStop2*MinPoint;
BuyToCover(0,MyExitPrice);
}
}else if(LowestAfterEntry[1] <= MyEntryPrice - TrailingStart1*MinPoint)// 第一級跟蹤止損的條件表達式//
{
If(High >= LowestAfterEntry[1] + TrailingStop1*MinPoint)
{
MyExitPrice = LowestAfterEntry[1] + TrailingStop1*MinPoint;
BuyToCover(0,MyExitPrice);
}
}else If(High >= MyEntryPrice + StopLossSet*MinPoint)//可以在這里寫上初始的止損處理//
{
MyExitPrice = MyEntryPrice + StopLossSet*MinPoint;
BuyToCover(0,MyExitPrice);
}
}
End
看吧饲握,改了一下條件奈懒,這系統(tǒng)就變得不錯的遭商,所以說ADX指標是不錯的,我的很多趨勢操作也是借鑒這個指標的缅帘。當然轴术,我這個代碼也是有缺陷的,就是買賣的時候钦无,觸發(fā)止盈之后逗栽,條件符合,持續(xù)開倉失暂,所以造成很大的浪費手續(xù)費彼宠,但怎么改進,我現(xiàn)在也懶得去寫了弟塞,有興趣的朋友可以自己弄了凭峡。