平均趋向ADX指标是我喜欢观察的一个好指标,它是辅助我判断是否有趋势运动的关键性指标,大家可以对它很熟悉了,我也不再这里细说什么了,这次直接解读TB系统里编写的基于ADX及EMA的交易系统,当然我对交易结果感觉一般,所以后面按我个人意愿,给它改了一下,变成一个新的系统。
我改写的系统暂且放下,先来看这TB系统操作的规则要素:
1. 计算30根k线最高价和最低价的EMA价差;
2. 计算12根k线的ADX.
入场条件:
1.满足上根K线的收盘价收于EMA30之上,且ADX向上的条件 在EntryBarBAR内该条件成立;
2.当前价大于等于BuySetup,做多,当条件满足超过EntryBarBAR后,取消入场.
出场条件:
1.当前价格下破30根K线最高价的EMA.
好了,让我们来看看这系统编写的程序化代码及解读:(个人觉得那些参数名,变量名可以跳过,直接读正文好的,要不然这一大堆的参数名,变量名谁能记得住的,我都是用的时候返回来写的)
Params
Numeric DMI_N(14); //声明数值型参数名DMI_N,初始值为14.//
Numeric DMI_M(30); //声明数值型参数名DMI_M,初始值为30.//
Numeric AvgLen(30); //声明数值型参数名为AvgLen,初始值为30.//
Numeric EntryBar(2);//声明数值型参数名为EntryBar,初始值为2.//
Vars
//DMI最终算出结果需要的变量名。//
NumericSeries oDMIPlus;//声明数值序列变量名为oDMIPlus.//
NumericSeries oDMIMinus;//声明数值序列变量名为oDMIMinus.//
NumericSeries oDMI;//声明数值序列变量名为oDMI.//
NumericSeries oADX;//声明数值序列变量名为oADX.//
NumericSeries oADXR;//声明数值序列变量名为oADXR.//
NumericSeries oVolty;//声明数值序列变量名为oVolty.//
//DMI过程计算中需要的变量名。//
NumericSeries sDMI;//声明数值序列变量名sDMI.//
NumericSeries sADX;//声明数值序列变量名sADX.//
NumericSeries cumm;//声明数值序列变量名cumm。//
NumericSeries sVolty;//声明数值序列变量名sVilty。//
Numeric PlusDM;//声明数值变量名PlusDM。//
Numeric MinusDM;//声明数值变量名MinusDM。//
Numeric UpperMove;//声明数值变量名UpperMove。//
Numeric LowerMove;//声明数值变量名LowerMove。//
Numeric SumPlusDM(0);//声明数值变量名SumPlusDM,赋值为0.//
Numeric SumMinusDM(0);//声明数值变量名SumMinusDM,赋值为0.//
Numeric SumTR(0);//声明数值变量名SumTR,赋值为0.//
NumericSeries AvgPlusDM;//声明数值序列变量名AvgPlusDM.//
NumericSeries AvgMinusDM;//声明数值序列变量名AvgMinusDM.//
Numeric SF;//声明数值变量名SF。//
Numeric Divisor;声明数值变量名Divisor。//
Numeric i;//声明数值变量名i。//
NumericSeries TRValue;//声明数值序列变量名TRValue。//
//计算EMA用的变量名。//
NumericSeries UpperMA(0); //声明数值序列变量UpperMA,赋值为0.//
NumericSeries LowerMA(0); //声明数值序列变量LowerMA,赋值为0.//
NumericSeries ADXValue(0); //声明数值序列变量ADXValue,赋值为0.//
NumericSeries ChanSpread(0); //声明数值序列变量ChanSpread,赋值为0.//
Bool BuySetup(False); //声明布尔型变量名BuySetup,初始判断为假。//
NumericSeries BuyTarget(0); //声明数值变量名BuyTarget,赋值为0.//
NumericSeries MROBS(0); //声明数值变量名MROBS,赋值为0.//
BoolSeries Con1;//声明布尔型序列变量名Con1.//
Numeric Minpoint;//声明数值型变量名Minpoint。//
Begin
If(!CallAuctionFilter()) Return;// 集合竞价和小节休息过滤。//
Minpoint=Minmove*PriceScale;//这两句一般固定的直接调用就行,一个过滤,一个计算最小变动价位。//
//DMI指标计算, 最终将输出ADX指标//
//--------------------------DMI计算开始-----------------------------------//
SF = 1/DMI_N;//变量SF是一个随周期而变化的系数,根据上面的赋值,可以直接得出SF=1/14。//
TRValue = TrueRange; //变量TRValue值,直接调用以前我们解读过的求真实波动函数TrueRange的值。//
If(CurrentBar == DMI_N)//假如当前k线数位等于14,按照下列语句来计算。//
{
For i = 0 To DMI_N - 1//循环语句,就是下列计算方程 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次,但记住了,循环计算也是按照顺序逻辑来的,就像我们小学记的九九乘法表那样,先把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总值除以周期数14.//
AvgMinusDM = SumMinusDM / DMI_N ;//同上的解读。//
sVolty = SumTR / DMI_N ;//同上解读的。//
}//循环到这只要还在0-13里的,就往回重新算一次,直到条件不满足了,才开始读下列语句。//
Else if(CurrentBar > DMI_N)//看着明白了吧,当k线数位大于了周期数14.就是上边循环跳出来了,开始执行下列语句。//
{
PlusDM = 0 ;//先等于0.你要问我那14根k线里循环计算得到的变量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]就是从当前数位倒退一个数位的意思。//
AvgMinusDM = AvgMinusDM[1] + SF * ( MinusDM - AvgMinusDM[1] ) ;//这个也直接照公式解读了。//
sVolty = sVolty[1] + SF * ( TRValue - sVolty[1] ) ;//同上的,直接照公式解读。//
}
Else//其实这最后这个else就是上面CurrentBar不是大于或等于14时,那就是小于14了,执行下列语句,变量都是返回无效值的。//
{
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; //函数Abs()意思是返回参数的绝对值,通俗的说不管括号里计算得到的是大于还是小于0,它返回的都是正整数。所以照公式解读,算出变量sDMI值了。//
}else//假如算得的变量Divisor小于0的。//
{
sDMI = 0 ;//变量sDMI等于0.//
}
cumm=Cum( sDMI );//函数Cum(),意思是求累计值,所以这个Cum( sDMI )就是计算从第一个k线以来sDMI值的累计值,把它赋值给变量cumm的。//
If(CurrentBar > 0)//假如k线数位大于0的,其实就是从第二根开始了。//
{
If (CurrentBar <= DMI_N)//这里再给个限定条件,k线数位小于或等于周期数14的。//
{
sADX = Cumm / CurrentBar ;//变量sADX等于变量Cumm值除以k线数位值的。//
oADXR = ( sADX + sADX[ CurrentBar - 1 ] ) * 0.5 ;//变量oADXR = (变量sADX + 变量sADX[k线数位值-1])* 固定系数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计算结束-----------------------------------//
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 )//假如满足买入条件了,执行下列语句。//
{
BuyTarget = Close + ChanSpread; //满足买入准备条件时,用当前k线价格计算出多头触发价,即为当前价 + 通道值。//
}
MROBS = NthCon(BuySetup, 1); //上次满足买入准备条件距离当前k线的距离数目 .//
If(MROBS > EntryBar) //假如这个距离数目大于参数EntryBar初值2的。//
{
MROBS = 0; //距离上次买入准备条件超过参数ENTRYBAR的数目后,重置。//
}
//系统入场条件。//
IF( MROBS[1] <> 0 and MarketPosition == 0 and CurrentBar > 100) //满足买入准备条件后,在ENTRYBAR数目内,且大于等于买入多头触发价,多单入场。//
{
If(High >= BuyTarget[1] And Vol > 0)//高价突破变量BuyTarget[1],而且成交量大于0的。//
{
Buy(0,max(Open,BuyTarget[1]));//取最大值开盘价买入1手。//
}
}
//系统出场条件。//
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
很一般,再看卖空的代码其实都差不多,就是改一下条件,代码及结果如下:
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
// 集合竞价和小节休息过滤
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计算结束-----------------------------------//
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价格计算出空头触发价。//
}
MROSS = NthCon(SellSetup, 1); //上次满足卖出准备条件距离当前BAR的数目//
If(MROSS > EntryBar)
{
MROSS = 0; //距离上次卖出准备条件超过ENTRYBAR的数目后,重置//
}
//系统入场规则//
If( MROSS[1] <>0 and MarketPosition == 0 and CurrentBar > 100) //满足卖出准备条件后ENTRYBAR数目内,且小于等于空头触发价,空单入场 //
{
If(Low <= SellTarget[1] And Vol > 0)
{
Sellshort(0,Min(Open,SellTarget[1]));
}
}
//系统出场规则//
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
看这做空的,多差的收益,所以我就照着心中想的,买卖规则很简单,两条移动均价,ADX值大于25的,两均线交叉的买入;ADX大于25,两均线交叉卖出。代码及结果如下:
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
看吧,改了一下条件,这系统就变得不错的,所以说ADX指标是不错的,我的很多趋势操作也是借鉴这个指标的。当然,我这个代码也是有缺陷的,就是买卖的时候,触发止盈之后,条件符合,持续开仓,所以造成很大的浪费手续费,但怎么改进,我现在也懒得去写了,有兴趣的朋友可以自己弄了。