English Русский 中文 Español Deutsch 日本語 Português 한국어 Français Türkçe
Programmazione delle modalità di EA utilizzando l'approccio orientato agli oggetti

Programmazione delle modalità di EA utilizzando l'approccio orientato agli oggetti

MetaTrader 5Esempi | 12 gennaio 2022, 11:43
229 0
Denis Kirichenko
Denis Kirichenko

Introduzione

In questo articolo parleremo delle modalità di programmazione, in cui può funzionare un MQL5 EA. L'obiettivo di questo articolo è descrivere l'idea che "ogni modalità è implementata a modo suo". L'autore ritiene che questo approccio consenta il completamento di compiti in diverse fasi di sviluppo di un EA in modo più efficiente.

In primo luogo, consideriamo in quali fasi consiste lo sviluppo di un EA. Quindi vengono esplorate le modalità in cui un EA in MetaTrader 5 può funzionare e le sue applicazioni di supporto. Lo sviluppo della gerarchia delle classi per l'implementazione dell'idea di cui sopra termina questo articolo.


1. Fasi di sviluppo

Lo sviluppo di un robot di trading (EA) è un processo multi-aspetto. I blocchi chiave qui sono l'algoritmo dell'idea e il suo test. In particolare, vengono testati sia la logica di trading di EA che l'algoritmo del codice.

Schematicamente, le fasi di questo processo possono essere rappresentate come segue (Fig.1).

Fig. 1. Fasi di sviluppo e implementazione di un EA

Fig.1. Fasi di sviluppo e implementazione di un EA

La quinta fase "Trading algoritmico" espone il lavoro degli sviluppatori, programmatori, analisti e altri specialisti coinvolti. Accade spesso che tutti questi ruoli siano svolti da una sola persona. Supponiamo che sia un trader-programmatore.

Questo schema può essere aggiornato ed esteso. A mio parere, illustra i punti più importanti nello sviluppo di un EA. Il modello ciclico di questo schema consente di migliorare e modificare il codice dell'EA per tutta la sua durata di vita.

Va notato che ogni fase richiede determinati strumenti, conoscenze e abilità.

Secondo me, lo sviluppatore si imbatte nella seguente semplice matrice di varianti (Fig.2).

Fig.2. Matrice variante

Fig.2. Matrice variante

Chiaramente, solo il robot che implementa una strategia di trading vincente con un codice di alta qualità arriverà alla quinta fase "Trading algoritmico".


2. Le modalità Expert Advisor in MQL5

L'ambiente MQL5 consente di lavorare con un EA in diverse modalità. Ce ne sono 7. Considereremo ciascuna di esse più in basso.

Dal punto di vista del tipo di file di programma, si possono distinguere 2 gruppi:

  1. Modalità che richiedono il file del codice sorgente e il file eseguibile;
  2. Modalità che richiedono solo il file eseguibile.

Le modalità di debug e di profilazione appartengono al primo gruppo.

Un altro criterio di classificazione della modalità è il lavoro di un EA in un flusso di quotazioni reali o storiche. Tutte le modalità di test sono collegate a quotazioni storiche.

6 modalità sono definite dalla programmazione. Una conclusione se un EA sta funzionando in modalità standard (rilascio) o meno può essere fatta in base ai risultati. Un programma pronto all'uso (file con estensione *.ex5), che è stato codificato per funzionare sui mercati finanziari, dovrebbe funzionare proprio in questa modalità. Allo stesso tempo, un programma pronto all'uso consente di utilizzare anche altre modalità nello Strategy Tester.

Creiamo un'enumerazione delle modalità operative del programma MQL denominata ENUM_MQL_MODE:

//+------------------------------------------------------------------+
//| MQL Mode                                                         |
//+------------------------------------------------------------------+
enum ENUM_MQL_MODE
  {
   MQL_MODE_RELEASE=0,       // Release
   MQL_MODE_DEBUG=1,         // Debugging
   MQL_MODE_PROFILER=2,      // Profiling  
   MQL_MODE_TESTER=3,        // Testing
   MQL_MODE_OPTIMIZATION=4,  // Optimization
   MQL_MODE_VISUAL=5,        // Visual testing 
   MQL_MODE_FRAME=6,         // Gathering frames
  };

In seguito, questo sarà necessario per riconoscere il tipo di modalità in cui sta lavorando un EA.


2.1. Funzione di identificazione e controllo della modalità

Scrivi una semplice funzione che itererà su tutte le modalità e stamperà le informazioni nel journal.

