请 [注册] 或 [登录]  | 返回主站

量化交易吧 /  量化策略 帖子:3353400 新帖:46

基于大众交易系统和交易机器人优化点金术的EA交易(续)

螺罗丝发表于:5 月 6 日 18:37回复(0)

简介

我收到上一篇文章的一位读者的提议,对回测过程稍加自动化,以实现同时获得所有优化结果的可能性。此外,手动改变测试周期不是很方便,该过程也应该自动化。这个想法非常棒。而且,MQL4完全可以实现。所以,我将从问题的解决方法开始讲述。



回测自动化

要完成该任务我们需要:

1.在所需的Expert Advisor标头下面写入一行,内容如下:

// + =============================================== =================== + // | 自定义BackTesting功能| // + =============================================== =================== + #include <IsBackTestingTime.mqh>


使用该指令,将IsBackTestingTime()函数加入EA代码。不要忘记将IsBackTestingTime.mqh文件放入INCLUDE文件夹。该函数:

bool IsBackTestingTime()
 {
 } 


用于定义时间周期,在该时间内进行回测优化或回测。在该时间周期内,函数始终返回'真',在其他时间则返回'假'。除了这个函数,通过以下指令将外部EA变量添加到EA代码:

// 用于回测外部 日期时间的外部变量声明 Start_Time = D'2007.01.01' ; //零优化的开始时间extern  int Opt_Period = 3 ; //以月为单位的优化周期,如果小于零,则参数以天为单位extern  int Test_Period = 2 ; //测试周期以月为单位extern  int Period_Shift = 1 ; //优化周期的步骤以月为单位extern  int Opt_Number = 0 ; //优化编号


希望这些变量的含义对于读了我上一篇文章的人都很清楚,这里就不再解释。

2.在EA代码前的开始函数程序块设置调用IsBackTestingTime()函数的最简单的通代代码,根据回测优化的数量将EA运行限制在特定的时间范围。

 //  +    如果(!IsBackTestingTime())
                        返回0),执行回测条件 ;


它的示意图如下:

// + =============================================== =================== + // | Exp_BackTest.mq4 | // | 版权所有©2008,Nikolay Kositsin | // | 哈巴罗夫斯克,farria @ mail.redcom.ru | // + =============================================== =================== + #property copyright  “Copyright©2008,Nikolay Kositsin” #property link  “farria@mail.redcom.ru” // + ==== ================================================== ============ + // | 自定义BackTesting功能| // + =============================================== =================== + #include<IsBackTestingTime.mqh> //  EA的输入参数//  EA的全球变量// + ==================== ============================================== + // | 用户自定义EA的功能| // + =============================================== =================== +
 // + =============================================== =================== + // | 自定义专家初始化功能| // + =============================================== =================== + int init()  {//  + +   +     //  EA初始化的代码//  + +   +                  / / 初始化结束   返回0);  }// + =============================================== =================== + // | 自定义专家迭代功能| // + =============================================== =================== + int start()  {   //  +    如果(!IsBackTestingTime())
                        返回0),执行回测条件 ;             
   //  + +  - +        //  + EA算法的代码   //  + +  - + //  +    
    return0);  }// + - - +


如果你对现成EA示例上的详细问题解决方案感兴趣,查看EA代码Exp_5_1.mq4,源于上一篇文章中的Exp_5.mq4,经修改后用于回测。实际上,与简单的EA交易相比,这种EA的优化没有多大不同。但是,我认为除了Opt_Number变量外,回测变量应该进行优化,不过你可能有不同的看法。

重要的是记住:在测试优化后,我们得到的不是优化期间的结果,而是在其之后(右侧边界之外)的结果使用遗传算法在一次运行内进行所有的回测优化并非最好的决定,在没有优化输入变量Opt_Number的情况下,单独深入分析每个回测优化更加有趣。

但即使在这种情况下,这种方法也促进了对EA行为的理解。应该记住,外部变量Opt_Number的值可以从零变化到某个最大值,该最大值可以使用以下方式定义:从执行所有回测优化的总周期(月数)减去回测优化周期的月数(Opt_Period)和减去回测周期(Test_Period)。获得的值加一。如果Period_Shift等于一,获得的结果将是Opt_Number变量的最大值。



基于两条移动线交叉的交易系统

这种交易系统的变体非常普遍现在我们来分析奠定这种策略的算法对于做多头寸,输入的算法如下。:

对于做空头寸,则如下:

可以使用在指标中定义平均线的具有不同参数的两条相同移动线。假设定义MovA移动平均线的参数始终小于MovB移动平均线的同一参数。这样,在该交易系统中,MovA是快速移动线,MovB是慢速线。下面是基于两条JMA移动线的交易系统的实现变体:

