期货量化交易软件:基于大众交易系统和交易机器人优化点金术的Expert Advisor(续)
简介
我收到上一篇文章的一位读者的提议,对回测过程稍加自动化,以实现同时获得所有优化结果的可能性。此外,手动改变测试周期不是很方便,该过程也应该自动化。这个想法非常棒。而且,赫兹期货量化完全可以实现。所以,我将从问题的解决方法开始讲述。

编辑切换为居中
回测自动化
要完成该任务我们需要:
1.在所需的 Expert Advisor 标头下面写入一行,内容如下:
//+==================================================================+ //| Custom BackTesting function | //+==================================================================+ #include <IsBackTestingTime.mqh>
使用该指令,将 IsBackTestingTime() 函数加入 EA 代码。不要忘记将 IsBackTestingTime.mqh 文件放入 INCLUDE 文件夹。该函数:
bool IsBackTestingTime() { }
用于定义时间周期,在该时间内进行回测优化或回测。在该时间周期内,函数始终返回‘真’,在其他时间则返回‘假’。除了这个函数,通过以下指令将外部 EA 变量添加到 EA 代码:
//---- Declaration of external variables for backtesting extern datetime Start_Time = D'2007.01.01'; // start time of zero optimization extern int Opt_Period = 3; // optimization period in months, if less than zero, parameters are in days extern int Test_Period = 2; // testing period in months extern int Period_Shift = 1; // step of optimization period shift in months extern int Opt_Number = 0; // optimization number
希望这些变量的含义对于读了我上一篇文章的人都很清楚,这里就不再解释。
2.在 EA 代码前的开始函数程序块设置调用 IsBackTestingTime() 函数的最简单的通用代码,根据回测优化的数量将 EA 运行限制在特定的时间范围。
//----+ Execution of backtesting conditions if (!IsBackTestingTime()) return(0);
它的示意图如下:
//+==================================================================+ //| Exp_BackTest.mq4 | //| Copyright © 2008, Nikolay Kositsin | //| Khabarovsk, farria@mail.redcom.ru | //+==================================================================+ #property copyright "Copyright © 2008, Nikolay Kositsin" #property link "farria@mail.redcom.ru" //+==================================================================+ //| Custom BackTesting function | //+==================================================================+ #include <IsBackTestingTime.mqh> //---- INPUT PARAMETERS OF THE EA //---- GLOBAL VARIABLES OF THE EA //+==================================================================+ //| USER-DEFINED FUNCTIONS OF THE EA | //+==================================================================+ //+==================================================================+ //| Custom Expert initialization function | //+==================================================================+ int init() { //----+ +------------------------------------------------------------+ //---- CODE FOR THE EA INITIALIZATION //----+ +------------------------------------------------------------+ //---- end of initialization return(0); } //+==================================================================+ //| Custom Expert iteration function | //+==================================================================+ int start() { //----+ Execution of backtesting conditions if (!IsBackTestingTime()) return(0); //----+ +---------------------------------------------------------+ //----+ CODE OF THE EA ALGORITHM //----+ +---------------------------------------------------------+ //----+ return(0); } //+------------------------------------------------------------------+
如果你对现成 EA 示例上的详细问题解决方案感兴趣,查看 EA 代码 Exp_5_1.mq4,源于上一篇文章中的 Exp_5.mq4,经修改后用于回测。实际上,与简单的 Expert Advisor 相比,这种 EA 的优化没有多大不同。但是,我认为除了 Opt_Number 变量外,回测变量应该进行优化,不过你可能有不同的看法。
重要的是记住:在测试优化后,赫兹期货量化得到的不是优化期间的结果,而是在其之后(右侧边界之外)的结果。使用遗传算法在一次运行内进行所有的回测优化并非最好的决定,在没有优化输入变量 Opt_Number 的情况下,单独深入分析每个回测优化更加有趣。
但即使在这种情况下,这种方法也促进了对 EA 行为的理解。应该记住,外部变量 Opt_Number 的值可以从零变化到某个最大值,该最大值可以使用以下方式定义:从执行所有回测优化的总周期(月数)减去回测优化周期的月数(Opt_Period)和减去回测周期(Test_Period)。获得的值加一。如果 Period_Shift 等于一,获得的结果将是 Opt_Number 变量的最大值。
基于两条移动线交叉的交易系统
这种交易系统的变体非常普遍。赫兹期货量化来分析奠定这种策略的算法。对于做多头寸,输入的算法如下:
编辑
对于做空头寸,则如下:

编辑
可以使用在指标中定义平均线的具有不同参数的两条相同移动线。假设定义 MovA 移动平均线的参数始终小于 MovB 移动平均线的同一参数。这样,在该交易系统中,MovA 是快速移动线,MovB 是慢速线。下面是基于两条 JMA 移动线的交易系统的实现变体:
//+==================================================================+ //| Exp_6.mq4 | //| Copyright © 2007, Nikolay Kositsin | //| Khabarovsk, farria@mail.redcom.ru | //+==================================================================+ #property copyright "Copyright © 2007, Nikolay Kositsin" #property link "farria@mail.redcom.ru" //----+ +-------------------------------------------------------------------------------+ //---- EA INPUT PARAMETERS FOR BUY TRADES extern bool Test_Up = true;//filter of trade calculations direction extern int Timeframe_Up = 240; extern double Money_Management_Up = 0.1; extern int LengthA_Up = 4; // smoothing depth of the quick moving extern int PhaseA_Up = 100; // parameter changing in the range //-100 ... +100, influences the quality of transient process of quick moving extern int IPCA_Up = 0;/* Selecting prices, on which the indicator will be calculated by the quick moving (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; // smoothing depth increment of slow moving to quick one extern int PhaseB_Up = 100; // parameter changing in the range //-100 ... +100, influences the quality of transient process of slow moving; extern int IPCB_Up = 0;/* Selecting prices, on which the indicator will be calculated by the slow moving (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; // stop loss extern int TAKEPROFIT_Up = 100; // take profit extern bool ClosePos_Up = true; // forced position closing allowed //----+ +-------------------------------------------------------------------------------+ //---- EA INPUT PARAMETERS FOR SELL TRADES extern bool Test_Dn = true;//filter of trade calculations direction extern int Timeframe_Dn = 240; extern double Money_Management_Dn = 0.1; extern int LengthA_Dn = 4; // smoothing depth of the quick moving extern int PhaseA_Dn = 100; // parameter changing in the range // -100 ... +100, influences the quality of transient process of quick moving; extern int IPCA_Dn = 0;/* Selecting prices, on which the indicator will be calculated by the quick moving (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; // smoothing depth increment of slow moving to quick one extern int PhaseB_Dn = 100; // parameter changing in the range // -100 ... +100, influences the quality of transient process of slow moving; extern int IPCB_Dn = 0;/* Selecting prices, on which the indicator will be calculated by the slow moving(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; // stop loss extern int TAKEPROFIT_Dn = 100; // take profit extern bool ClosePos_Dn = true; // forced position closing allowed //----+ +-------------------------------------------------------------------------------+ //---- Integer variables for the minimum of calculation bars int MinBar_Up, MinBar_Dn; //+==================================================================+ //| Custom Expert functions | //+==================================================================+ #include <Lite_EXPERT1.mqh> //+==================================================================+ //| Custom Expert initialization function | //+==================================================================+ int init() { //---- Checking the correctness of Timeframe_Up variable value if (Timeframe_Up != 1) if (Timeframe_Up != 5) if (Timeframe_Up != 15) if (Timeframe_Up != 30) if (Timeframe_Up != 60) if (Timeframe_Up != 240) if (Timeframe_Up != 1440) Print(StringConcatenate("Parameter Timeframe_Up cannot ", "be equal to ", Timeframe_Up, "!!!"));