//+------------------------------------------------------------------+
//| Checking all MQL modes                                           |
//+------------------------------------------------------------------+
void CheckMqlModes(void)
  {
//--- if it is debug mode
   if(MQLInfoInteger(MQL_DEBUG))
      Print("Debug mode: yes");
   else
      Print("Debug mode: no");
//--- if it is code profiling mode
   if(MQLInfoInteger(MQL_PROFILER))
      Print("Profile mode: yes");
   else
      Print("Profile mode: no");
//--- if it is test mode
   if(MQLInfoInteger(MQL_TESTER))
      Print("Tester mode: yes");
   else
      Print("Tester mode: no");
//--- if it is optimization mode
   if(MQLInfoInteger(MQL_OPTIMIZATION))
      Print("Optimization mode: yes");
   else
      Print("Optimization mode: no");
//--- if it is visual test mode
   if(MQLInfoInteger(MQL_VISUAL_MODE))
      Print("Visual mode: yes");
   else
      Print("Visual mode: no");
//--- if it is frame gathering optimization result mode
   if(MQLInfoInteger(MQL_FRAME_MODE))
      Print("Frame mode: yes");
   else
      Print("Frame mode: no");
  }

Verrà verificato il lavoro di questa funzione in ogni modalità. Può essere chiamato nel gestore di eventi OnInit().

Ai fini del test, creiamo un modello dell'EA chiamato Test1_Modes_EA.mq5.

Un'opzione per specificare la modalità in cui l'EA funzionerà è abilitata nei parametri di input. È importante assicurarsi che venga nominata la modalità corretta, altrimenti le informazioni saranno imprecise. Questo è quello che è successo.

Di seguito è la modalità di rilascio.

CL      0       17:20:38.932    Test1_Modes_EA (EURUSD.e,H1)     Current mode: MQL_MODE_RELEASE
QD      0       17:20:38.932    Test1_Modes_EA (EURUSD.e,H1)     Debug mode: no
KM      0       17:20:38.932    Test1_Modes_EA (EURUSD.e,H1)     Profile mode: no
EK      0       17:20:38.932    Test1_Modes_EA (EURUSD.e,H1)     Tester mode: no
CS      0       17:20:38.932    Test1_Modes_EA (EURUSD.e,H1)     Optimization mode: no
RJ      0       17:20:38.932    Test1_Modes_EA (EURUSD.e,H1)     Visual mode: no
GL      0       17:20:38.932    Test1_Modes_EA (EURUSD.e,H1)     Frame mode: no

Per la modalità di rilascio, i flag di tutte le altre modalità sono stati azzerati. Quindi, la funzione ha identificato che non era né una modalità di debug (modalità debug: no), né una modalità di profilazione (modalità profilo: no) ecc. Utilizzando il metodo della negazione, siamo giunti alla conclusione che stiamo lavorando in modalità di rilascio.

Ora vedremo come è stata identificata la modalità di debug.

HG      0       17:27:47.709    Test1_Modes_EA (EURUSD.e,H1)     Current mode: MQL_MODE_DEBUG
LD      0       17:27:47.710    Test1_Modes_EA (EURUSD.e,H1)     Debug mode: yes
RS      0       17:27:47.710    Test1_Modes_EA (EURUSD.e,H1)     Profile mode: no
HE      0       17:27:47.710    Test1_Modes_EA (EURUSD.e,H1)     Tester mode: no
NJ      0       17:27:47.710    Test1_Modes_EA (EURUSD.e,H1)     Optimization mode: no
KD      0       17:27:47.710    Test1_Modes_EA (EURUSD.e,H1)     Visual mode: no
RR      0       17:27:47.710    Test1_Modes_EA (EURUSD.e,H1)     Frame mode: no

La modalità di debug è stata riconosciuta correttamente.

Qualsiasi manuale sulla programmazione contiene informazioni che il debug facilita la ricerca e la localizzazione degli errori nel codice. Evidenzia anche le peculiarità del programma. Maggiori dettagli sul debug nell'ambiente MQL5 possono essere trovati nell'articolo "Debug dei programmi MQL5".

Questa modalità è più comunemente utilizzata nelle fasi di formalizzazione e costruzione dell'algoritmo di un'idea di trading.

Nella programmazione, il debug è abilitato utilizzando le macro IS_DEBUG_MODE o la funzione MQLInfoInteger() con l'identificatore MQL_DEBUG.

Passiamo alla modalità di profilazione.