// + =============================================== =================== + // | Exp_6.mq4 | // | 版权所有©2007,Nikolay Kositsin | // | 哈巴罗夫斯克,farria @ mail.redcom.ru | // + =============================================== =================== + #property copyright  “Copyright©2007,Nikolay Kositsin” #property link  “farria@mail.redcom.ru” //  + + -  + //  EA INPUT参数购买交易extern  bool    Test_Up = true ;//交易计算方向过滤器extern  int     Timeframe_Up = 240 ;extern  double Money_Management_Up = 0.1 ;extern  int     LengthA_Up = 4 ;  //快速移动的extern  int的平滑深度     PhaseA_Up = 100 ; //参数改变的范围内          // - 100 ... 100,影响快速移动的瞬态过程的质量的extern  INT     IPCA_Up = 0 ; / *选择指标所在的价格通过快速移动计算(0-CLOSE,1-OPEN,2-HIGH,3-LOW,4-MEDIAN,5-TYPICAL, 6-WEIGHTED,7-Heiken Ashi Close,8-SIMPL,9-TRENDFOLLOW,10-0.5 * TRENDFOLLOW, 11-Heiken Ashi Low,12-Heiken Ashi High,13-Heiken Ashi Open, 14-Heiken Ashi Close。)* / extern  int     LengthB_Up = 4 ; //平滑深度增量缓慢移动到快速一个外部 int     PhaseB_Up = 100 ; //参数在          //  -  100 ... +100 范围内变化,影响慢速运动瞬态过程的质量; extern  int     IPCB_Up = 0 ; / *选择指标所在的价格缓慢移动计算(0-CLOSE,1-OPEN,2-HIGH,3-LOW,4-MEDIAN,5-TYPICAL, 6-WEIGHTED,7-Heiken Ashi Close,8-SIMPL,9-TRENDFOLLOW,10-0.5 * TRENDFOLLOW, 11-Heiken Ashi Low,12-Heiken Ashi High,13-Heiken Ashi Open, 14-Heiken Ashi Close。)* / extern  int     STOPLOSS_Up = 50 ;  //止损extern  int     TAKEPROFIT_Up = 100 ; //获取利润extern  bool    ClosePos_Up = true ; //允许强制关闭位置//  + +  - + //     出售交易的EA输入参数extern  bool Test_Dn = true ; //交易计算方向过滤器extern  int     Timeframe_Dn = 240 ;EXTERN double Money_Management_Dn = 0.1 ;extern  int     LengthA_Dn = 4 ;  //快速移动的extern  int的平滑深度     PhaseA_Dn = 100 ; //参数在         // -100 ... +100 范围内变化,影响快速移动瞬态过程的质量; extern  int     IPCA_Dn = 0 ; / *选择指标所在的价格通过快速移动计算(0-CLOSE,1-OPEN,2-HIGH,3-LOW,4-MEDIAN,5-TYPICAL, 6-WEIGHTED,7-Heiken Ashi Close,8-SIMPL,9-TRENDFOLLOW,10-0.5 * TRENDFOLLOW, 11-Heiken Ashi Low,12-Heiken Ashi High,13-Heiken Ashi Open, 14-Heiken Ashi Close。)* / extern  int     LengthB_Dn = 4 ; //平滑深度增量缓慢移动到快速一个外部 int     PhaseB_Dn = 100 ; //参数在         // -100 ... +100 范围内变化,影响慢速运动的瞬态过程质量; extern  int     IPCB_Dn = 0 ; / *选择指标所在的价格缓慢移动计算(0-CLOSE,1-OPEN,2-HIGH,3-LOW,4-MEDIAN,5-TYPICAL, 6-WEIGHTED,7-Heiken Ashi Close,8-SIMPL,9-TRENDFOLLOW,10-0.5 * TRENDFOLLOW, 11-Heiken Ashi Low,12-Heiken Ashi High,13-Heiken Ashi Open, 14-Heiken Ashi Close。)* / extern  int    STOPLOSS_Dn = 50 ;  //止损extern  int    TAKEPROFIT_Dn = 100 ; //获取利润extern  bool    ClosePos_Dn = true ; //允许强制关闭位置//  + +  - + // 最小计算条的整数变量int MinBar_Up,MinBar_Dn;// + =============================================== =================== + // | 自定义专家功能|// + =============================================== =================== + #include <Lite_EXPERT1.mqh> // + ==================== ============================================== + // | 自定义专家初始化功能| // + =============================================== =================== + int init()  {// 检查Timeframe_Up变量值的正确性   if(Timeframe_Up!= 1)
     if(Timeframe_Up!= 5)
      if(Timeframe_Up!= 15)
       if(Timeframe_Up!= 30)
        if(Timeframe_Up!= 60ifTimeframe_Up!= 60)
         if( Timeframe_Up!= 240)
          if(Timeframe_Up!= 1440)
            PrintStringConcatenate“参数Timeframe_Up不能”,  
                                   “等于”,Timeframe_Up,“!!!” ));// 检查Timeframe_Dn变量值的正确性   if(Timeframe_Dn!= 1)
     if(Timeframe_Dn!= 5)
      if(Timeframe_Dn!= 15)
       if(Timeframe_Dn!= 30)
        if(Timeframe_Dn!= 60ifTimeframe_Dn!= 60)
         if( Timeframe_Dn!= 240)
          if(Timeframe_Dn!= 1440)
            PrintStringConcatenate“参数Timeframe_Dn不能”),  
                                  “等于”,Timeframe_Dn,“!!!” )); 
