Guarda come scaricare robot di trading gratuitamente
Ci trovi su Twitter!
Unisciti alla nostra fan page
Script interessante?
Pubblica il link!
lasciare che altri lo valutino
Ti è piaciuto lo script? Provalo nel Terminale MetaTrader 5
Sistemi Esperti

Esempio di MACD - sistema esperto per MetaTrader 5

Pubblicati da::
MetaQuotes
Visualizzazioni:
933
Valutazioni:
(51)
Pubblicato:
2021.11.01 12:41
Hai bisogno di un robot o indicatore basato su questo codice? Ordinalo su Freelance Vai a Freelance

L'esempio di Expert Advisor MACD è incluso nel pacchetto standard del terminale MetaTrader 5 ed è un esempio di Ea che trada utilizzando l'indicatore MACD.

Il file dell' Expert Advisor MACD Sample.mq5 è situato in terminal_data_folder\MQL5\Experts\Examples\MACD\". Questo Expert Advisor è un esempio di approccio orietato agli oggetti nello sviluppo di un EA.

Andiamo a considerare la struttura dell' Expert Advisor e come lavora.


1 Proprietà dell'EA

1.1. Proprietà dell'EA

//+------------------------------------------------------------------+
//|                                                  MACD Sample.mq5 |
//|                   Copyright 2009-2013, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright   "Copyright 2009-2013, MetaQuotes Software Corp."
#property link        "https://www.mql5.com"
#property version     "5.20"
#property description "It is important to make sure that the expert works with a normal"
#property description "chart and the user did not make any mistakes setting input"
#property description "variables (Lots, TakeProfit, TrailingStop) in our case,"
#property description "we check TakeProfit on a chart of more than 2*trend_period bars"

Le prime 5 righe contengono un commento, le sette linee succesive impostano le proprietà del programma MQL5 (copyright, link, version, description) utilizzando le direttive del preprocessore #property.

Quando esegui gli Expert Advisor sono mostrati nella scheda "Comune":

Esempio di  Expert Advisor MACD

Figura 1 parametri comuni dell'Esempio dell' EA MACD

1.2. File dell' Include

Dopo, la direttiva dell' #include dice al compilatore di includere i file che contengono le classi di trade della Libreria Standard.

  • Trade.mqh (CTrade - una classe per le operazioni di trade);
  • SymbolInfo.mqh (CSymbolInfo - una classe per lavorare con le proprietà di uno strumento di trading);
  • PositionInfo.mqh (CPositionInfo - una classe per lavorare con le proprietà di una posizione aperta);
  • AccountInfo.mqh (CAccountInfo - una classe per lavorare con le proprietà di un account di trading).
//--- include files 
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>
#include <Trade\PositionInfo.mqh>
#include <Trade\AccountInfo.mqh>

Le istanze delle classi appropriate vengono quindi utilizzate come variabili membro della classe CExpert (Sezione 3).

1.3. Inputs

Poi troviamo il tipo,nome,valori predefiniti e un commento. Il loro ruolo è mostrato in fig. 2.

//--- Expert Advisor input parameters
input double InpLots          =0.1; // Lots
input int    InpTakeProfit    =50;  // Take Profit (in pips)
input int    InpTrailingStop  =30;  // Trailing Stop Level (in pips)
input int    InpMACDOpenLevel =3;   // MACD open level (in pips)
input int    InpMACDCloseLevel=2;   // MACD close level (in pips)
input int    InpMATrendPeriod =26;  // MA trend period

Notare che i nomi dei parametri di input hanno il prefisso "Inp". Notare anche che le variabili globali sono prefissate con "Ext". Questo tipo di approccio alla denominazione delle variabili semplifica l'utilizzo di molte variabili diverse.

InpLots - volume di trade, InpTakeProfit e InpTrailingStop determinano il Take Profit e i livelli di Trailing Stop.

Il testo nel commento nella linea dei parametri di input, affianco ai valori predefiniti, sono visualizzati nella scheda "Opzioni" anzichè il nome del parametro di input.

Figure 2. Parametri di input dell'Esempio dell' EA MACD

Figure 2. Parametri di input dell'Esempio dell' EA MACD


1.4. Variabili Globali

Poi è dichiarata la variabile globale ExtTimeOut. Sarà utilizzata per controllare il tempo di esecuzione delle operazioni di trade.

int ExtTimeOut=10; // tempo (in secondi) tra le operazioni di trade

Dopo la dichiarazione della classe CSampleExpert class, nella liea 76 un'altra variabile globale è dichiarata: ExtExpert - istanza della classe CSampleExpert:

//--- the ExtExpert global variable
CSampleExpert ExtExpert;

L'oggetto ExtExpert (classe di esempio CSampleExpert) contiene le basi logiche delle strategie dii trading (Sezione 3).


2. Funzioni di Gestione degli Eventi

Funzioni di Gestione degli Eventi

2.1. La funzione di inizializzazione OnInit()

La funzione OnInit()è chiamata una sola volta durante il primo avvio dell'Expert Advisor. Normalmente nelle gestione dll'evento OnInit() l'EA è pronto ad operare: vengono verificati i parametri di input, indicatori e i parametri sono inizializzati, etc. In caso di errori critici, quando ulteriore lavoro non ha senso, la funzione viene chiusa con il codice di ritorno INIT_FAILED.

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit(void)
  {
//--- initialization and creation of all the required objects
   if(!ExtExpert.Init())
      return(INIT_FAILED);
//--- successful initialization
   return(INIT_SUCCEEDED);
  }

In questo caso, il metodo Init() dell'oggetto ExtExpert è chiamato, il quale ritorna true o false a seconda della preparazione di tutti gli oggetti richiesti per operare (vedere Sezione 3.4). In caso di errore, si esce da OnInit() con il codice di ritorno INIT_FAILED - è il modo corretto per completare l'operazione EA/indicatore in caso di inizializzazione non riuscita.


2.2. Funzione OnTick()

La funzione OnTick() è chiamata ogni volta che si riceve una nuova quotazione per il simbolo sul grafico, o sulla quale l'EA è eseguito.

//+------------------------------------------------------------------+
//| Expert new tick handling function                                |
//+------------------------------------------------------------------+
void OnTick(void)
  {
   static datetime limit_time=0; // stores the last call time + timeout
//--- do not operate if the required time has not elapsed
   if(TimeCurrent()>=limit_time)
     {
      //--- checking data
      if(Bars(Symbol(),Period())>2*InpMATrendPeriod)
        {
         //--- after the call of the Processing() method increase the value of limit_time by ExtTimeOut 
         if(ExtExpert.Processing())
            limit_time=TimeCurrent()+ExtTimeOut;
        }
     }
  }

Nel gestore dell'evento OnTick() è incluso un meccanismo per periodiche chiamate al metodo ExtExpert.Processing(), il quale è utilizzato per l'analisi del mercato e per le operazioni di trading quando le condizioni di trading sono soddisfatte.

L'intervallo di tempo tra le chiamate è impostato con il valore del parametro di input ExtTimeOut .


2.3. La funzione di deinizializzazione OnDeint()

OnDeInit() è chiamata quando un EA è rimosso dal garfico. Se un programma piazza oggetti grafici durante la sua operatività, possono essere rimossi dal grafico.

In questo esempio nessuna funzione di deinizializzazione è utilizzata, non sono eseguite azioni.


3. La classe CSampleExpert

3.1. La classe CSampleExpert

//+------------------------------------------------------------------+
//| The MACD Sample EA class sample                                  |
//+------------------------------------------------------------------+
class CSampleExpert
  {
protected: 
   //--- protected variables - class members are available only inside the class methods 
   double            m_adjusted_point;             // a multiplier for 3/5-digit quotes
   CTrade            m_trade;                      // CTrade class sample
   CSymbolInfo       m_symbol;                     // CSymbolInfo class sample
   CPositionInfo     m_position;                   // CPositionInfo class sample
   CAccountInfo      m_account;                    // CAccountInfo class sample
   //--- indicator handles
   int               m_handle_macd;                // the MACD indicator handle
   int               m_handle_ema;                 // the Moving Average indicator handle
   //--- indicator buffers
   double            m_buff_MACD_main[];           // the buffer of the main line of the MACD indicator
   double            m_buff_MACD_signal[];         // the buffer of the signal line of the MACD indicator
   double            m_buff_EMA[];                 // EMA indicator buffers
   //--- current indicator values
   double            m_macd_current;
   double            m_macd_previous;
   double            m_signal_current;
   double            m_signal_previous;
   double            m_ema_current;
   double            m_ema_previous;
   //--- levels (in standard points)
   double            m_macd_open_level;
   double            m_macd_close_level;
   double            m_traling_stop;
   double            m_take_profit;

public: 
   //--- constructor
                     CSampleExpert(void);
   //--- destructor
                     ~CSampleExpert(void);
   //--- public-methods can be called from outside the class 
   //--- initialization method
   bool              Init(void);
   //--- deinitialization method
   void              Deinit(void);
   //--- method of processing
   bool              Processing(void);
protected: 
   //--- protected-methods can be accessed only inside the class methods 
   bool              InitCheckParameters(const int digits_adjust);
   bool              InitIndicators(void);
   bool              LongClosed(void);
   bool              ShortClosed(void);
   bool              LongModified(void);
   bool              ShortModified(void);
   bool              LongOpened(void);
   bool              ShortOpened(void);
  };