GS      0       17:30:53.879    Test1_Modes_EA (EURUSD.e,H1)     Current mode: MQL_MODE_PROFILER
OR      0       17:30:53.879    Test1_Modes_EA (EURUSD.e,H1)     Debug mode: no
GE      0       17:30:53.879    Test1_Modes_EA (EURUSD.e,H1)     Profile mode: yes
QM      0       17:30:53.879    Test1_Modes_EA (EURUSD.e,H1)     Tester mode: no
CE      0       17:30:53.879    Test1_Modes_EA (EURUSD.e,H1)     Optimization mode: no
FM      0       17:30:53.879    Test1_Modes_EA (EURUSD.e,H1)     Visual mode: no
GJ      0       17:30:53.879    Test1_Modes_EA (EURUSD.e,H1)     Frame mode: no

La funzione ha correttamente stimato che Profiler fosse coinvolto.

In questa modalità è possibile verificare la velocità di funzionamento del programma. Il Profiler passa le informazioni sul tempo impiegato ai blocchi di programma. Questo strumento dovrebbe evidenziare i colli di bottiglia di un algoritmo. Non è sempre possibile sbarazzarsene, ma comunque queste informazioni possono essere utili.

La profilazione può essere abilitata tramite le macro IS_PROFILE_MODE o la funzione MQLInfoInteger() con l'identificatore MQL_PROFILER.

Ora diamo un'occhiata alla modalità test. Queste informazioni appariranno nella scheda "Giornale" di Strategy Tester.

EG      0       17:35:25.397    Core 1  2014.11.03 00:00:00   Current mode: MQL_MODE_TESTER
OS      0       17:35:25.397    Core 1  2014.11.03 00:00:00   Debug mode: no
GJ      0       17:35:25.397    Core 1  2014.11.03 00:00:00   Profile mode: no
ER      0       17:35:25.397    Core 1  2014.11.03 00:00:00   Tester mode: yes
ED      0       17:35:25.397    Core 1  2014.11.03 00:00:00   Optimization mode: no
NL      0       17:35:25.397    Core 1  2014.11.03 00:00:00   Visual mode: no
EJ      0       17:35:25.397    Core 1  2014.11.03 00:00:00   Frame mode: no

La modalità di prova è stata identificata correttamente.

Questa è la modalità predefinita di EA quando viene aperto lo Strategy Tester.

Non ci sono macro per questa modalità e quindi in MQL5 possiamo determinarla solo utilizzando la funzione MQLInfoInteger() con l'identificatore MQL_TESTER.

Passiamo ora all'ottimizzazione. Un journal con i record verrà archiviato nella cartella dell'agente. Nel mio caso il percorso è il seguente: %Program Files\MetaTrader5\tester\Agent-127.0.0.1-3000\logs

OH      0       17:48:14.010    Test1_Modes_EA (EURUSD.e,H1)     2014.11.03 00:00:00   Current mode: MQL_MODE_OPTIMIZATION
KJ      0       17:48:14.010    Test1_Modes_EA (EURUSD.e,H1)     2014.11.03 00:00:00   Debug mode: no
NO      0       17:48:14.010    Test1_Modes_EA (EURUSD.e,H1)     2014.11.03 00:00:00   Profile mode: no
FI      0       17:48:14.010    Test1_Modes_EA (EURUSD.e,H1)     2014.11.03 00:00:00   Tester mode: yes
KE      0       17:48:14.010    Test1_Modes_EA (EURUSD.e,H1)     2014.11.03 00:00:00   Optimization mode: yes
LS      0       17:48:14.010    Test1_Modes_EA (EURUSD.e,H1)     2014.11.03 00:00:00   Visual mode: no
QE      0       17:48:14.010    Test1_Modes_EA (EURUSD.e,H1)     2014.11.03 00:00:00   Frame mode: no

Se la modalità di ottimizzazione è attiva, la modalità di test è abilitata per impostazione predefinita.

La modalità di ottimizzazione è attiva in Strategy Tester se il campo "Ottimizzazione" non è disabilitato nella scheda "Impostazioni".

Per scoprire se l'EA viene testato in modalità di ottimizzazione in MQL5, chiamare la funzione MQLInfoInteger() con l'identificatore MQL_OPTIMIZATION.

Stiamo procedendo alla modalità di visualizzazione.

JQ      0       17:53:51.485    Test1_Modes_EA (EURUSD.e,H1)     2014.11.03 00:00:00   Current mode: MQL_MODE_VISUAL
JK      0       17:53:51.485    Test1_Modes_EA (EURUSD.e,H1)     2014.11.03 00:00:00   Debug mode: no
KF      0       17:53:51.485    Test1_Modes_EA (EURUSD.e,H1)     2014.11.03 00:00:00   Profile mode: no
CP      0       17:53:51.485    Test1_Modes_EA (EURUSD.e,H1)     2014.11.03 00:00:00   Tester mode: yes
HJ      0       17:53:51.485    Test1_Modes_EA (EURUSD.e,H1)     2014.11.03 00:00:00   Optimization mode: no
LK      0       17:53:51.485    Test1_Modes_EA (EURUSD.e,H1)     2014.11.03 00:00:00   Visual mode: yes
KS      0       17:53:51.485    Test1_Modes_EA (EURUSD.e,H1)     2014.11.03 00:00:00   Frame mode: no