// 变量的初始化                MinBar_Up = 4 + 30 ;   MinBar_Dn = 4 + 30 ;                                        // 初始化结束   返回0);  }// + =============================================== =================== + // | 专家取消初始化功能| // + =============================================== =================== +   int deinit()  {//  +   
    //  EA deinitialization     返回结束0);//  +  }// + =============================================== =================== + // | 自定义专家迭代功能| // + =============================================== =================== + int start()  {   //  +声明局部变量   int     bar;
    MovA [ 2 ],MovB [ 2 ];
   //  +声明静态变量   static  int LastBars_Up,LastBars_Dn;
   static  bool BUY_Sign,BUY_Stop,SELL_Sign,SELL_Stop;   
   //  ++   长期位置代码if(Test_Up)    {      int IBARS_Up = iBarsNULLTimeframe_Up);      
      if(IBARS_Up> = MinBar_Up)       {         if(LastBars_Up!= IBARS_Up)          {           //  +变量的初始化            BUY_Sign = false ;           BUY_Stop = false ;           LastBars_Up = IBARS_Up;           
           //  +计算指示符值和上载他们BUFFERS                    (巴= 1 ;栏< 3 ;巴++)                     MovA [bar  - 1 ] =                  
                          iCustomNULLTimeframe_Up, 
                                 “JJMA”,LengthA_Up,PhaseA_Up, 
                                                    0,IPCA_Up,0,bar);
           for(bar = 1 ; bar < 3 ; bar ++)                MovB [bar  - 1 ] =                  
                    iCustomNULLTimeframe_Up, 
                      “JJMA”,LengthA_Up + LengthB_Up,PhaseB_Up, 
                                                    0,IPCB_Up,0,bar);                                                   
           //  +定义交易信号                                                      if(MovA [ 1 ] <MovB [ 1 ])
                if(MovA [ 0 ]> MovB [ 0 ])                        BUY_Sign = true ;                          
            if(MovA [ 0 ]> MovB [ 0 ])                        BUY_Stop = true ;                                                     }          
          //  +交易的执行          if(!OpenBuyOrder1(BUY_Sign,1,Money_Management_Up,                                          STOPLOSS_Up,TAKEPROFIT_Up))                                                                 返回( - 1);
          ifClosePos_Up )
                 if(!CloseOrder1(BUY_Stop,1))
                                         return( - 1);        }     }     
   //  ++用于短位置的代码   if(Test_Dn)    {      int IBARS_Dn = iBarsNULLTimeframe_Dn);      
      if(IBARS_Dn> = MinBar_Dn)       {         if(LastBars_Dn!= IBARS_Dn)          {           //  +变量的初始化            SELL_Sign = false ;           SELL_Stop = false ;           LastBars_Dn = IBARS_Dn;            
           //  +计算指示符值和上载他们BUFFERS            (巴= 1 ;栏< 3 ;巴++)                     MovA [bar  - 1 ] =                  
                          iCustomNULLTimeframe_Dn, 
                                 “JJMA”,LengthA_Dn,PhaseA_Dn, 
                                                    0,IPCA_Dn,0,bar);
           for(bar = 1 ; bar < 3 ; bar ++)                MovB [bar  - 1 ] =                  
                    iCustomNULLTimeframe_Dn, 
                      “JJMA”,LengthA_Dn + LengthB_Dn,PhaseB_Dn, 
                                                    0,IPCB_Dn,0,bar);           
           //  +定义交易信号                                                      if(MovA [ 1 ]> MovB [ 1 ])
                if(MovA [ 0 ] <MovB [ 0 ])                        SELL_Sign = true ;                          
            if(MovA [ 0 ] <MovB [ 0 ])                        SELL_Stop = true ;                                                          }          //  +交易的执行          if(!OpenSellOrder1(SELL_Sign,2,Money_Management_Dn,                                            STOPLOSS_Dn,TAKEPROFIT_Dn))                                                                   返回( - 1);
          ifClosePos_Dn )
                 if(!CloseOrder1(SELL_Stop,2))
                                         return( - 1);        }     }//  +     
    return0);  }// + - - +