La classe EA contiene la dichiarazione di variabili (membri di classe) e funzioni (metodi di classe).

Per un lavoro più conveniente con le variabili, tutte le variabili dei membri della classe contengono il prefisso "m_" (membro), che indica che una variabile è un membro della classe. Prima della dichiarazione di una variabile o di un metodo, ne viene specificato il tipo (o il valore restituito per le funzioni).

La visibilità delle variabili e dei metodi dei membri della classe è definita utilizzando modificatori di accesso. Nella classe CSampleExpert vengono utilizzati i modificatori protected e public. Tutte le variabili e i metodi definiti nella sezione public, sono pubblici e accessibili dall'esterno. La classe CSampleExpert ha cinque di questi metodi:

  1. CSampleExpert(void) - un costruttore  (chiamato automaticamente durante la creazione di un'istanza di classe);
  2. ~CSampleExpert(void) - un distruttore (chiamato automaticamente quando si elimina un'istanza di classe);
  3. bool Init(void) - metodo di inizializzazione, in cui vengono preparati tutti i dati necessari per il funzionamento;
  4. void Deinit(void) - metodo di deinizializzazione;
  5. bool Processing(void) - metodo di elaborazione.

Le variabili membro della classe CSampleExpert dichiarate con il modificatore di accesso protected saranno disponibili solo all'interno dei metodi della classe CSampleExpert (e delle classi figlio).

  1. double           m_adjusted_point - variabile moltiplicatrice per una corretta operazione con virgola a 3/5 cifre;
  2. CTrade          m_trade - СTrade classe d'esempio;
  3. CSymbolInfo  m_symbol - CSymbolInfo classe d'esempio;
  4. CPositionInfo  m_position - СPositionInfo classe d'esempio;
  5. CAccountInfo  m_account - CAccountInfo classe d'esempio;
  6. int                 m_handle_macd - una variabile per memorizzare il valore dell'handle dell' indicatore MACD.
  7. int                 m_handle_ema - una variabile per memorizzare il valore dell'handle dell' indicatore EMA.
  8. double           m_buff_MACD_main[] - un array dinamico di tipo double, che serve per richiedere i valori della linea main dell' MACD;
  9. double           m_buff_MACD_signal[] - un array dinamico di tipo double, che serve per richiedere i valori della linea signal dell' MACD;
  10. double           m_buff_EMA[] - un array dinamico di tipo double, che serve per richiedere i valori dell'indicatore EMA;
  11. double           m_macd_current - è utilizzata per memorizzare il valore corrente della linea main dell'MACD;
  12. double           m_macd_previous - è utilizzata per memorizzare il valore precedente della linea main dell'MACD;
  13. double           m_signal_current - è utilizzata per memorizzare il valore corrente della linea signal dell'MACD;
  14. double           m_signal_previous - è utilizzata per memorizzare il valore precedente della linea signal dell'MACD;
  15. double           m_ema_current - è utilizzata per memorizzare il valore corrente dell'indicatore EMA;
  16. double           m_ema_previous - è utilizzata per memorizzare il valore precedente dell'indicatore EMA
  17. double           m_macd_open_level,
  18. double           m_macd_close_level,
  19. double           m_traling_stop,
  20. double           m_take_profit - sono utilizzati per memorizzare i valori dei livelli di prezzo (impostati nei parametri di input) tenendo conto del moltiplicatore m_adjusted_point.

Metodi della classe CSampleExpert dichiarati con il modificatore di accesso protected:

  1. bool  InitCheckParameters(const int digits_adjust) - verifica della correttezza dei parametri di input e inizializzazione dei parametri dell'EA;
  2. bool  InitIndicators(void) - inizializzazione (creazione ) degli indicatori MACD e Moving Average;
  3. bool  LongClosed(void) - restituisce true (e chiude una posizione lunga aperta) se sono soddisfatte le condizioni per chiudere una posizione lunga;
  4. bool  ShortClosed(void) - restituisce true (e chiude una posizione corta aperta) se sono soddisfatte le condizioni per chiudere una posizione corta;
  5. bool  LongModified(void) - restituisce true (e modifica il prezzo di Stop Loss) se sono soddisfatte le condizioni per modificare il livello di Stop Loss di una posizione lunga aperta;
  6. bool  ShortModified(void) - restituisce true (e modifica il prezzo di Stop Loss) se sono soddisfatte le condizioni per modificare il livello di Stop Loss di una posizione corta aperta;
  7. bool  LongOpened(void) - restituisce true (e apre una posizione long) se sono soddisfatte le condizioni per l'apertura di una posizione long;
  8. bool  ShortOpened(void) - restituisce true (e apre una posizione corta) se le condizioni per l'apertura di una posizione corta sono soddisfatte.


3.2. Costruttore della Classe CSampleExpert

//+------------------------------------------------------------------+
//| CSampleExpert Class Constructor                                  |
//+------------------------------------------------------------------+
CSampleExpert::CSampleExpert(void) : m_adjusted_point(0),
                                     m_handle_macd(INVALID_HANDLE),
                                     m_handle_ema(INVALID_HANDLE),
                                     m_macd_current(0),
                                     m_macd_previous(0),
                                     m_signal_current(0),
                                     m_signal_previous(0),
                                     m_ema_current(0),
                                     m_ema_previous(0),
                                     m_macd_open_level(0),
                                     m_macd_close_level(0),
                                     m_traling_stop(0),
                                     m_take_profit(0)
  {
   ArraySetAsSeries(m_buff_MACD_main,true);
   ArraySetAsSeries(m_buff_MACD_signal,true);
   ArraySetAsSeries(m_buff_EMA,true);
  }

Il costruttore della Classe Costruttore di classe viene chiamato automaticamente quando viene creato un oggetto di esempio della classe. Quando viene chiamato, vengono impostati i valori predefiniti (tra parentesi) per le variabili membro della classe e le serie temporali direzione di indicizzazione per m_buff_MACD_main[], m_buff_MACD_signal[], m_buff_EMA[].


3.3. Distruttore della Classe CSampleExpert

//+------------------------------------------------------------------+
//| CSampleExpert class destructor                                   |
//+------------------------------------------------------------------+
CSampleExpert::~CSampleExpert(void)
  {
  }

Il distruttore della classe CSampleExpert non contiene alcun codice.


3.4. Il metodo Init della classe CSampleExpert

//+------------------------------------------------------------------+
//| Initialization and verification of input parameters              |
//+------------------------------------------------------------------+
bool CSampleExpert::Init(void)
  {
//--- setting common properties
   m_symbol.Name(Symbol());              // symbol
   m_trade.SetExpertMagicNumber(12345);  // magic
//--- taking into account 3/5-digit quotes
   int digits_adjust=1;
   if(m_symbol.Digits()==3 || m_symbol.Digits()==5)
      digits_adjust=10;
   m_adjusted_point=m_symbol.Point()*digits_adjust;
//--- setting the values of the levels taking into account the m_adjusted_point modifier
   m_macd_open_level =InpMACDOpenLevel*m_adjusted_point;
   m_macd_close_level=InpMACDCloseLevel*m_adjusted_point;
   m_traling_stop    =InpTrailingStop*m_adjusted_point;
   m_take_profit     =InpTakeProfit*m_adjusted_point;
//--- setting the slippage of 3 points
   m_trade.SetDeviationInPoints(3*digits_adjust);
//---
   if(!InitCheckParameters(digits_adjust))
      return(false);
   if(!InitIndicators())
      return(false);
//--- successful completion
   return(true);
  }

Nel metodo Init(), le variabili della classe membro sono inizializzate e i parametri di input verificati.

una chiamata del metodo Name() per l'oggetto m_symbol (istanza della classe CSymbolInfo) imposta il nome del simbolo, sulla quale l'Expert Advisor è avviato,in seguito è chiamato il metodo SetExpertMagicNumber(); Imposta il valore del magic number dell'EA per l'oggetto m_trade (verrà utilizzato per le operazioni di trading). Successivamente viene utilizzato il metodo Digits() per richiedere il numero di cifre del simbolo dopo la virgola e, se necessario, vengono corretti i valori dei livelli.

In seguito viene chiamato il metodo SetDeviationInPoints() dell'oggetto m_trade, in cui viene impostato il valore dello slippage consentito nelle operazioni di trade.


3.5. Il metodo della InitCheckParameters della classe CSampleExpert

//+------------------------------------------------------------------+
//| Checking for input parameters                                    |
//+------------------------------------------------------------------+
bool CSampleExpert::InitCheckParameters(const int digits_adjust)
  {
//--- checking correctness of the Take Profit level
   if(InpTakeProfit*digits_adjust<m_symbol.StopsLevel())
     {
      printf("Take Profit must be greater than %d",m_symbol.StopsLevel());
      return(false);
     }
//--- checking correctness of the Trailing Stop level
   if(InpTrailingStop*digits_adjust<m_symbol.StopsLevel())
     {
      printf("Trailing Stop must be greater than %d",m_symbol.StopsLevel());
      return(false);
     }
//--- checking correctness of the trade volume
   if(InpLots<m_symbol.LotsMin() || InpLots>m_symbol.LotsMax())
     {
      printf("Lots amount must be in the range from %f to %f",m_symbol.LotsMin(),m_symbol.LotsMax());
      return(false);
     }
   if(MathAbs(InpLots/m_symbol.LotsStep()-MathRound(InpLots/m_symbol.LotsStep()))>1.0E-10)
     {
      printf("Lots amount is not corresponding with lot step %f",m_symbol.LotsStep());
      return(false);
     }
//--- show warning if Take Profit<=Trailing Stop
   if(InpTakeProfit<=InpTrailingStop)
      printf("Warning: Trailing Stop must be less than Take Profit");
//--- successful completion
   return(true);
  }

La correttezza dei parametri di input dell'EA viene verificata nel metodo InitCheckParameters(). Se uno dei parametri non è valido, viene visualizzato un messaggio appropriato e la funzione restituisce false.


3.6. Il metodo InitIndicators() della classe CSampleExpert

//+------------------------------------------------------------------+
//| Indicators initialization method                                 |
//+------------------------------------------------------------------+
bool CSampleExpert::InitIndicators(void)
  {
//--- creating the MACD indicator
   if(m_handle_macd==INVALID_HANDLE)
      if((m_handle_macd=iMACD(NULL,0,12,26,9,PRICE_CLOSE))==INVALID_HANDLE)
        {
         printf("Error creating MACD indicator");
         return(false);
        }
//--- creating the EMA indicator
   if(m_handle_ema==INVALID_HANDLE)
      if((m_handle_ema=iMA(NULL,0,InpMATrendPeriod,0,MODE_EMA,PRICE_CLOSE))==INVALID_HANDLE)
        {
         printf("Error creating EMA indicator");
         return(false);
        }
//--- successful completion
   return(true);
  }

Nel metodo InitIndicators() viene verificata la correttezza dei valori iniziali delle variabili m_handle_macd e m_handle_ema (devono essere uguali a INVALID_HANDLE, poiché sono stati inizializzati nel costruttore), e gli indicatori tecnici MACD e Moving Average vengono creati (utilizzando le funzioni iMACD e iMA). In caso di successo, la funzione restituisce true e gli handle dell'indicatore vengono salvati nei membri della classe m_handle_macd e m_handle_ema.

Gli handle degli indicatori creati verranno quindi utilizzati per verificare la quantità di dati calcolati (BarsCalculated) e ottenere i valori numerici (CopyBuffer) degli indicatori nel metodo Processing ().


3.7. Il metodo LongClosed() della classe CSampleExpert

//+------------------------------------------------------------------+
//| Checking conditions for closing a long position                  |
//+------------------------------------------------------------------+
bool CSampleExpert::LongClosed(void)
  {
   bool res=false;
//--- Should the position be closed?
   if(m_macd_current>0)
      if(m_macd_current<m_signal_current && m_macd_previous>m_signal_previous)
         if(m_macd_current>m_macd_close_level)
           {
            //--- closing the position
            if(m_trade.PositionClose(Symbol()))
               printf("Long position by %s to be closed",Symbol());
            else
               printf("Error closing position by %s : '%s'",Symbol(),m_trade.ResultComment());
            res=true;
           }
//--- returning the result
   return(res);
  }

Il metodo LongClosed() restituisce true (e chiude la posizione long aperta) se vengono soddisfatte le condizioni per la chiusura della posizione:

  1. m_macd_current>0 - il valore corrente della linea main dell'indicatore MACD è positivo (l'istogramma dell'MACD è sopra la linea dello zero);
  2. m_macd_current<m_signal_current && m_macd_previous>m_signal_previous - la linea main dell'indicatore MACD ha attraversato verso il basso la linea del signal.
  3. m_macd_current>m_macd_close_level - il valore corrente della linea main dell'indicatore MACD è maggiore di m_macd_close_level.


3.8. Il metodo shortClosed() della classe CSampleExpert

//+------------------------------------------------------------------+
//| Checking conditions for closing a short position                 |
//+------------------------------------------------------------------+
bool CSampleExpert::ShortClosed(void)
  {
   bool res=false;
//--- Should the position be closed?
   if(m_macd_current<0)
      if(m_macd_current>m_signal_current && m_macd_previous<m_signal_previous)
         if(MathAbs(m_macd_current)>m_macd_close_level)
           {
            //--- closing the position
            if(m_trade.PositionClose(Symbol()))
               printf("Short position by %s to be closed",Symbol());
            else
               printf("Error closing position by %s : '%s'",Symbol(),m_trade.ResultComment());
            res=true;
           }
//--- returning the result
   return(res);
  }

Il metodo ShortClosed() restituisce true (e chiude la posizione short aperta) se vengono soddisfatte le condizioni per la chiusura della posizione short:

  1. m_macd_current<0 - il valore corrente della linea main dell'indicatore MACD è negativo (l'istogramma dell'MACD è sotto la linea dello zero);
  2. m_macd_current>m_signal_current && m_macd_previous<m_signal_previous - la linea main dell'indicatore MACD ha attraversato verso l'alto la linea del signal.
  3. MathAbs(m_macd_current)>m_macd_close_level - il valore corrente della linea main dell'indicatore MACD è maggiore di m_macd_close_level.


3.9. Il metodo LongModified() della classe CSampleExpert

//+------------------------------------------------------------------+
//| Checking conditions for long position modification               |
//+------------------------------------------------------------------+
bool CSampleExpert::LongModified(void)
  {
   bool res=false;
//--- checking if Trailing Stop is required
   if(InpTrailingStop>0)
     {
      if(m_symbol.Bid()-m_position.PriceOpen()>m_adjusted_point*InpTrailingStop)
        {
         double sl=NormalizeDouble(m_symbol.Bid()-m_traling_stop,m_symbol.Digits());
         double tp=m_position.TakeProfit();
         if(m_position.StopLoss()<sl || m_position.StopLoss()==0.0)
           {
            //--- modifying Stop Loss and Take Profit of the position
            if(m_trade.PositionModify(Symbol(),sl,tp))
               printf("Long position by %s to be modified",Symbol());
            else
              {
               printf("Error modifying position by %s : '%s'",Symbol(),m_trade.ResultComment());
               printf("Modify parameters : SL=%f,TP=%f",sl,tp);
              }
            res=true;
           }
        }
     }
//--- returning the result
   return(res);
  }

Il metodo LongModified() ritorna true (e modifica il valore dello Stop Loss) se le condizioni per la modifica della posizione long sono soddisfatte: se il valore dell'input InpTrailingStop>0, se le condizioni per la modifica della posizione long sono soddisfatte: Se il valore dell'input InpTrailingStop>0, viene verificato il fatto che il prezzo passato InpTrailingStop punti dal prezzo aperto nella direzione della posizione. Successivamente si calcola il valore del nuovo livello di Stop Loss e si modifica il parametro Stop Loss della posizione aperta.


3.10. Il metodo ShortModified() della classe CSampleExpert

//+------------------------------------------------------------------+
//| Checking conditions for long position modification               |
//+------------------------------------------------------------------+
bool CSampleExpert::ShortModified(void)
  {
   bool   res=false;
//--- checking if Trailing Stop is required
   if(InpTrailingStop>0)
     {
      if((m_position.PriceOpen()-m_symbol.Ask())>(m_adjusted_point*InpTrailingStop))
        {
         double sl=NormalizeDouble(m_symbol.Ask()+m_traling_stop,m_symbol.Digits());
         double tp=m_position.TakeProfit();
         if(m_position.StopLoss()>sl || m_position.StopLoss()==0.0)
           {
            //--- modifying Stop Loss and Take Profit of the position
            if(m_trade.PositionModify(Symbol(),sl,tp))
               printf("Short position by %s to be modified",Symbol());
            else
              {
               printf("Error modifying position by %s : '%s'",Symbol(),m_trade.ResultComment());
               printf("Modify parameters : SL=%f,TP=%f",sl,tp);
              }
            res=true;
           }
        }
     }
//--- returning the result
   return(res);
  }

Il metodo ShortModified() ritorna true (e modifica il valore dello Stop Loss) se le condizioni per la modifica della posizione short sono soddisfatte: se il valore dell'input InpTrailingStop>0, viene verificato il fatto che il prezzo passato InpTrailingStop punti dal prezzo aperto nella direzione della posizione. Successivamente si calcola il valore del nuovo livello di Stop Loss e si modifica il parametro Stop Loss della posizione aperta.


3.11. Il metodo LongOpened() della classe CSampleExpert

//+------------------------------------------------------------------+
//| Check for long position opening                                  |
//+------------------------------------------------------------------+
bool CSampleExpert::LongOpened(void)
  {
   bool res=false;
//--- checking conditions for opening a long position
   if(m_macd_current<0)
      if(m_macd_current>m_signal_current && m_macd_previous<m_signal_previous)
         if(MathAbs(m_macd_current)>(m_macd_open_level) && m_ema_current>m_ema_previous)
           {
            double price=m_symbol.Ask();
            double tp   =m_symbol.Bid()+m_take_profit;
            //--- checking free margin
            if(m_account.FreeMarginCheck(Symbol(),ORDER_TYPE_BUY,InpLots,price)<0.0)
               printf("We have no money. Free Margin = %f",m_account.FreeMargin());
            else
              {
               //--- opening a long position
               if(m_trade.PositionOpen(Symbol(),ORDER_TYPE_BUY,InpLots,price,0.0,tp))
                  printf("Position by %s to be opened",Symbol());
               else
                 {
                  printf("Error opening BUY position by %s : '%s'",Symbol(),m_trade.ResultComment());
                  printf("Open parameters : price=%f,TP=%f",price,tp);
                 }
              }
            res=true;
           }
//--- returning the result
   return(res);
  }

Il metodo LongOpened() ritorna true (e apre una posizione long) se le condizioni per aprire una posizione buy sono soddisfatte:

  1. m_macd_current<0 - il valore corrente della linea main dell'indicatore MACD è negativo (l'istogramma dell'MACD è sotto la linea dello zero);
  2. m_macd_current>m_signal_current && m_macd_previous<m_signal_previous - la linea main dell'indicatore MACD ha attraversato verso l'alto la linea del signal.
  3. MathAbs(m_macd_current)>m_macd_open_level - il valore corrente della linea main dell'indicatore MACD è maggiore di m_macd_open_level;
  4. m_ema_current>m_ema_previous - l'ema cresce.

Quando tutte le condizioni sono soddisfatte, viene controllato il margine libero (il metodo FreeMarginCheck() della classe della libreria standard CAccountInfo) e viene aperta una posizione long utilizzando la PositionOpen () metodo della classe CTrade.


3.12. Il metodo ShortOpened() della classe CSampleExpert

//+------------------------------------------------------------------+
//| Check for short position opening                                 |
//+------------------------------------------------------------------+
bool CSampleExpert::ShortOpened(void)
  {
   bool res=false;
//--- checking conditions for opening a short position
   if(m_macd_current>0)
      if(m_macd_current<m_signal_current && m_macd_previous>m_signal_previous)
         if(m_macd_current>(m_macd_open_level) && m_ema_current<m_ema_previous)
           {
            double price=m_symbol.Bid();
            double tp   =m_symbol.Ask()-m_take_profit;
            //--- checking free margin
            if(m_account.FreeMarginCheck(Symbol(),ORDER_TYPE_SELL,InpLots,price)<0.0)
               printf("We have no money. Free Margin = %f",m_account.FreeMargin());
            else
              {
               //--- opening a short position
               if(m_trade.PositionOpen(Symbol(),ORDER_TYPE_SELL,InpLots,price,0.0,tp))
                  printf("Position by %s to be opened",Symbol());
               else
                 {
                  printf("Error opening SELL position by %s : '%s'",Symbol(),m_trade.ResultComment());
                  printf("Open parameters : price=%f,TP=%f",price,tp);
                 }
              }
            res=true;
           }
//--- returning the result
   return(res);
  }

Il metodo ShortOpened() ritorna true (e apre una posizione short) se le condizioni per aprire una posizione sell sono soddisfatte:

  1. m_macd_current>0 - il valore corrente della linea main dell'indicatore MACD è positivo (l'istogramma dell'MACD è sopra la linea dello zero);
  2. m_macd_current<m_signal_current && m_macd_previous>m_signal_previous - la linea main dell'indicatore MACD ha attraversato verso il basso la linea del signal.
  3. m_macd_current>m_macd_open_level - il valore corrente della linea main dell'indicatore MACD è maggiore di m_macd_open_level;
  4. m_ema_current<m_ema_previous - l'ema scende.

Quando tutte le condizioni sono soddisfatte, viene controllato il margine libero (il metodo FreeMarginCheck() della classe della libreria standard CAccountInfo) e viene aperta una posizione short utilizzando la PositionOpen () metodo della classe CTrade.


3.13 Il metodo Processing() della classe CSampleExpert

//+------------------------------------------------------------------+
//| main function returns true if any position processed             |
//+------------------------------------------------------------------+
bool CSampleExpert::Processing(void)
  {
//--- updating quotes
   if(!m_symbol.RefreshRates())
      return(false);
//--- updating indicator values
   if(BarsCalculated(m_handle_macd)<2 || BarsCalculated(m_handle_ema)<2)
      return(false);
   if(CopyBuffer(m_handle_macd,0,0,2,m_buff_MACD_main)  !=2 ||
      CopyBuffer(m_handle_macd,1,0,2,m_buff_MACD_signal)!=2 ||
      CopyBuffer(m_handle_ema,0,0,2,m_buff_EMA)         !=2)
      return(false);
//--- to simplify work with indicators and for faster access
//--- the current values of the indicators are saved in internal variables (class members)
   m_macd_current   =m_buff_MACD_main[0];
   m_macd_previous  =m_buff_MACD_main[1];
   m_signal_current =m_buff_MACD_signal[0];
   m_signal_previous=m_buff_MACD_signal[1];
   m_ema_current    =m_buff_EMA[0];
   m_ema_previous   =m_buff_EMA[1];
//--- correct market entry is important, but a correct exit is even more important
//--- first check if there is an open position
   if(m_position.Select(Symbol()))
     {
      if(m_position.PositionType()==POSITION_TYPE_BUY)
        {
         //--- if necessary, we try to close or modify a long position
         if(LongClosed())
            return(true);
         if(LongModified())
            return(true);
        }
      else
        {
         //--- if necessary, we try to close or modify a short position
         if(ShortClosed())
            return(true);
         if(ShortModified())
            return(true);
        }
     }
//--- no open positions
   else
     {
      //--- check conditions and open a long position if necessary
      if(LongOpened())
         return(true);
      //--- check conditions and open a short position if necessary
      if(ShortOpened())
         return(true);
     }
//--- exit without position processing
    return(false);
  }

Il metodo Processing() della classe CSampleExpert è il metodo dell'Expert Advisor. Il metodo Processing() viene chiamato nel gestore dell'evento OnTick() e viene monitorato l'intervallo di tempo tra le chiamate successive di questo metodo (non meno di ExtTimeOut secondi) (sezione 2.2).

Chiamando il metodo RefreshRates() della classe CSymbolInfo le quotazioni vengono aggiornate. La funzione BarsCalculated() viene utilizzata per richiedere il numero di barre, per le quali vengono calcolati gli indicatori MACD e Moving Average (sezione 3.6.); se il numero di barre è inferiore a 2, esce dalla funzione e restituisci false.

Successivamente, la chiamata alla funzione CopyBuffer richiede gli ultimi due valori degli indicatori tecnici (le linee MACD main e signal e i valori della Moving Average ​); e se la quantità di dati copiati è inferiore a due, esce dalla funzione. Successivamente i valori degli indicatori dagli array m_buff_MACD_main[], m_buff_MACD_signal[] e m_buff_EMA[] vengono copiati nelle variabili m_macd_current, m_macd_previous, m_signal_current, m_signal_previous, m_ema_current e m_ema_previous.

Il passo successivo è lavorare con una posizione tramite la classe CPositionInfo della Libreria Standard. Se la chiamata al metodo Select() ha restituito true, significa che attualmente esiste una posizione aperta, il suo tipo viene determinato utilizzando il metodo PositionType(). Ulteriori lavori vengono eseguiti in base al tipo di posizione aperta.


4. Backtesting

I migliori valori dei parametri si possono trovare utilizzando lo Strategy Tester del terminale MetaTrader 5.

La Figura 3 mostra i risultati dei test dell' Expert Advisor per il 2013 con le impostazioni predefinite.

Figure 3. Risultato del Backtest dell' Esempio di  Expert Advisor MACD

Figure 3. Risultato del Backtest dell' Esempio di Expert Advisor MACD

Conclusioni

Il MACD Sample Expert Advisor, incluso nel pacchetto standard rilasciato col terminale MetaTrader 5, è un esempio di approccio orientato agli oggetti nello sviluppo di EA.


Tradotto dal russo da MetaQuotes Ltd.
Codice originale https://www.mql5.com/ru/code/2154

Media Mobile Media Mobile

L'Expert Advisor Moving Average (Media Mobile) trada quando il prezzo attraversa la MA

ALGLIB - Libreria di Analisi Numerica ALGLIB - Libreria di Analisi Numerica

ALGLIB libreria di funzioni matematiche (v. 3.19) portata a MQL5.

Bollinger Bands ® Bollinger Bands ®

L'indicatore Bollinger Bands ® (BB) è simile a Envelopes. L'unica differenza è che le bande Envelopes sono tracciate ad una distanza fissa (%) dalla media mobile, mentre le Bande di Bollinger sono tracciate ad un certo numero di deviazioni standard da essa.

Accelerator Oscillator (AC) Accelerator Oscillator (AC)

The Acceleration/Deceleration Indicator (AC) measures acceleration and deceleration of the current driving force.