Qui possiamo vedere che sono coinvolte la modalità di test visivo e la modalità di test standard.

L'EA funziona in questa modalità nello Strategy Tester se il campo "Visualizzazione" nella scheda "Impostazioni" è contrassegnato.

È possibile stabilire il fatto di testare un programma MQL5 in modalità di test visivo utilizzando la funzione MQLInfoInteger() con l'identificatore MQL_VISUAL_MODE.

L'ultima modalità è la gestione della modalità frame.

HI      0       17:59:10.177    Test1_Modes_EA (EURUSD.e,H1)     2014.11.03 00:00:00   Current mode: MQL_MODE_FRAME
GR      0       17:59:10.177    Test1_Modes_EA (EURUSD.e,H1)     2014.11.03 00:00:00   Debug mode: no
JR      0       17:59:10.177    Test1_Modes_EA (EURUSD.e,H1)     2014.11.03 00:00:00   Profile mode: no
JG      0       17:59:10.177    Test1_Modes_EA (EURUSD.e,H1)     2014.11.03 00:00:00   Tester mode: yes
GM      0       17:59:10.177    Test1_Modes_EA (EURUSD.e,H1)     2014.11.03 00:00:00   Optimization mode: yes
HR      0       17:59:10.177    Test1_Modes_EA (EURUSD.e,H1)     2014.11.03 00:00:00   Visual mode: no
MI      0       17:59:10.177    Test1_Modes_EA (EURUSD.e,H1)     2014.11.03 00:00:00   Frame mode: no

È interessante notare che la funzione ha riconosciuto solo le modalità di test e ottimizzazione poiché il flag dei frame è stato azzerato. Se la chiamata della funzione viene trasferita al gestore OnTesterInit(), il journal "Expert" conterrà le seguenti voci:

IO      0       18:04:27.663    Test1_Modes_EA (EURUSD.e,H1)     Current mode: MQL_MODE_FRAME
GE      0       18:04:27.663    Test1_Modes_EA (EURUSD.e,H1)     Debug mode: no
ML      0       18:04:27.663    Test1_Modes_EA (EURUSD.e,H1)     Profile mode: no
CJ      0       18:04:27.663    Test1_Modes_EA (EURUSD.e,H1)     Tester mode: no
QR      0       18:04:27.663    Test1_Modes_EA (EURUSD.e,H1)     Optimization mode: no
PL      0       18:04:27.663    Test1_Modes_EA (EURUSD.e,H1)     Visual mode: no
GS      0       18:04:27.663    Test1_Modes_EA (EURUSD.e,H1)     Frame mode: yes

In effetti, ora è stata rilevata solo la modalità di raccolta dei fotogrammi.

Questa modalità viene utilizzata in Strategy Tester se il campo "Ottimizzazione" nella scheda "Impostazioni" non è disabilitato. Come ha dimostrato l'esperienza, questa modalità è definita nel corpo dei gestori OnTesterInit(), OnTesterPass() e OnTesterDeinit().

La funzione MQLInfoInteger() con l'identificatore MQL_FRAME_MODE può facilitare l'identificazione del fatto di testare un EA in modalità raccolta frame.

Di seguito è riportato il codice della funzione di servizio MqlMode(), che specifica automaticamente la modalità in cui opera l'EA.

//+------------------------------------------------------------------+
//| Identify the current MQL mode                                    |
//+------------------------------------------------------------------+
ENUM_MQL_MODE MqlMode(void)
  {
   ENUM_MQL_MODE curr_mode=WRONG_VALUE;

//--- if it is debug mode
   if(MQLInfoInteger(MQL_DEBUG))
      curr_mode=MQL_MODE_DEBUG;
//--- if it is code profiling mode
   else if(MQLInfoInteger(MQL_PROFILER))
      curr_mode=MQL_MODE_PROFILER;
//--- if it is visual test mode
   else if(MQLInfoInteger(MQL_VISUAL_MODE))
      curr_mode=MQL_MODE_VISUAL;
//--- if it is optimization mode
   else if(MQLInfoInteger(MQL_OPTIMIZATION))
      curr_mode=MQL_MODE_OPTIMIZATION;
//--- if it is test mode
   else if(MQLInfoInteger(MQL_TESTER))
      curr_mode=MQL_MODE_TESTER;
//--- if it is frame gathering optimization result mode
   else if(MQLInfoInteger(MQL_FRAME_MODE))
      curr_mode=MQL_MODE_FRAME;
//--- if it is release mode
   else
      curr_mode=MQL_MODE_RELEASE;
//---
   return curr_mode;
  }