基于两个震荡指标交叉的交易系统

这种交易策略不仅可以使用移动线,还可以使用震荡指标,但对于后者,根据上一篇文章所写,最好设置挂单,而不是在收到信号后立即进入市场。可以使用NACD图表作为生动的示例。

要设置BuyLimit挂单,算法如下:

下面是用于SellLimit类型订单的算法:

该EA的代码跟之前EA的代码类似:

// + =============================================== =================== + // | Exp_7.mq4 | // | 版权所有©2007,Nikolay Kositsin | // | 哈巴罗夫斯克,farria @ mail.redcom.ru | // + =============================================== =================== + #property copyright  “Copyright©2007,Nikolay Kositsin” #property link  “farria@mail.redcom.ru” //  + + -  + //  EA INPUT参数购买交易extern  bool    Test_Up = true ;//交易计算方向过滤器extern  int     Timeframe_Up = 240 ;extern  double Money_Management_Up = 0.1 ;extern  int     FST_period_Up = 12 ;  //快速移动的时间段extern  int     SLO_period_Up = 22 ; //缓慢移动到快速一个外部的 句点增量int     SIGN_period_Up = 8 ; //信号线的周期extern  int     Price_Up = 0 ;  //选择计算MACD的价格extern  int     STOPLOSS_Up = 50 ;  //止损extern  int     TAKEPROFIT_Up = 100 ; // take profit extern  int     PriceLevel_Up = 40 ; //                                          触发extern  bool 的当前价格和//挂单价格之间的差异    ClosePos_Up = true ; //允许强制关闭位置//  + +  - + //  EA INPUT PARAMETERS FOR卖出交易的extern  布尔    Test_Dn =  ;//交易计算方向过滤器extern  int     Timeframe_Dn = 240 ;extern  double Money_Management_Dn = 0.1 ;extern  int     FST_period_Dn = 12 ;  //快速移动的时间段extern  int     SLO_period_Dn = 22 ; //缓慢移动到快速一个外部的 句点增量int     SIGN_period_Dn = 8 ; //信号线的周期extern  int     Price_Dn = 0 ;  //选择计算MACD的价格extern  int     STOPLOSS_Dn = 50 ;  //止损extern  int     TAKEPROFIT_Dn = 100 ; //获取利润extern  int     PriceLevel_Dn = 40 ;  //当前价格和                                         //挂单的价格之间的差异触发extern  bool    ClosePos_Dn = true ; //允许强制关闭位置//  + +  - + // 整数变量的计算条最小诠释 MinBar_Up,MinBar_Dn;// + =============================================== =================== + // | 自定义专家功能| // + =============================================== =================== + #include <Lite_EXPERT1.mqh> // + ==================== ============================================== + // | 自定义专家初始化功能| // + =============================================== =================== + int init()  {// 检查Timeframe_Up变量值的正确性   if(Timeframe_Up!= 1)
     if(Timeframe_Up!= 5)
      if(Timeframe_Up!= 15)
       if(Timeframe_Up!= 30)
        if(Timeframe_Up!= 60ifTimeframe_Up!= 60)
         if( Timeframe_Up!= 240)
          if(Timeframe_Up!= 1440)
            PrintStringConcatenate“参数Timeframe_Up不能”,  
                                   “等于”,Timeframe_Up,“!!!” ));// 检查Timeframe_Dn变量值的正确性   if(Timeframe_Dn!= 1)
     if(Timeframe_Dn!= 5)
      if(Timeframe_Dn!= 15)
       if(Timeframe_Dn!= 30)
        if(Timeframe_Dn!= 60ifTimeframe_Dn!= 60)
         if( Timeframe_Dn!= 240)
          if(Timeframe_Dn!= 1440)
            PrintStringConcatenate“参数Timeframe_Dn不能”),  
                                  “等于”,Timeframe_Dn,“!!!” )); 
