English Русский 中文 Español Deutsch 日本語
Expert Advisors baseado em estratégias de trading populares e alquimia da otimização de robô de trading (Parte VI)

Expert Advisors baseado em estratégias de trading populares e alquimia da otimização de robô de trading (Parte VI)

MetaTrader 4Sistemas de negociação | 8 fevereiro 2016, 07:25
688 0
Nikolay Kositsin
Nikolay Kositsin

Introdução

No meu artigo anterior, dei uma descrição detalhada sobre a escrita de Expert Advisors que processam a informação que chega de dois timeframes diferentes. Entretanto, a questão é que essa informação geralmente é insuficiente para entrar com precisão no mercado. Por exemplo, se um timeframe menor é igual a H1, então entrar no mercado imediatamente durante a mudança de uma barra de uma hora geralmente não é a melhor solução, uma vez que a tendência no timeframe menor do que H1, e geralmente existente no ruído de preço, pode trabalhar contra a posição a ser aberta. Em muitos casos, essa tendência a curto prazo pode ser detectada mais facilmente. Em tal caso, se ela se move contra a posição a ser aberta, você deve adiar sua entrada no mercado até que essa tendência que age no menor timeframe mude sua direção para uma direção oposta. Ou, no pior dos casos, você pode entrar no mercado antes que a próxima barra de uma hora mude. É essa tarefa que tentarei resolver no meu artigo.

Sistema Triple Screen de Elder

Alexander Elder é conhecido por ser o autor de livros bastante populares na psicologia do trading e comportamento de massas. Foi ele quem inventou a ideia de usar os gráficos de três timeframes na análise financeira de mercados. Esses gráficos foram nomeados Triple Screen de Elder. Já aprendemos no meu artigo anterior a construir uma tela dupla. Agora temos que adicionar a terceira tela a ele. Como os exemplos da compilação de código seguinte, pudemos ver alguns EAs prontos do meu artigo anterior. Entretanto, no presente artigo, decidi construir outro EA (Exp_14.mq4) com base nos mesmos procedimentos, apenas para fazer algo diferente.

Como base inicial para escrever o código, tomo Exp_12.mq4, no qual eu substituo o alerta de média de movimento, JFatl.nq4, por oscilador JCCIX.mq4 e o indicador trend-following MAMA_NK.mq4 consistindo em dois MAs por indicador StepMA_Stoch_NK.mq4 consistindo em alguns osciladores estocásticos. No fim, o algoritmo inicial permanece o mesmo, apenas modifiquei as solicitações para os indicadores custom indicators, as variáveis externas do EA e a inicialização de constantes no bloco da função init() e também compliquei o código de blocos que tinha o objetivo de detectar os sinais de entrada no mercado. Apresento o algoritmo de funcionamento desse EA mais uma vez usando dois timeframes de uma forma geral, como fiz em meu artigo anterior. Entretanto, faço isso com um pouco mais de detalhes dessa vez.

Para posições longas, temos:

E para posições curtas:

Temos que realizar o algoritmo resultante no código do programa para usar os gráficos de três timeframes diferentes da forma mais racional possível como segue:

Para posições longas:

Para posições curtas:

A realização desse algoritmo em um código de programa com base em Exp_15.mq4 pode ser apresentado como segue:

//+==================================================================+
//|                                                       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);
  }
//+------------------------------------------------------------------+

Agora devemos entrar em mais detalhes sobre transformar Exp_14.mq4 em Exp_15.mq4. Temos um novo módulo, "DETECTANDO SINAIS DE RUÍDO PARA ENTRAR NO MERCADO", em nosso código de programa. O ponto dessa operação de módulo pode ser expresso como segue (estou considerando o algoritmo apenas para posições longas):
O sinal NoiseBUY_Sign ocorre se a direção de tendência no menor timeframe coincidir com a direção de sinal de entrada do mercado, BUY_Sig. Ou, caso haja não correspondência dessa tendência, o sinal NoiseBUY_Sign ocorre antes da modificação regular da barra.

Como um MA trend-following, usei um indicador obtido por suavização dupla da sequência de preço por algoritmos de média padrão. Como um parâmetro externo para o EA desse módulo, usei apenas duas variáveis:

extern int    TimeframeN_Up = 15;
extern int    Noise_period_Up = 8;

Fiz a maioria das varáveis externas do custom indicator 2Moving Avereges.mq4 fixas (inicialização de variáveis globais):

int SmoothN_Up = 7, SmoothN_Dn = 7, MaMethodN_Up = 1, MaMethodN_Dn = 1;

A lógica de adição de teste é absolutamente a mesma da que fiz em meu artigo anterior.

Ideia geral de construir Expert Advisors usando três timeframe

No geral, o código do EA está pronto e eu poderia parar nesse estágio. Entretanto, na minha opinião, a menor parte do trabalho realmente foi feita. O primeiro sistema de trading escrito com base nessa ideia dificilmente produziria bons resultados no trading real. Então, deveríamos ser motivados pelo fato de que temos que escrever o código de mais do que um ou dois EAs similares para escolher uma versão mais apropriada. Então agora estamos encarando a tarefa de abstrair os sinais de trading específicos calculando algoritmos e usando apenas o próprio algoritmo de triple screen. O que, em geral, não é um problema. O código resultante sem algoritmos aparecerá como segue:

//+==================================================================+
//|                                                 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);
  }
//+------------------------------------------------------------------+

Se usarmos esse código como template para escrever EAs, deveríamos, antes de mais nada, inicializar variáveis nos blocos correspondentes: DETECTANDO UMA TENDÊNCIA" E "DETECTANDO SINAL DE RUÍDO PARA ENTRAR NO MERCADO":

TrendX_Up = 1;
TrendX_Dn =-1;
Noise8uy_Sign = true;
NoiseSELL_Sign = true;

Depois disso, você pode adicionar seus próprios códigos nos blocos "DETECTANDO SINAIS PARA ENTRAR NO MERCADO" e ajustar o EA para funcionar com esse código. Você pode aprender como fazer isso no código de EA Exp_15_A.mq4, no qual há somente algoritmos para detectar sinais para entrar no mercado para o timeframe intermediário, enquanto não há algoritmos que se destinam a detectar a tendência do maior timeframe ou aqueles que se destinam a detectar a tendência de ruído para o menor timeframe. Você deve prestar atenção às inicializações de variáveis para a menor quantidade de barras no bloco int int(), nesse caso:

//---- 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;

No segundo passo, remova as inicializações dos blocos "DETECTANDO UMA TENDÊNCIA":

TrendX_Up = 1;
TrendX_Dn =-1;

Adicione seu código para detectar a direção de tendência nesses blocos e ajuste o EA mais uma vez. Esse estágio de escrita de código é exibido em Exp_15_B.mq4. Por favor, não se esqueça de inicializar as variáveis MinBarX_Up e MinBarX_Dn no bloco init():

//---- 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;

Como resultado, temos um EA funcionando em dois timeframes. No terceiro passo, absolutamente da mesma forma, como o código de EA nos blocos "DETECTANDO SINAIS DE RUÍDO PARA ENTRAR NO MERCADO", tendo removido previamente as inicializações

Noise8uy_Sign = true;
NoiseSELL_Sign = true;

daqueles blocos e adicionado operações aritméticas para a inicialização de variáveis para a menor quantidade de barras no bloco int int(), nesse caso:

//---- 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;

Assim, o código do EA é feito em três estágios. Entretanto, se você tentar construir esse código dentro de apenas um estágio, você pode cometer alguns erros nele que podem não ser facilmente detectados no futuro!

Conclusão

No presente artigo, apresentei minha versão de uma abordagem geral para escrever Expert Advisors usando três timeframes. Tecnicamente, essa ideia pode ser facilmente realizada no MQL4. Existem outras questões, entretanto: "Quais soluções ajudariam tal ideia a revelar seu certo sentido prático?"

Traduzido do russo pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/ru/articles/1535

Arquivos anexados |
EXPERTS.zip (20.37 KB)
INCLUDE.zip (34.56 KB)
indicators.zip (20.7 KB)
TESTER.zip (6.29 KB)
Análise estatística dos movimentos de mercado e seu prognóstico Análise estatística dos movimentos de mercado e seu prognóstico
O presente artigo contempla as amplas oportunidades da abordagem estatística ao marketing. Infelizmente, traders iniciantes falham deliberadamente em aplicar a ciência realmente poderosa da estatística. Enquanto isso, é a única coisa que eles usam subconscientemente ao analisar o mercado. Além disso, a estatística pode dar respostas a muitas perguntas.
Indicadores de teste de EA não comercial Indicadores de teste de EA não comercial
Todos os indicadores podem ser divididos em dois grupos: indicadores estáticos, a exibição deles, uma vez que aparece, sempre permanece a mesma no histórico e não muda com as novas cotações recebidas e indicadores dinâmicos que exibem seus status somente para o momento atual e são totalmente reelaborados quando um novo preço chega. A eficiência de um indicador estático é diretamente visível no gráfico. Mas como podemos verificar se um indicador dinâmico funciona bem? É para essa questão que o artigo se dedica.
Observações de Layman: ZigZag... Observações de Layman: ZigZag...
Certamente, um pensamento visionário de trade próximo do extremo visitou o aprendizado de cada trader quando ele viu a polilinha "enigmática" pela primeira vez. Na verdade, é muito simples. Aqui está o máximo. E aqui está o mínimo. Um belo quadro no histórico. E o que é na prática? Um raio é desenhado. Deveria parecer como sendo o pico! É hora de vender. E agora abaixamos. Mas, oh não! O preço traiçoeiramente está se movendo para cima. Ah! É uma brincadeira, não um indicador. E você joga fora!
Integrando o terminal do cliente do MetaTrader 4 com o MS SQL SERVER Integrando o terminal do cliente do MetaTrader 4 com o MS SQL SERVER
O artigo dá um exemplo de integração do terminal do cliente do MetaTrader 4 com o MS SQL SERVER usando um dll. Em anexo estão ambos os códigos fontes em C ++ e no MQL4, e um projeto pronto e compilado Visual C++ 6.0 SP5.