Poiché il test standard viene identificato in modalità di ottimizzazione e test visivo, la modalità di test standard deve essere verificata dopo l'ottimizzazione e la modalità di visualizzazione.

Se diamo un'occhiata al lavoro della funzione nel secondo template dell'EA Test2_Modes_EA.mq5, possiamo vedere che una nuova voce appare nel journal all'avvio del template. Ad esempio, per la modalità di profilazione è stata fatta la seguente voce:

HG      0       11:23:52.992    Test2_Modes_EA (EURUSD.e,H1)    Current mode: MQL_MODE_PROFILER

Abbiamo discusso i dettagli delle modalità operative dell'Expert MQL5 per la creazione di modelli di classe corrispondenti a una modalità specificata. Lo implementeremo nella prossima parte dell'articolo.


3. Modello dell'EA progettato per funzionare in diverse modalità

Suggerisco di ripassare le fasi di sviluppo di un EA.

Nella fase di algoritmizzazione, un programmatore esegue molto spesso il debug e la profilazione. Per testare i dati storici, provano tutte le modalità dello Strategy Tester. La modalità finale (modalità di rilascio) è utilizzata nel trading online.

A mio parere, un EA deve essere multiforme, nel senso che i requisiti delle fasi di sviluppo e test devono riflettersi nel suo codice.

A quel punto, l'algoritmo principale verrà preservato e, a seguito di esso, l'EA avrà un comportamento diverso in diverse modalità. Il set di strumenti di programmazione orientato agli oggetti si adatta perfettamente all'implementazione di questa idea.

Fig.2 Gerarchia di classi per l'EA progettata per funzionare in diverse modalità

Fig.3. Gerarchia di classe per EA progettata per funzionare in diverse modalità

La gerarchia di classi con implementazione di diverse modalità è rappresentata in Fig.3.

La classe base CModeBase che incapsula tutte le cose comuni avrà due discendenti diretti: le classi CModeRelease e CModeTester. Il primo sarà un genitore per le classi di debug e il secondo per le classi legate al test dell'EA su dati storici.

Sviluppiamo l'idea di combinare un approccio procedurale e modulare quando si sviluppano metodi di classe nel contesto dei modi. A titolo di esempio consideriamo la seguente logica di trading:

  1. Aprire da un segnale se non c'è posizione aperta;
  2. Chiusura al segnale se c'è una posizione aperta;
  3. Trailing Stop se c'è una posizione aperta.

Il segnale di trading viene rilevato dall'indicatore standard MACD quando appare una nuova barra.

Un segnale da acquistare appare quando la linea principale sta andando verso l'alto e attraversa il segnale nella zona negativa dell'indicatore MACD (Fig.4).

Fig.4 Segnale per acquistare

Fig.4. Segnale di acquisto

Un segnale da vendere appare quando la linea principale sta andando verso il basso e incrocia quella del segnale nella zona positiva dell'indicatore (Fig. 5).

Fig.5 Segnale di vendere

Fig.5. Segnale di vendere

La posizione viene chiusa o quando appare il segnale opposto o dallo Stop Loss, che viene posizionato nel caso in cui sia abilitata la modalità di un supporto di posizione.

Quindi la definizione della classe base CModeBase è la seguente:

//+------------------------------------------------------------------+
//| Class CModeBase                                                  |
//| Purpose: a base class for MQL-modes                              |            
//+------------------------------------------------------------------+
class CModeBase
  {
//--- === Data members === --- 
private:
   //--- a macd object & values
   CiMACD            m_macd_obj;
   double            m_macd_main_vals[2];
   double            m_macd_sig_vals[2];

protected:
   long              m_pos_id;
   bool              m_is_new_bar;
   uint              m_trailing_stop;
   uint              m_trail_step;
   //--- trade objects
   CSymbolInfo       m_symbol_info;
   CTrade            m_trade;
   CPositionInfo     m_pos_info;
   CDealInfo         m_deal_info;
   //--- mql mode
   ENUM_MQL_MODE     m_mql_mode;

   //--- a new bar object
   CisNewBar         m_new_bar;
   //--- current tick signal flag
   bool              m_is_curr_tick_signal;
   //--- close order type
   ENUM_ORDER_TYPE   m_close_ord_type;
   
//--- === Methods === --- 
public:
   //--- constructor/destructor
   void              CModeBase();
   void             ~CModeBase(void){};
   //--- initialization
   virtual bool      Init(int _fast_ema,int slow_ema,int _sig,ENUM_APPLIED_PRICE _app_price);
   virtual void      Deinit(void){};

   //--- Modules
   virtual void      Main(void){};

   //--- Procedures
   virtual void      Open(void){};
   virtual void      Close(void){};
   virtual void      Trail(void){};

   //--- Service
   static ENUM_MQL_MODE CheckMqlMode(void);
   ENUM_MQL_MODE     GetMqlMode(void);
   void              SetMqlMode(const ENUM_MQL_MODE _mode);
   void              SetTrailing(const uint _trailing,const uint _trail_step);

protected:
   //--- Functions
   ENUM_ORDER_TYPE   CheckOpenSignal(const ENUM_ORDER_TYPE _open_sig);
   ENUM_ORDER_TYPE   CheckCloseSignal(const ENUM_ORDER_TYPE _close_sig);
   ENUM_ORDER_TYPE   CheckTrailSignal(const ENUM_ORDER_TYPE _trail_sig,double &_sl_pr);
   //---
   double            GetMacdVal(const int _idx,const bool _is_main=true);

private:
   //--- Macros
   bool              RefreshIndicatorData(void);
   //--- Normalization
   double            NormalPrice(double d);
   double            NormalDbl(double d,int n=-1);
   double            NormalSL(const ENUM_ORDER_TYPE _ord_type,double op,double pr,
                              uint SL,double stop);
   double            NormalTP(const ENUM_ORDER_TYPE _ord_type,double op,double pr,
                              uint _TP,double stop);
   double            NormalLot(const double _lot);
  };

Qualsiasi cosa può essere inclusa in una classe di base fintanto che verrà utilizzata nelle classi eredi.

I dati MACD non saranno disponibili per i discendenti in quanto rappresentati da membri privati.

Va notato che tra questi metodi ci sono quelli virtuali: Main(), Open(), Close(), Trail(). La loro implementazione dipenderà in larga misura dalla modalità in cui l'EA sta attualmente lavorando. Questi metodi rimarranno vuoti per la classe base.

Inoltre, la classe base comprende metodi che hanno la stessa logica di trading per tutte le modalità MQL. Tutti i metodi di segnale appartengono a loro:

  • CModeBase::CheckOpenSignal(),
  • CModeBase::CheckCloseSignal(),
  • CModeBase::CheckTrailSignal().

Va tenuto presente che questo articolo non mira alla scrittura di codice per tutti i tipi di modalità MQL. I test standard e visivi serviranno da esempio.


3.1. Modalità test

Dopo che l'algoritmo è stato codificato e compilato, di solito provo la strategia su dati storici nello Strategy Tester per verificare se funziona come previsto.

Molto spesso è necessario verificare con quanta precisione il sistema implementa i segnali di trading. In ogni caso, l'obiettivo fondamentale in questa fase per un EA è il lancio e il trading.

La classe CModeTester per i test regolari può essere implementata come segue:

//+------------------------------------------------------------------+
//| Class CModeTester                                                |
//| Purpose: a class for the tester mode                             |            
//| Derives from class CModeBase.                                    |
//+------------------------------------------------------------------+
class CModeTester : public CModeBase
  {
//--- === Methods === --- 
public:
   //--- constructor/destructor
   void              CModeTester(void){};
   void             ~CModeTester(void){};

   //--- Modules
   virtual void      Main(void);

   //--- Procedures
   virtual void      Open(void);
   virtual void      Close(void);
   virtual void      Trail(void);
  };

Il modulo principale è implementato come:

//+------------------------------------------------------------------+
//| Main module                                                      |
//+------------------------------------------------------------------+
void CModeTester::Main(void)
  {
//--- 1) closure
   this.Close();
//--- 2) opening
   this.Open();
//--- 3) trailing stop
   this.Trail();
  }

Per la modalità di test regolare, crea un'opportunità per stampare informazioni sui segnali di trading nel Journal.

Aggiungi stringhe contenenti valori dell'indicatore che sono considerati la fonte del segnale di trading.

Di seguito è riportato un estratto dal Journal su un segnale per aprire una posizione seguito da un segnale per chiudere.