// 变量的初始化                 MinBar_Up = 4 + FST_period_Up + SLO_period_Up + SIGN_period_Up;   MinBar_Dn = 4 + FST_period_Dn + SLO_period_Dn + SIGN_period_Dn;                                        // 初始化结束   返回0);  }// + =============================================== =================== + // | 专家取消初始化功能| // + =============================================== =================== +   int deinit()  {//  +   
    //  EA deinitialization     返回结束0);//  +  }// + =============================================== =================== + // | 自定义专家迭代功能| // + =============================================== =================== + int start()  {   //  +声明局部变量   int     bar;
    MovA [ 2 ],MovB [ 2 ];
   //  +声明静态变量   static  int LastBars_Up,LastBars_Dn;
   static  datetime StopTime_Up,StopTime_Dn; 
   static  bool BUY_Sign,BUY_Stop,SELL_Sign,SELL_Stop;   
   //  ++   长期位置代码if(Test_Up)    {      int IBARS_Up = iBarsNULLTimeframe_Up);      
      if(IBARS_Up> = MinBar_Up)       {         if(LastBars_Up!= IBARS_Up)          {           //  +变量的初始化            BUY_Sign = false ;           BUY_Stop = false ;           LastBars_Up = IBARS_Up;           StopTime_Up = iTimeNULLTimeframe_Up0                                            + 60 * Timeframe_Up;           
           //  +计算指示符值和上载他们BUFFERS                       (巴= 1 ;栏< 3 ;巴++)             MovA [bar  - 1 ] = iMACDNULLTimeframe_Up                      FST_period_Up,FST_period_Up + SLO_period_Up,                                         SIGN_period_Up,Price_Up,0,bar);                          
           for(bar = 1 ; bar < 3 ; bar ++)             MovB [bar  - 1 ] = iMACDNULLTimeframe_Up                      FST_period_Up,FST_period_Up + SLO_period_Up,                                         SIGN_period_Up,Price_Up,1,bar);                 
           //  +定义交易信号                                                      if(MovA [ 1 ] <MovB [ 1 ])
                if(MovA [ 0 ]> MovB [ 0 ])                        BUY_Sign = true ;                          
            if(MovA [ 0 ]> MovB [ 0 ])                        BUY_Stop = true ;                                                     }          
          //  +交易的执行          if(!OpenBuyLimitOrder1(BUY_Sign,1              Money_Management_Up,STOPLOSS_Up,TAKEPROFIT_Up,                                            PriceLevel_Up,StopTime_Up))                                                                 返回( - 1);
          ifClosePos_Up )
                 if(!CloseOrder1(BUY_Stop,1))
                                         return( - 1);        }     }     
   //  ++用于短位置的代码   if(Test_Dn)    {      int IBARS_Dn = iBarsNULLTimeframe_Dn);      
      if(IBARS_Dn> = MinBar_Dn)       {         if(LastBars_Dn!= IBARS_Dn)          {           //  +变量的初始化            SELL_Sign = false ;           SELL_Stop = false ;           LastBars_Dn = IBARS_Dn;           StopTime_Dn = iTimeNULLTimeframe_Dn0                                            + 60 * Timeframe_Dn;           
           //  +计算指示符值和上载他们BUFFERS                      (巴= 1 ;栏< 3 ;巴++)             MovA [bar  - 1 ] = iMACDNULLTimeframe_Dn                      FST_period_Dn,FST_period_Dn + SLO_period_Dn,                                         SIGN_period_Dn,Price_Dn,0,bar);                          
           for(bar = 1 ; bar < 3 ; bar ++)             MovB [bar  - 1 ] = iMACDNULLTimeframe_Dn                      FST_period_Dn,FST_period_Dn + SLO_period_Dn,                                         SIGN_period_Dn,Price_Dn,1,bar);           
           //  +定义交易信号                                                      if(MovA [ 1 ]> MovB [ 1 ])
                if(MovA [ 0 ] <MovB [ 0 ])                        SELL_Sign = true ;                          
            if(MovA [ 0 ] <MovB [ 0 ])                        SELL_Stop = true ;                                                          }          //  +执行交易          if(!OpenSellLimitOrder1(SELL_Sign,2              Money_Management_Dn,STOPLOSS_Dn,TAKEPROFIT_Dn,                                            PriceLevel_Dn,StopTime_Dn))                                                                 返回( - 1);
          ifClosePos_Dn )
                 if(!CloseOrder1(SELL_Stop,2))
                                         return( - 1);        }     }//  +     
    return0);  }// + - - +



总结

另一篇文章也已完成。在Expert Advisor中基于绝对不同的指标变体实现了另一个交易系统。希望本文能够对EA编程新手有用,以进一步培养将正确形式化的算法转化为Expert Advisor可用和绝对有效的代码。



全部回复

0/140

量化课程

    移动端课程