在上一篇文章中,我详细介绍了如何编写用于处理来自两个不同时间范围的信息的 Expert Advisor。然而,问题是,这些信息往往还不足以支持准确地进入市场。例如,如果较小的时间范围等于 H1,则在一小时柱发生变化时立即进入市场的做法往往不是最好的解决方案,因为在此时间范围上的趋势小于 H1,而且通常存在于价格噪声之中,可能会对要建立的仓位造成不利。在很多情况下,可相当轻松地检测出这种短期趋势。在这种情况下,如果趋势变动对要建立的仓位不利,你应推迟进入市场,直至最小时间范围上的趋势方向发生反转。或者,在最坏的情况下,你可以在下一次一小时柱变动时进入市场。这就是我尝试在本文解决的任务。
众所周知,Alexander Elder 是交易和群体行为的心理学方面的极畅销书籍的作者。就是他提出了在分析金融市场的过程中使用包括三个时间范围的图表的思路。这些图表被称为 Elder 的三重滤网。我们已经在上一篇文章中了解到如何构建双重滤网。现在,我们要在这个基础上添加第三层滤网。作为进一步编译代码的示例,我们可以使用上一篇文章中的一些现成 EA。然而,在本文中,我决定基于相同的程序构建另一个 EA (Exp_14.mq4),仅仅是为了做些改变。
我将 Exp_12.mq4 作为编写代码的初始基础,其中,我用振荡指标 JCCIX.mq4 替代了提醒移动平均线 Jfatl.nq4,并用包含多个随机振荡指标的指标 StepMA_Stoch_NK.mq4 替代了包含两个 MA 的指标 MAMA_NK.mq4。最终,初始算法保持不变,我只是更改了自定义指标的调用、EA 的外部变量以及 init() 函数块中常数的初始化,我还将各个块的代码设置得更加复杂,旨在检测进入市场的信号。我再次使用了两个时间范围来按非常通用的形式呈现此 EA 的工作算法,就像我在上一篇文章中一样。但是,这次我略微详细些。
对于多头仓位,我们有:
对于空头仓位,我们有:
下面显示了产生的算法,我们需要在程序代码中实现此算法,以便尽可能合理地使用包含三个不同时间范围的图表。
对于多头仓位:
对于空头仓位:
此算法在程序代码中基于 Exp_15.mq4 的实现按如下方式显示:
//+==================================================================+ //| Exp_15.mq4 | //| Copyright © 2008, Nikolay Kositsin | //| Khabarovsk, farria@mail.redcom.ru | //+==================================================================+ #property copyright "Copyright © 2008, Nikolay Kositsin" #property link "farria@mail.redcom.ru" //----+ +---------------------------------------------------------------------------+ //---- EXPERT ADVISORS INPUTS FOR BUY TRADES extern bool Test_Up = true;//filter of trade calculations direction extern double Money_Management_Up = 0.1; //---- + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + extern int TimeframeX_Up = 1440; extern int PeriodWATR_Up = 10; extern double Kwatr_Up = 1.0000; extern int HighLow_Up = 0; //---- + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + extern int Timeframe_Up = 240; extern int JJLength_Up = 8; // depth of JJMA smoothing for the entry price extern int JXLength_Up = 8; // depth of JurX smoothing for the obtained indicator extern int Phase_Up = 100;// the parameter ranging // from -100 to +100 influences the process quality; extern int IPC_Up = 0; /* Selecting price to calculate the indicator on (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 TimeframeN_Up = 15; extern int Noise_period_Up = 8; //extern int SmoothN_Up = 7; //extern int MaMethodN_Up = 1; //---- + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + extern int STOPLOSS_Up = 50; // StopLoss extern int TAKEPROFIT_Up = 100; // TakeProfit extern bool ClosePos_Up = true; // enable forcible closing the position //----+ +---------------------------------------------------------------------------+ //---- EXPERT ADVISORS INPUTS FOR SELL TRADES extern bool Test_Dn = true;//filter of trade calculations direction extern double Money_Management_Dn = 0.1; //---- + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + extern int TimeframeX_Dn = 1440; extern int PeriodWATR_Dn = 10; extern double Kwatr_Dn = 1.0000; extern int HighLow_Dn = 0; //---- + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + extern int Timeframe_Dn = 240; extern int JJLength_Dn = 8; // depth of JJMA smoothing for the entry price extern int JXLength_Dn = 8; // depth of JurX smoothing for the obtained indicator extern int Phase_Dn = 100;// the parameter ranging // from -100 to +100 influences the process quality; extern int IPC_Dn = 0; /* Selecting price to calculate the indicator on (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 TimeframeN_Dn = 15; extern int Noise_period_Dn = 8; //extern int SmoothN_Dn = 7; //extern int MaMethodN_Dn = 1; //---- + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + extern int STOPLOSS_Dn = 50; // StopLoss extern int TAKEPROFIT_Dn = 100; // TakeProfit extern bool ClosePos_Dn = true; // enable forcible closing the position //----+ +---------------------------------------------------------------------------+ //---- Integer variables for calling to custom indicators int SmoothN_Up = 7, SmoothN_Dn = 7, MaMethodN_Up = 1, MaMethodN_Dn = 1; //---- Integer variables for the minimum of reference bars int MinBar_Up, MinBar_Dn, MinBarX_Up, MinBarX_Dn, MinBarN_Up, MinBarN_Dn; //+==================================================================+ //| Custom Expert functions | //+==================================================================+ #include <Lite_EXPERT1.mqh> //+==================================================================+ //| TimeframeCheck() functions | //+==================================================================+ void TimeframeCheck(string Name, int Timeframe) { //----+ //---- Checking the value of variable Timeframe for correctness if (Timeframe != 1) if (Timeframe != 5) if (Timeframe != 15) if (Timeframe != 30) if (Timeframe != 60) if (Timeframe != 240) if (Timeframe != 1440) Print(StringConcatenate("Parameter ",Name, " cannot ", "be equal to ", Timeframe, "!!!")); //----+ } //+==================================================================+ //| Custom Expert initialization function | //+==================================================================+ int init() { //---- Checking the values of timeframe variables for correctness TimeframeCheck("TimeframeX_Up", TimeframeX_Up); TimeframeCheck("Timeframe_Up", Timeframe_Up); TimeframeCheck("TimeframeN_Up", TimeframeN_Up); //---- Checking the values of timeframe variables for correctness TimeframeCheck("TimeframeX_Dn", TimeframeX_Dn); TimeframeCheck("Timeframe_Dn", Timeframe_Dn); TimeframeCheck("TimeframeN_Dn", TimeframeN_Dn); //---- Initialization of variables MinBarX_Up = 2 + PeriodWATR_Up; MinBar_Up = 4 + 3 * JXLength_Up + 30; MinBarN_Up = 4 + Noise_period_Up + SmoothN_Up; //---- Initialization of variables MinBarX_Dn = 2 + PeriodWATR_Dn; MinBar_Dn = 4 + 3 * JXLength_Dn + 30; MinBarN_Dn = 4 + Noise_period_Dn + SmoothN_Dn; //---- initialization complete return(0); } //+==================================================================+ //| expert deinitialization function | //+==================================================================+ int deinit() { //----+ //---- EA deinitialization complete return(0); //----+ } //+==================================================================+ //| Custom Expert iteration function | //+==================================================================+ int start() { //----+ Declaration of local variables int bar; double JCCIX[2], Trend, Fast_StepMA, Slow_StepMA, MA1, MA2; //----+ Declaration of static variables static datetime StopTime_Up, StopTime_Dn; static double TrendX_Up, TrendX_Dn, OldTrend_Up, OldTrend_Dn; //--- static int LastBars_Up, LastBars_Dn; static int LastBarsX_Up, LastBarsX_Dn, LastBarsN_Up, LastBarsN_Dn; //--- static bool BUY_Sign, BUY_Stop, SELL_Sign, SELL_Stop; static bool SecondStart_Up, SecondStart_Dn, NoiseBUY_Sign, NoiseSELL_Sign; //----+ +---------------------------------------------------------------+ //----++ CODE FOR LONG POSITIONS | //----+ +---------------------------------------------------------------+ if (Test_Up) { int IBARS_Up = iBars(NULL, Timeframe_Up); int IBARSX_Up = iBars(NULL, TimeframeX_Up); int IBARSN_Up = iBars(NULL, TimeframeN_Up); //--- if (IBARS_Up >= MinBar_Up && IBARSX_Up >= MinBarX_Up && IBARSN_Up >= MinBarN_Up) { //----+ +----------------------+ //----+ DETECTING A TREND | //----+ +----------------------+ if (LastBarsX_Up != IBARSX_Up) { //----+ Initialization of variables LastBarsX_Up = IBARSX_Up; BUY_Sign = false; BUY_Stop = false; //----+ calculating the values of indicators Fast_StepMA = iCustom(NULL, TimeframeX_Up, "StepMA_Stoch_NK", PeriodWATR_Up, Kwatr_Up, HighLow_Up, 0, 1); //--- Slow_StepMA = iCustom(NULL, TimeframeX_Up, "StepMA_Stoch_NK", PeriodWATR_Up, Kwatr_Up, HighLow_Up, 1, 1); //----+ detecting a trend TrendX_Up = Fast_StepMA - Slow_StepMA; //----+ defining a signal to close trades if (TrendX_Up < 0) BUY_Stop = true; } //----+ +----------------------------------------+ //----+ DETECTING SIGNALS TO ENTER THE MARKET | //----+ +----------------------------------------+ if (LastBars_Up != IBARS_Up && TrendX_Up > 0) { //----+ Initialization of variables BUY_Sign = false; LastBars_Up = IBARS_Up; //----+ Initialization of noise variables NoiseBUY_Sign = false; StopTime_Up = iTime(NULL, Timeframe_Up, 0) + 50 * Timeframe_Up; //----+ Initialization of zero if (!SecondStart_Up) { //--- Search for trend direction at the first start for(bar = 2; bar < IBARS_Up - 1; bar++) { JCCIX[0] = iCustom(NULL, Timeframe_Up, "JCCIX", JJLength_Up, JXLength_Up, Phase_Up, IPC_Up, 0, bar); //--- JCCIX[1] = iCustom(NULL, Timeframe_Up, "JCCIX", JJLength_Up, JXLength_Up, Phase_Up, IPC_Up, 0, bar + 1); //--- OldTrend_Up = JCCIX[0] - JCCIX[1]; //--- if (OldTrend_Up != 0) { SecondStart_Up = true; break; } } } //----+ calculating the values of indicators and loading them to a buffer for(bar = 1; bar < 3; bar++) JCCIX[bar - 1] = iCustom(NULL, Timeframe_Up, "JCCIX", JJLength_Up, JXLength_Up, Phase_Up, IPC_Up, 0, bar); //----+ detecting signals for trades Trend = JCCIX[0] - JCCIX[1]; if (TrendX_Up > 0) if (OldTrend_Up < 0) if (Trend > 0) BUY_Sign = true; if (Trend != 0) OldTrend_Up = Trend; } //----+ +------------------------------------------------+ //----+ DETECTING NOISE SIGNALS TO ENTER THE MARKET | //----+ +------------------------------------------------+ if (BUY_Sign) if (LastBarsN_Up != IBARSN_Up) { NoiseBUY_Sign = false; LastBarsN_Up = IBARSN_Up; //--- MA1 = iCustom(NULL, TimeframeN_Up, "2Moving Avereges", Noise_period_Up, SmoothN_Up, MaMethodN_Up, MaMethodN_Up, PRICE_LOW, 0, 0, 1); //--- MA2 = iCustom(NULL, TimeframeN_Up, "2Moving Avereges", Noise_period_Up, SmoothN_Up, MaMethodN_Up, MaMethodN_Up, PRICE_LOW, 0, 0, 2); //--- if (MA1 > MA2 || TimeCurrent() > StopTime_Up) NoiseBUY_Sign = true; } //----+ +-------------------+ //----+ MAKING TRADES | //----+ +-------------------+ if (NoiseBUY_Sign) if (!OpenBuyOrder1(BUY_Sign, 1, Money_Management_Up, STOPLOSS_Up, TAKEPROFIT_Up)) return(-1); if (ClosePos_Up) if (!CloseOrder1(BUY_Stop, 1)) return(-1); } } //----+ +---------------------------------------------------------------+ //----++ CODE FOR SHORT POSITIONS | //----+ +---------------------------------------------------------------+ if (Test_Dn) { int IBARS_Dn = iBars(NULL, Timeframe_Dn); int IBARSX_Dn = iBars(NULL, TimeframeX_Dn); int IBARSN_Dn = iBars(NULL, TimeframeN_Dn); //--- if (IBARS_Dn >= MinBar_Dn && IBARSX_Dn >= MinBarX_Dn && IBARSN_Dn >= MinBarN_Dn) { //----+ +----------------------+ //----+ DETECTING A TREND | //----+ +----------------------+ if (LastBarsX_Dn != IBARSX_Dn) { //----+ Initialization of variables LastBarsX_Dn = IBARSX_Dn; SELL_Sign = false; SELL_Stop = false; //----+ calculating the values of indicators Fast_StepMA = iCustom(NULL, TimeframeX_Dn, "StepMA_Stoch_NK", PeriodWATR_Dn, Kwatr_Dn, HighLow_Dn, 0, 1); //--- Slow_StepMA = iCustom(NULL, TimeframeX_Dn, "StepMA_Stoch_NK", PeriodWATR_Dn, Kwatr_Dn, HighLow_Dn, 1, 1); //----+ detecting a trend TrendX_Dn = Fast_StepMA - Slow_StepMA; //----+ defining a signal to close trades if (TrendX_Dn > 0) SELL_Stop = true; } //----+ +----------------------------------------+ //----+ DETECTING SIGNALS TO ENTER THE MARKET | //----+ +----------------------------------------+ if (LastBars_Dn != IBARS_Dn && TrendX_Dn < 0) { //----+ Initialization of variables SELL_Sign = false; LastBars_Dn = IBARS_Dn; //----+ Initialization of noise variables NoiseSELL_Sign = false; StopTime_Dn = iTime(NULL, Timeframe_Dn, 0) + 50 * Timeframe_Dn; //----+ Initialization of zero if (!SecondStart_Dn) { //--- Search for trend direction at the first start for(bar = 2; bar < IBARS_Dn - 1; bar++) { JCCIX[0] = iCustom(NULL, Timeframe_Dn, "JCCIX", JJLength_Dn, JXLength_Dn, Phase_Dn, IPC_Dn, 0, bar); //--- JCCIX[1] = iCustom(NULL, Timeframe_Dn, "JCCIX", JJLength_Dn, JXLength_Dn, Phase_Dn, IPC_Dn, 0, bar + 1); //--- OldTrend_Dn = JCCIX[0] - JCCIX[1]; //--- if (OldTrend_Dn != 0) { SecondStart_Dn = true; break; } } } //----+ calculating the values of indicators and loading them to a buffer for(bar = 1; bar < 3; bar++) JCCIX[bar - 1]= iCustom(NULL, Timeframe_Dn, "JCCIX", JJLength_Dn, JXLength_Dn, Phase_Dn, IPC_Dn, 0, bar); //----+ detecting signals for trades Trend = JCCIX[0] - JCCIX[1]; //--- if (TrendX_Dn < 0) if (OldTrend_Dn > 0) if (Trend < 0) SELL_Sign = true; if (Trend != 0) OldTrend_Dn = Trend; } //----+ +------------------------------------------------+ //----+ DETECTING NOISE SIGNALS TO ENTER THE MARKET | //----+ +------------------------------------------------+ if (SELL_Sign) if (LastBarsN_Dn != IBARSN_Dn) { NoiseSELL_Sign = false; LastBarsN_Dn = IBARSN_Dn; //--- MA1 = iCustom(NULL, TimeframeN_Dn, "2Moving Avereges", Noise_period_Dn, SmoothN_Dn, MaMethodN_Dn, MaMethodN_Dn, PRICE_HIGH, 0, 0, 1); //--- MA2 = iCustom(NULL, TimeframeN_Dn, "2Moving Avereges", Noise_period_Dn, SmoothN_Dn, MaMethodN_Dn, MaMethodN_Dn, PRICE_HIGH, 0, 0, 2); //--- if (MA1 < MA2 || TimeCurrent() > StopTime_Dn) NoiseSELL_Sign = true; } //----+ +-------------------+ //----+ MAKING TRADES | //----+ +-------------------+ if (NoiseSELL_Sign) if (!OpenSellOrder1(SELL_Sign, 2, Money_Management_Dn, STOPLOSS_Dn, TAKEPROFIT_Dn)) return(-1); if (ClosePos_Dn) if (!CloseOrder1(SELL_Stop, 2)) return(-1); } } //----+ return(0); } //+------------------------------------------------------------------+
现在,我们应进入将 Exp_14.mq4 转变成 Exp_15.mq4 的细节部分。我们在程序代码中有一个新的模块,即“DETECTING NOISE SIGNALS TO ENTER THE MARKET”。可按如下方式显示此模块的操作点(我正在考虑仅用于多头仓位的算法):
如果最小时间范围上的趋势方向与市场进入信号 BUY_Sig 的方向相一致,则出现信号 NoiseBUY_Sign。或者,如果此趋势不一致,最小时间范围上NoiseBUY_Sign
作为趋势跟踪 MA,我使用了通过标准平均算法对价格序列进行双重平滑处理而获得的指标。作为 EA 在此模块的外部参数,我仅使用了两个变量:
extern int TimeframeN_Up = 15; extern int Noise_period_Up = 8;
我将自定义指标2Moving Avereges.mq4 fixed(全局变量的初始化):
int SmoothN_Up = 7, SmoothN_Dn = 7, MaMethodN_Up = 1, MaMethodN_Dn = 1;
添加代码的基本逻辑与我在上一篇文章中介绍的完全相同。
通常,EA 的代码是现成的,我可以在这个阶段停下来。但是,我认为,这项工作中最小的一部分确实已完成。基于此思路编写的第一个交易系统在实际交易中很难产生良好的结果。因此,我们应接受这一现实:我们需要编写一两个相似的 EA 的代码,以便从中选择一个更合适的版本。现在,我们面临一个从计算算法的具体交易信号中提取并仅使用三重滤网算法的任务。通常,这不成问题。产生的不含算法的代码如下所示:
//+==================================================================+ //| ThreeScreens.mqh | //| Copyright © 2008, Nikolay Kositsin | //| Khabarovsk, farria@mail.redcom.ru | //+==================================================================+ #property copyright "Copyright © 2008, Nikolay Kositsin" #property link "farria@mail.redcom.ru" //----+ +---------------------------------------------------------------------------+ //---- EXPERT ADVISORS INPUTS FOR BUY TRADES extern bool Test_Up = true;//filter of trade calculations direction extern double Money_Management_Up = 0.1; //---- + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + extern int TimeframeX_Up = 1440; // Declarations and initializations of the EA external parameters for long positions for the largest timeframe //---- + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + extern int Timeframe_Up = 240; // Declarations and initializations of the EA external parameters for long positions for the middle timeframe //---- + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + extern int TimeframeN_Up = 15; // Declarations and initializations of the EA external parameters for long positions for the smallest timeframe //---- + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + extern int STOPLOSS_Up = 50; // StopLoss extern int TAKEPROFIT_Up = 100; // TakeProfit extern bool ClosePos_Up = true; // enable forcible closing the position //----+ +---------------------------------------------------------------------------+ //---- EXPERT ADVISORS INPUTS FOR SELL TRADES extern bool Test_Dn = true;//filter of trade calculations direction extern double Money_Management_Dn = 0.1; //---- + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + extern int TimeframeX_Dn = 1440; // Declarations and initializations of the EA external parameters for short positions for largest timeframe //---- + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + extern int Timeframe_Dn = 240; // Declarations and initializations of the EA external parameters for short positions for middle timeframe //---- + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + extern int TimeframeN_Dn = 15; // Declarations and initializations of the EA external parameters for short positions for the smallest timeframe //---- + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + extern int STOPLOSS_Dn = 50; // StopLoss extern int TAKEPROFIT_Dn = 100; // TakeProfit extern bool ClosePos_Dn = true; // enable forcible closing the position //----+ +---------------------------------------------------------------------------+ //---- Integer variables for the minimum of reference bars int MinBar_Up, MinBar_Dn, MinBarX_Up, MinBarX_Dn, MinBarN_Up, MinBarN_Dn; //+==================================================================+ //| Custom Expert functions | //+==================================================================+ #include <Lite_EXPERT1.mqh> //+==================================================================+ //| TimeframeCheck() functions | //+==================================================================+ void TimeframeCheck(string Name, int Timeframe) { //----+ //---- Checking the value of variable Timeframe for correctness if (Timeframe != 1) if (Timeframe != 5) if (Timeframe != 15) if (Timeframe != 30) if (Timeframe != 60) if (Timeframe != 240) if (Timeframe != 1440) Print(StringConcatenate("Parameter ",Name, " cannot ", "be equal to ", Timeframe, "!!!")); //----+ } //+==================================================================+ //| Custom Expert initialization function | //+==================================================================+ int init() { //---- Checking the values of timeframe variables for correctness TimeframeCheck("TimeframeX_Up", TimeframeX_Up); TimeframeCheck("Timeframe_Up", Timeframe_Up); TimeframeCheck("TimeframeN_Up", TimeframeN_Up); //---- Checking the values of timeframe variables for correctness TimeframeCheck("TimeframeX_Dn", TimeframeX_Dn); TimeframeCheck("Timeframe_Dn", Timeframe_Dn); TimeframeCheck("TimeframeN_Dn", TimeframeN_Dn); //---- Initialization of variables for long positions MinBarX_Up = // initialization of the variable for the minimum reference bars for largest timeframe MinBar_Up = // initialization of the variable for the minimum reference bars for middle timeframe MinBarN_Up = // initialization of the variable for the minimum reference bars for the smallest timeframe //---- Initialization of variables for short positions MinBarX_Dn = // initialization of the variable for the minimum reference bars for largest timeframe MinBar_Dn = // initialization of the variable for the minimum reference bars for middle timeframe MinBarN_Dn = // initialization of the variable for the minimum reference bars for the smallest timeframe //---- initialization complete return(0); } //+==================================================================+ //| expert deinitialization function | //+==================================================================+ int deinit() { //----+ //---- EA deinitialization complete return(0); //----+ } //+==================================================================+ //| Custom Expert iteration function | //+==================================================================+ int start() { //----+ Declaration of local variables of trading algorithms //----+ Declaration of static variables of trading algortihms //----+ Declaration of static variables static datetime StopTime_Up, StopTime_Dn; //--- static int LastBars_Up, LastBars_Dn; static int LastBarsX_Up, LastBarsX_Dn; static int LastBarsN_Up, LastBarsN_Dn; //--- static bool BUY_Sign, BUY_Stop; static bool SELL_Sign, SELL_Stop; static bool NoiseBUY_Sign, NoiseSELL_Sign; static double TrendX_Up, TrendX_Dn; //----+ +---------------------------------------------------------------+ //----++ CODE FOR LONG POSITIONS | //----+ +---------------------------------------------------------------+ if (Test_Up) { int IBARS_Up = iBars(NULL, Timeframe_Up); int IBARSX_Up = iBars(NULL, TimeframeX_Up); int IBARSN_Up = iBars(NULL, TimeframeN_Up); //--- if (IBARS_Up >= MinBar_Up && IBARSX_Up >= MinBarX_Up && IBARSN_Up >= MinBarN_Up) { //----+ +----------------------+ //----+ DETECTING A TREND | //----+ +----------------------+ if (LastBarsX_Up != IBARSX_Up) { //----+ Initialization of variables LastBarsX_Up = IBARSX_Up; BUY_Sign = false; BUY_Stop = false; // Trend direction detecting algorithm on the largest timeframe //(initializing variable TrendX_Up) //----+ defining a signal to close trades if (TrendX_Up < 0) BUY_Stop = true; } //----+ +----------------------------------------+ //----+ DETECTING SIGNALS TO ENTER THE MARKET | //----+ +----------------------------------------+ if (LastBars_Up != IBARS_Up && TrendX_Up > 0) { //----+ Initialization of variables BUY_Sign = false; LastBars_Up = IBARS_Up; //----+ Initialization of noise variables NoiseBUY_Sign = false; StopTime_Up = iTime(NULL, Timeframe_Up, 0) + 50 * Timeframe_Up; // Entering point determining algorithm on the middle timeframe //(Initializing variable BUY_Sign) } //----+ +------------------------------------------------+ //----+ DETECTING NOISE SIGNALS TO ENTER THE MARKET | //----+ +------------------------------------------------+ if (BUY_Sign) if (LastBarsN_Up != IBARSN_Up) { NoiseBUY_Sign = false; LastBarsN_Up = IBARSN_Up; //--- // Entering point precising algorithm on the smallest timeframe //(Initializing variable NoiseBUY_Sign) } //----+ +-------------------+ //----+ MAKING TRADES | //----+ +-------------------+ if (NoiseBUY_Sign) if (!OpenBuyOrder1(BUY_Sign, 1, Money_Management_Up, STOPLOSS_Up, TAKEPROFIT_Up)) return(-1); if (ClosePos_Up) if (!CloseOrder1(BUY_Stop, 1)) return(-1); } } //----+ +---------------------------------------------------------------+ //----++ CODE FOR SHORT POSITIONS | //----+ +---------------------------------------------------------------+ if (Test_Dn) { int IBARS_Dn = iBars(NULL, Timeframe_Dn); int IBARSX_Dn = iBars(NULL, TimeframeX_Dn); int IBARSN_Dn = iBars(NULL, TimeframeN_Dn); //--- if (IBARS_Dn >= MinBar_Dn && IBARSX_Dn >= MinBarX_Dn && IBARSN_Dn >= MinBarN_Dn) { //----+ +----------------------+ //----+ DETECTING A TREND | //----+ +----------------------+ if (LastBarsX_Dn != IBARSX_Dn) { //----+ Initialization of variables LastBarsX_Dn = IBARSX_Dn; SELL_Sign = false; SELL_Stop = false; // Trend direction detecting algorithm on the largest timeframe //(initializing variable TrendX_Dn) //----+ defining a signal to close trades if (TrendX_Dn > 0) SELL_Stop = true; } //----+ +----------------------------------------+ //----+ DETECTING SIGNALS TO ENTER THE MARKET | //----+ +----------------------------------------+ if (LastBars_Dn != IBARS_Dn && TrendX_Dn < 0) { //----+ Initialization of variables SELL_Sign = false; LastBars_Dn = IBARS_Dn; //----+ Initialization of noise variables NoiseSELL_Sign = false; StopTime_Dn = iTime(NULL, Timeframe_Dn, 0) + 50 * Timeframe_Dn; // Entering point determining algorithm on the middle timeframe //(Initializing variable SELL_Sign) } //----+ +------------------------------------------------+ //----+ DETECTING NOISE SIGNALS TO ENTER THE MARKET | //----+ +------------------------------------------------+ if (SELL_Sign) if (LastBarsN_Dn != IBARSN_Dn) { NoiseSELL_Sign = false; LastBarsN_Dn = IBARSN_Dn; //--- // Entering point precising algorithm on the smallest timeframe //(Initializing variable NoiseSELL_Sign) } //----+ +-------------------+ //----+ MAKING TRADES | //----+ +-------------------+ if (NoiseSELL_Sign) if (!OpenSellOrder1(SELL_Sign, 2, Money_Management_Dn, STOPLOSS_Dn, TAKEPROFIT_Dn)) return(-1); if (ClosePos_Dn) if (!CloseOrder1(SELL_Stop, 2)) return(-1); } } //----+ return(0); } //+------------------------------------------------------------------+
如果我们将此代码作为编写 EA 的模板,首先,我们应对相应块中的变量 EA 进行初始化:“DETECTING A TREND”和“DETECTING NOISE SIGNAL TO ENTER THE MARKET”:
TrendX_Up = 1; TrendX_Dn =-1; Noise8uy_Sign = true; NoiseSELL_Sign = true;
之后,你可以将自己的代码添加到 “DETECTING SIGNALS TO ENTER THE MARKET”的块中,并调整 EA 以使用此代码。你可以在 EA Exp_15_A.mq4 的代码中了解如何执行此操作,在此代码中,只有用于检测中等时间范围的进入市场信号的算法,而没有旨在检测最大时间范围上的趋势的算法,或者旨在检测最小时间范围的噪声趋势的算法。你应注意有关块 int init() 的最小柱数的变量的初始化,在此例中为:
//---- Initialization of variables MinBarX_Up = 0; MinBar_Up = 4 + 3 * JXLength_Up + 30; MinBarN_Up = 0; //---- Initialization of variables MinBarX_Dn = 0; MinBar_Dn = 4 + 3 * JXLength_Dn + 30; MinBarN_Dn = 0;
第二步,从“DETECTING A TREND”的块中删除初始化:
TrendX_Up = 1; TrendX_Dn =-1;
将用于检测趋势方向的代码添加到这些块中,并再次调整 EA。这一阶段的代码编写将显示 Exp_15_B.mq4 中。不要忘记初始化块 init() 中的变量 MinBarX_Up 和 MinBarX_Dn:
//---- Initialization of variables MinBarX_Up = 2 + PeriodWATR_Up; MinBar_Up = 4 + 3 * JXLength_Up + 30; MinBarN_Up = 0; //---- Initialization of variables MinBarX_Dn = 2 + PeriodWATR_Dn; MinBar_Dn = 4 + 3 * JXLength_Dn + 30; MinBarN_Dn = 0;
结果我们得到在两个时间范围上工作的 EA。第三步,与“DETECTING NOISE SIGNALS TO ENTER THE MARKET”的块中的 EA 代码的方式完全相同,将初始化
Noise8uy_Sign = true; NoiseSELL_Sign = true;
从这些块中初步删除,并添加算术运算以对块 int init() 的最小柱数的变量进行初始化,在此例中为:
//---- Initialization of variables MinBarX_Up = 2 + PeriodWATR_Up; MinBar_Up = 4 + 3 * JXLength_Up + 30; MinBarN_Up = 4 + Noise_period_Up + SmoothN_Up; //---- Initialization of variables MinBarX_Dn = 2 + PeriodWATR_Dn; MinBar_Dn = 4 + 3 * JXLength_Dn + 30; MinBarN_Dn = 4 + Noise_period_Dn + SmoothN_Dn;
因此,EA 代码的构建分成三个阶段。然而,如果你尝试仅在一个阶段内构建好此代码,你可能会犯一些错误,而将来会很难轻松地检测出这些错误!
在本文中,我提出了使用三个时间范围编写 Expert Advisor 的通用方法。在技术上,在 MQL4 中能够非常轻松地实现此想法。尽管如此,还有一个问题:“什么解决方案能够帮助揭示其一定的实际意义?”
本社区仅针对特定人员开放
查看需注册登录并通过风险意识测评
5秒后跳转登录页面...
移动端课程