HE      0       13:34:04.118    Core 1  2014.11.14 22:15:00   ---=== Signal to open: SELL===---
FI      0       13:34:04.118    Core 1  2014.11.14 22:15:00   A bar before the last one, main: 0.002117; signal: 0.002109
DL      0       13:34:04.118    Core 1  2014.11.14 22:15:00   The last bar, main: 0.002001; signal: 0.002118
LO      0       13:34:04.118    Core 1  2014.11.14 22:15:00   market sell 0.03 EURUSD.e (1.25242 / 1.25251 / 1.25242)
KH      0       13:34:04.118    Core 1  2014.11.14 22:15:00   deal #660 sell 0.03 EURUSD.e at 1.25242 done (based on order #660)
GE      0       13:34:04.118    Core 1  2014.11.14 22:15:00   deal performed [#660 sell 0.03 EURUSD.e at 1.25242]
OD      0       13:34:04.118    Core 1  2014.11.14 22:15:00   order performed sell 0.03 at 1.25242 [#660 sell 0.03 EURUSD.e at 1.25242]
IK      0       13:34:04.118    Core 1  2014.11.14 22:15:00   CTrade::OrderSend: market sell 0.03 EURUSD.e [done at 1.25242]
IL      0       13:34:04.118    Core 1  2014.11.17 13:30:20   
CJ      0       13:34:04.118    Core 1  2014.11.17 13:30:20   ---=== Signal to close: SELL===---
GN      0       13:34:04.118    Core 1  2014.11.17 13:30:20   A bar before the last one, main: -0.001218; signal: -0.001148
QL      0       13:34:04.118    Core 1  2014.11.17 13:30:20   The last bar, main: -0.001123; signal: -0.001189
EP      0       13:34:04.118    Core 1  2014.11.17 13:30:20   market buy 0.03 EURUSD.e (1.25039 / 1.25047 / 1.25039)
FG      0       13:34:04.118    Core 1  2014.11.17 13:30:20   deal #661 buy 0.03 EURUSD.e at 1.25047 done (based on order #661)
OJ      0       13:34:04.118    Core 1  2014.11.17 13:30:20   deal performed [#661 buy 0.03 EURUSD.e at 1.25047]
PD      0       13:34:04.118    Core 1  2014.11.17 13:30:20   order performed buy 0.03 at 1.25047 [#661 buy 0.03 EURUSD.e at 1.25047]
HE      0       13:34:04.118    Core 1  2014.11.17 13:30:20   CTrade::OrderSend: market buy 0.03 EURUSD.e [done at 1.25047]

Si prega di notare che non ci sono riviste familiari "Expert" nello Strategy Tester. Tutte le informazioni possono essere trovate nella scheda "Journal", che contiene i record sulle azioni eseguite dallo Strategy Tester durante il test e l'ottimizzazione.

Ecco perché bisogna cercare le stringhe richieste. Se è necessario separare le informazioni della voce, è possibile registrarle in un file.

La strategia per i test standard è implementata nel codice di TestMode_tester.mq5 EA.


3.2. Testing Visuale

A volte è necessario fare riferimento a un grafico in tempo reale e vedere come un EA sta gestendo la situazione attuale.

La semplice visualizzazione consente non solo di vedere come reagisce il sistema di trading ai tick, ma anche di confrontare modelli di prezzo simili alla fine del test.

La definizione della classe CModeVisual per i test visivi può essere la seguente:

//+------------------------------------------------------------------+
//| Class CModeVisual                                                |
//| Purpose: a class for the tester mode                             |            
//| Derived from class CModeBase.                                    |
//+------------------------------------------------------------------+
class CModeVisual : public CModeTester
  {
//--- === Data members === --- 
private:
   CArrayObj         m_objects_arr;
   double            m_subwindow_max;
   double            m_subwindow_min;
   
//--- === Methods === --- 
public:
   //--- constructor/destructor
   void              CModeVisual(void);
   void             ~CModeVisual(void);

   //--- Procedures
   virtual void      Open(void);
   virtual void      Close(void);

private:
   bool              CreateSignalLine(const bool _is_open_sig,const bool _is_new_bar=true);
   bool              CreateRectangle(const ENUM_ORDER_TYPE _signal);
   void              RefreshRectangles(void);
  };

La classe contiene membri nascosti. Un membro della classe m_objects_arr implementa un array dinamico del tipo CArrayObj. Gli oggetti grafici, ad esempio linee e rettangoli, appartengono a questo campo. Altri due membri della classe (m_subwindow_max, m_subwindow_min) controllano le dimensioni massime e minime della sottofinestra dell'indicatore.

I metodi privati sono responsabili del lavoro con gli oggetti grafici.

Questa classe non contiene i metodi Main() e Trail(). I loro analoghi genitori CModeTester::Main() e CModeTester::Trail() verranno chiamati rispettivamente.

Gli oggetti grafici possono essere creati nella modalità di test visivo. Questo non può essere fatto in altre modalità dello Strategy Tester.

Disegna una verticale rossa sul grafico quando appare un segnale per entrare e una verticale blu quando viene ricevuto un segnale per uscire. Riempi lo spazio tra i punti di entrata e di uscita con un rettangolo del colore pertinente nella sottofinestra dell'indicatore.

Se è una posizione lunga, il rettangolo è azzurro. Se la posizione è corta, il rettangolo è rosa (Fig.6).

Fig.6. Oggetti grafici in modalità visual testing

Fig.6. Oggetti grafici nella modalità di test visivo

L'altezza del rettangolo dipende dai valori di massimo e minimo della sottofinestra del grafico al momento della creazione. Per rendere tutti i rettangoli di dimensioni uguali, è necessario aggiungere al codice un blocco di coordinate rettangolari modificabili nel caso in cui le coordinate della sottofinestra del grafico cambino.

Quindi nella sottofinestra dell'indicatore MACD otteniamo le seguenti aree: non colorato (nessuna posizione), rosa (posizione corta), azzurro (lungo posizione).

La strategia per la modalità di test visuale è implementata nel codice dell'EA TestMode_visual_tester.mq5.


Conclusione

In questo articolo ho cercato di illustrare le funzionalità della modalità del terminale MetaTrader 5 e del linguaggio MQL5. Va detto che un approccio multimodale alla programmazione di un algoritmo di trading comporta da un lato maggiori costi e dall'altro offre l'opportunità di considerare ogni fase di sviluppo una dopo l'altra. La programmazione orientata agli oggetti è un aiuto ingegnoso per un programmatore in questo caso.

Le modalità di ottimizzazione e raccolta dei frame verranno evidenziate nei prossimi articoli sulle proprietà statistiche di un trading system.


Tradotto dal russo da MetaQuotes Ltd.
Articolo originale: https://www.mql5.com/ru/articles/1246

File allegati |
cisnewbar.mqh (13.74 KB)
modes.mqh (62.77 KB)
test1_modes_ea.mq5 (9.43 KB)
test2_modes_ea.mq5 (10.01 KB)
Principi dei prezzi di scambio attraverso l'esempio del mercato dei derivati della Borsa di Mosca Principi dei prezzi di scambio attraverso l'esempio del mercato dei derivati della Borsa di Mosca
Questo articolo descrive la teoria dei prezzi di cambio e le specifiche di compensazione del mercato dei derivati della Borsa di Mosca. Questo è un articolo completo per i principianti che cercano una prima esperienza di scambio sul trading di derivati, così come per i trader forex esperti che stanno considerando di fare trading su una piattaforma di scambio centralizzata.
Manuale statistico del trader ipotesi Manuale statistico del trader ipotesi
Questo articolo considera l'ipotesi, una delle idee di base della statistica matematica. Varie ipotesi vengono esaminate e verificate attraverso esempi utilizzando metodi di statistica matematica. I dati effettivi vengono generalizzati utilizzando metodi non parametrici. Per l'elaborazione dei dati vengono utilizzati il pacchetto Statistica e la libreria di analisi numerica ALGLIB MQL5 pilotata.
Trading bidirezionale e copertura delle posizioni in MetaTrader 5 utilizzando il pannello HedgeTerminal, parte 1 Trading bidirezionale e copertura delle posizioni in MetaTrader 5 utilizzando il pannello HedgeTerminal, parte 1
Questo articolo descrive un nuovo approccio al hedging delle posizioni e pone dei limiti nei dibattiti tra gli utenti di MetaTrader 4 e MetaTrader 5 su questo argomento. Gli algoritmi che rendono affidabile tale copertura sono descritti in parole povere e illustrati con semplici grafici e diagrammi. Questo articolo è dedicato al nuovo pannello HedgeTerminal, che è essenzialmente un terminale di trading completo all'interno di MetaTrader 5. Utilizzando HedgeTerminal e la virtualizzazione del trading che esso offre, le posizioni possono essere gestite in modo simile a MetaTrader 4.
Fondamenti di programmazione MQL5: Variabili Globali del Terminale Fondamenti di programmazione MQL5: Variabili Globali del Terminale
Questo articolo evidenzia le capacità orientate agli oggetti del linguaggio MQL5 per la creazione di oggetti che facilitano il lavoro con le variabili globali del terminale. Come esempio pratico considero un caso in cui le variabili globali vengono utilizzate come punti di controllo per l'implementazione delle fasi del programma.