期货软件TB系统源代码解读系列11-基于ADX及EMA的交易系统

  平均趋向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指标是不错的,我的很多趋势操作也是借鉴这个指标的。当然,我这个代码也是有缺陷的,就是买卖的时候,触发止盈之后,条件符合,持续开仓,所以造成很大的浪费手续费,但怎么改进,我现在也懒得去写了,有兴趣的朋友可以自己弄了。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,063评论 6 510
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,805评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,403评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,110评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,130评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,877评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,533评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,429评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,947评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,078评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,204评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,894评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,546评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,086评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,195评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,519评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,198评论 2 357

推荐阅读更多精彩内容