English Русский 中文 Español Deutsch 日本語 Português 한국어 Français Türkçe
Crea il Tuo Robot di Trading in 6 Passaggi!

Crea il Tuo Robot di Trading in 6 Passaggi!

MetaTrader 5Esempi | 9 dicembre 2021, 14:24
1 322 0
MetaQuotes
MetaQuotes

Ancora una Volta su MQL5 Wizard.

Il mondo intorno a noi sta cambiando rapidamente e noi cerchiamo di stargli dietro. Non abbiamo tempo per imparare qualcosa di nuovo e questo è un atteggiamento normale di un normale essere umano. I trader sono persone come tutti gli altri, vogliono ottenere il massimo risultato con il minimo sforzo. Specialmente per i trader, MetaEditor 5 offre un meraviglioso MQL5 Wizard. Ci sono diversi articoli che descrivono come creare un sistema di trading automatizzato utilizzando la procedura guidata, tra cui una "versione leggera" MQL5 Wizard per “i più Duri di Comprendonio” e una "versione dagli sviluppatori" - MQL5 Wizard: Nuova Versione.

Sembra tutto a posto: un robot di trading viene creato con 5 click del mouse, puoi testarlo nello Strategy Tester eottimizzare i parametri di un sistema di trading, puoi lasciare che il robot risultante venga scambiato sul tuo account senza la necessità di fare nient'altro manualmente. Ma il problema sorge quando un trader/sviluppatore MQL5 vuole creare qualcosa di suo, qualcosa di unico che non è mai stato descritto da nessuna parte, e sta per scrivere il proprio modulo di segnali di trading. Il trader apre la documentazione MQL5, accede alla Libreria Standard ed è inorridito nel vedere...


Cinque Classi Terribili

È vero, MQL5 Wizard semplifica enormemente la creazione di un Expert Advisor, ma prima devi imparare cosa verrà utilizzato come input per esso. Per creare automaticamente un Expert Advisor utilizzando MQL5 Wizard, assicurati che i suoi componenti aderiscano a cinque classi di base della sezione Classi di base degli Expert Advisor:

  • CExpertBase è una classe base per altre quattro classi.
  • CExpert è la classe per la creazione di un robot di trading; questa è la classe che fa trading.
  • CExpertSignal è una classe per la creazione di un modulo di segnali di trading; l'articolo riguarda questa classe.
  • CExpertTrailing è una classe per seguire uno Stop Loss protettivo.
  • CExpertMoney è la classe di gestione del denaro.

Ecco tutta la forza dell'approccio "grande e terribile" chiamato Programmazione Orientata agli Oggetti (OOP). Ma niente paura, ormai quasi tutti hanno un cellulare con tante funzioni e quasi nessuno sa come funziona. Non abbiamo bisogno di studiare tutto questo, parleremo solo di alcune funzioni della classe CExpertSignal.


In questo articolo, esamineremo le fasi della creazione di un modulo di segnali di trading e vedrai come farlo senza dover imparare l'OOP o le classi. Ma se vuoi, allora puoi andare un po' oltre.


1. Creare una Classe da Zero

Non modificheremo alcun modulo esistente di segnali di trading alle nostre esigenze, perché è il modo per confondersi. Pertanto, scriveremo semplicemente la nostra classe, ma prima useremo Navigator per creare una nuova cartella per memorizzare i nostri segnali in MQL5/Include/Expert/.



Fare click con il tasto destro sulla cartella che abbiamo creato, selezionare "Nuovo file" e creare una nuova classe per il nostro modulo di segnali di trading.


Compila i campi:

  • Class Name: il nome della classe. Questo sarà un modulo per generare segnali all'intersezione di due medie mobili, quindi chiamiamolo MA_Cross.
  • Base Name è la classe da cui è derivata la nostra classe. E dovremmo derivarlo dalla classe base CExpertSignal.

Fare click su "Fine" e una bozza del nostro modulo è pronta. È tutto a est finora. Abbiamo solo bisogno di aggiungere la dichiarazione #include al file risultante in modo che il compilatore sappia dove trovare la classe base CExpertSignal

#include "..\ExpertSignal.mqh"   // CExpertSignal is in the file ExpertSignal

Il risultato:

//+------------------------------------------------------------------+
//|                                                     MA_Cross.mqh |
//|                        Copyright 2012, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2012, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"

#include "..\ExpertSignal.mqh"   // CExpertSignal is in the file ExpertSignal
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class MA_Cross : public CExpertSignal
  {
private:

public:
                     MA_Cross();
                    ~MA_Cross();
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
MA_Cross::MA_Cross()
  {
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
MA_Cross::~MA_Cross()
  {
  }
//+------------------------------------------------------------------+

Controlla la classe risultante (deve essere priva di errori di compilazione) e clicca F7. Non ci sono errori e possiamo andare avanti.


2. Un Handle per il Modulo

La nostra classe è completamente vuota, non contiene errori e possiamo testarla: proviamo a creare un nuovo Expert Advisor in MQL5 Wizard basato su di essa. Arriviamo alla fase di selezione di un modulo di segnali di trading e vediamo... che il nostro modulo non c'è.


E come può essere lì? Non aggiungiamo alcuna indicazione per MQL5 Wizard per capire che la nostra classe potrebbe essere qualcosa di utile. Risolviamo questo problema. Se guardi i moduli del pacchetto standard, vedrai che ognuno di essi contiene un'intestazione all'inizio del file. Questo è l'handle del modulo compilato secondo determinate regole. E le regole sono molto semplici.

Aprire, ad esempio, il codice sorgente del modulo dei segnali di trading basati su AMA (vedere la descrizione logica in Segnali della Media Mobile Adattiva.) Ed esegui MQL5 Wizard scegliendo questo modulo. Paragona:

L'ultimo blocco nell'handle si riferisce ai parametri del modulo, la prima riga contiene il nome del modulo da visualizzare nel Wizard MQL5. Come puoi vedere, non c'è niente di complicato. Pertanto, l'handle di ciascun modulo contiene le seguenti voci:

  • Titolo - il nome del modulo da mostrare in MQL5 Wizard.
  • Tipo - la versione del modulo dei segnali. Deve essere sempre SignalAdvanced.
  • Nome: il nome del modulo dopo che è stato selezionato in MQL5 Wizard e viene utilizzato nei commenti per descrivere i parametri interni dell'Expert Advisor generato (preferibilmente specificato).
  • ShortName - un prefisso per la denominazione automatica dei parametri esterni nell'Expert Advisor generato (nella forma di Signal_<ShortName>_<ParameterName>).
  • Class - il nome della classe che è contenuto nel modulo.
  • Pagina - un parametro per ottenere la Guida per questo modulo (solo per i moduli della consegna standard).

Segue la descrizione dei parametri sotto forma di Parameter=list_of_values, in cui viene specificato quanto segue (separato da virgole):

  1. Il nome della funzione per impostare il valore del parametro all'avvio di Expert Advisor.
  2. Il tipo di parametro può essere enumerazione.
  3. Il valore predefinito per il parametro, ovvero il valore che verrà impostato sul parametro, se non lo si modifica in MQL5 Wizard.
  4. Descrizione del parametro, che vedi quando avvii l'Expert Advisor generato in MQL5 Wizard.

Ora, sapendo tutto questo, creiamo l'handle del nostro modulo di segnali di trading. Quindi, stiamo scrivendo un modulo per ottenere segnali di trading all'intersezione di due medie mobili. Dobbiamo impostare almeno quattro parametri esterni:

  • FastPeriod - il periodo della media mobile veloce
  • FastMethod - il tipo di livellamento della media mobile veloce
  • SlowPeriod - il periodo della media mobile lenta
  • SlowMethod - il tipo di smoothing della media mobile lenta

Potresti anche aggiungere uno spostamento e il tipo di prezzi per calcolare ciascuna delle medie mobili, ma sostanzialmente non cambia nulla. Quindi, la versione attuale è la seguente:

// wizard description start
//+------------------------------------------------------------------+
//| Description of the class                                         |
//| Title=Signals at the intersection of two MAs                     |
//| Type=SignalAdvanced                                              |
//| Name=My_MA_Cross                                                 |
//| ShortName=MaCross                                                |
//| Class=MA_Cross                                                   |
//| Page=Not needed                                                  |
//| Parameter=FastPeriod,int,13,Period of fast MA                    |
//| Parameter=FastMethod,ENUM_MA_METHOD,MODE_SMA,Method of fast MA   |
//| Parameter=SlowPeriod,int,21,Period of slow MA                    |
//| Parameter=SlowMethod,ENUM_MA_METHOD,MODE_SMA,Method of slow MA   |
//+------------------------------------------------------------------+
// wizard description end

L'handle del modulo è pronto e in esso abbiamo descritto quanto segue:

  1. Il nome visualizzato in MQL5 Wizard - "Segnali all'intersezione di due medie mobili".
  2. Quattro parametri esterni per configurare i segnali di trading.
    • FastPeriod - il periodo della media mobile veloce con il valore predefinito di 13.
    • FastMethod - il tipo di smoothing della media mobile veloce, smoothing semplice per impostazione predefinita.
    • SlowPeriod - il periodo della media mobile lenta con il valore predefinito di 21.
    • SlowMethod - il tipo di smoothing della media mobile lenta, smoothing semplice di default.

Salva le modifiche e compila. Non dovrebbero esserci errori. Eseguire in MQL5 Wizard per verificare. Vedi, il nostro modulo è ora disponibile per la selezione e mostra tutti i nostri parametri!


Congratulazioni, il nostro modulo di segnale di trading sembra fantastico ora!


3. Metodi per l'Impostazione dei Parametri

Ora è il momento di lavorare con i parametri esterni. Poiché il nostro modulo di trading è rappresentato dalla classe MA_Cross, i suoi parametri devono essere memorizzati all'interno della stessa classe dei membri privati. Aggiungiamo quattro righe (pari al numero di parametri) alla dichiarazione della classe. Abbiamo già descritto il parametro nell'handle e sappiamo quanto segue:

class MA_Cross : public CExpertSignal
  {
private:
   //--- Configurable module parameters
   int               m_period_fast;    // Period of the fast MA
   int               m_period_slow;    // Period of the slow MA
   ENUM_MA_METHOD    m_method_fast;    // Type of smoothing of the fast MA
   ENUM_MA_METHOD    m_method_slow;    // Type of smoothing of the slow MA

Ma come fanno i valori ​​dei parametri esterni del modulo compaiono nei corrispondenti membri della nostra classe MA_Cross? È tutto molto semplice, devi solo dichiarare metodi pubblici dello stesso nome nella classe, ovvero aggiungere quattro righe alla sezione pubblica:

class MA_Cross : public CExpertSignal
  {
private:
   //--- Configurable module parameters
   int               m_period_fast;    // Period of the fast MA
   int               m_period_slow;    // Period of the slow MA
   ENUM_MA_METHOD    m_method_fast;    // Type of smoothing of the fast MA
   ENUM_MA_METHOD    m_method_slow;    // Type of smoothing of the slow MA

public:
   //--- Constructor of class
                     MA_Cross();
   //--- Destructor of class
                    ~MA_Cross();
   //--- Methods for setting
   void              FastPeriod(int value)               { m_period_fast=value;        }
   void              FastMethod(ENUM_MA_METHOD value)    { m_method_fast=value;        }
   void              SlowPeriod(int value)               { m_period_slow=value;        }
   void              SlowMethod(ENUM_MA_METHOD value)    { m_method_slow=value;        }
   };

Quando si genera un Expert Advisor sulla base di questo modulo utilizzando MQL5 Wizard e lo si esegue sul grafico, questi quattro metodi vengono chiamati automaticamente durante l'inizializzazione dell’Expert Advisor. Quindi ecco una semplice regola:

La regola della creazione dei parametri nel modulo - per ogni parametro che abbiamo dichiarato nell'handle, dovremmo creare un membro privato nella classe per memorizzare il suo valore e un membro pubblico per impostarlo. Il nome del metodo deve corrispondere al nome del parametro.

E l'ultimo momento è quello di impostare i valori predefiniti ​​per i nostri parametri che verranno utilizzati nel caso non vengano richiamati i metodi di impostazione del valore. Ogni variabile dichiarata o membro di classe deve essere inizializzato. Questa tecnica permette di evitare molti degli errori difficili da trovare.

Per l'inizializzazione automatica, il più adatto è il constructor di classi; è sempre il primo ad essere chiamato quando si crea un oggetto. Per i valori predefiniti, useremo quelli scritti nell'handle del modulo.

class MA_Cross : public CExpertSignal
  {
private:
   //--- Configurable module parameters
   int               m_period_fast;    // Period of the fast MA
   ENUM_MA_METHOD    m_method_fast;     // Type of smoothing of the fast MA
   int               m_period_slow;    // Period of the slow MA
   ENUM_MA_METHOD    m_method_slow;     // Type of smoothing of the slow MA

public:
   //--- Constructor of class
                     MA_Cross(void);
   //--- Destructor of class
                    ~MA_Cross(void);
//+------------------------------------------------------------------+
//| Constructor                                                      |
//+------------------------------------------------------------------+
MA_Cross::MA_Cross(void) : m_period_fast(13),          // Default period of the fast MA is 3
                           m_method_fast(MODE_SMA),    // Default smoothing method of the fast MA
                           m_period_slow(21),          // Default period of the slow MA is 21
                           m_method_slow(MODE_SMA)     // Default smoothing method of the slow MA
  {
  }

Qui, i membri della classe vengono inizializzati utilizzando l'elenco di inizializzazione.

Come puoi vedere, non abbiamo ancora utilizzato indicatori di media mobile. Abbiamo trovato una semplice regola: poiché molti parametri sono indicati nell'handledel modulo, tanti metodi e membri dovrebbero essere nella classe che implementa il modulo. Non c'è niente di complicato! Tuttavia, non dimenticare di impostare i valori predefiniti dei parametri nel constructor.


4. //--- imposta la correttezza dei parametri di input

Abbiamo creato parametri per il nostro modulo di trading, metodi scritti per impostare i valori ​​a loro e ora arriva la prossima importante fase: la correttezza dei parametri deve essere verificata. Nel nostro caso, dobbiamo verificare i periodi delle medie mobili e il tipo di smoothing per il loro calcolo. Per questo scopo dovresti scrivere il tuo metodo ValidationSettings() nella classe. Questo metodo è definito nella classe genitore CExpertBase e in tutti i suoi figli è obbligatoriamente ridefinito.

Ma se non sai nulla sulla programmazione orientata agli oggetti, ricorda: nella nostra classe dovremmo scrivere la funzione ValidationSettings(), che non richiede parametri e restituisce true o false.

class MA_Cross : public CExpertSignal
  {
...
   //--- Constructor of class
                     MA_Cross(void);
   //--- Destructor of class
                    ~MA_Cross(void);
   //--- Checking correctness of input data
   bool              ValidationSettings();
...
   };
//+------------------------------------------------------------------+
//| Checks input parameters and returns true if everything is OK     |
//+------------------------------------------------------------------+
bool MA_Cross:: ValidationSettings()
  {
   //--- Call the base class method
   if(!CExpertSignal::ValidationSettings())  return(false);
   //--- Check periods, number of bars for the calculation of the MA >=1
   if(m_period_fast<1 || m_period_slow<1)
     {
      PrintFormat("Incorrect value set for one of the periods! FastPeriod=%d, SlowPeriod=%d",
                  m_period_fast,m_period_slow);
      return false;
     }
//--- Slow MA period must be greater that the fast MA period
   if(m_period_fast>m_period_slow)
     {
      PrintFormat("SlowPeriod=%d must be greater than FastPeriod=%d!",
                  m_period_slow,m_period_fast);
      return false;
     }
//--- Fast MA smoothing type must be one of the four values of the enumeration
   if(m_method_fast!=MODE_SMA && m_method_fast!=MODE_EMA && m_method_fast!=MODE_SMMA && m_method_fast!=MODE_LWMA)
     {
      PrintFormat("Invalid type of smoothing of the fast MA!");
      return false;
     }
//--- Show MA smoothing type must be one of the four values of the enumeration
   if(m_method_slow!=MODE_SMA && m_method_slow!=MODE_EMA && m_method_slow!=MODE_SMMA && m_method_slow!=MODE_LWMA) 
     {
      PrintFormat("Invalid type of smoothing of the slow MA!");
      return false;
     }
//--- All checks are completed, everything is ok
   return true;
  }
Come puoi vedere, nella parte pubblica della classe MA_Cross abbiamo aggiunto la dichiarazione del metodo ValidationSettings() e quindi aggiunto il corpo del metodo nel seguente modulo:
bool MA_Cross:: ValidationSettings()

Prima viene il tipo restituito, quindi il nome della classe, poi l'operatore di risoluzione dello scopo :: e tutto questo è seguito dal nome del metodo dichiarato in precedenza. Non dimenticare che il nome e il tipo di parametri devono corrispondere nella dichiarazione e nella descrizione del metodo della classe. Tuttavia, il compilatore ti avviserà di tale errore.

Si noti che prima viene chiamato il metodo della classe base, quindi vengono controllati i parametri di input.

//--- Call the base class method
   if(!CExpertSignal::ValidationSettings())  return(false);
//--- Our code to check the values of parameters

Se non aggiungi questa riga, l'Expert Advisor generato non sarà in grado di inizializzare il nostro modulo di segnali di trading.


5. Dove Sono i Nostri Indicatori?

È tempo di lavorare con gli indicatori, poiché tutto il lavoro preparatorio con i parametri per essi è stato completato. Ciascun modulo di segnali di trading contiene il metodo InitIndicators() che viene chiamato automaticamente quando si esegue l'Expert Advisor generato. In questo metodo, dobbiamo fornire indicatori di medie mobili per il nostro modulo.

Innanzitutto, dichiara il metodo InitIndicators() nella classe e incolla la sua bozza:

public:
   //--- Constructor of class
                     MA_Cross(void);
   //--- Destructor of class
                    ~MA_Cross(void);
   //--- Methods for setting
   void              FastPeriod(int value)               { m_period_fast=value;        }
   void              FastMethod(ENUM_MA_METHOD value)    { m_method_fast=value;        }
   void              SlowPeriod(int value)               { m_period_slow=value;        }
   void              SlowMethod(ENUM_MA_METHOD value)    { m_method_slow=value;        }
   //--- Checking correctness of input data
   bool              ValidationSettings();
   //--- Creating indicators and timeseries for the module of signals
   bool              InitIndicators(CIndicators *indicators);
  };
...
//+------------------------------------------------------------------+
//| Creates indicators                                               |
//| Input:  a pointer to a collection of indicators                  |
//| Output: true if successful, otherwise false                      |
//+------------------------------------------------------------------+
bool MA_Сross::InitIndicators(CIndicators* indicators)
  {
//--- Standard check of the collection of indicators for NULL
   if(indicators==NULL)                           return(false);
//--- Initializing indicators and timeseries in additional filters
   if(!CExpertSignal::InitIndicators(indicators)) return(false);
//--- Creating our MA indicators
   ... Some code here
//--- Reached this part, so the function was successful, return true
   return(true);
  }

Quindi non c'è niente di complicato, dichiariamo il metodo e poi creiamo semplicemente il corpo del metodo, come abbiamo fatto per il metodo ValidationSettings(). Soprattutto, non dimenticare di inserire il nome della classe e l'operatore :: nella definizione della funzione. Abbiamo una bozza, che possiamo inserire in un codice per creare medie mobili. Facciamolo correttamente: per ogni indicatore, creiamo una funzione separata nella classe che restituisce true in caso di successo. La funzione può avere qualsiasi nome, ma lascia che rifletta il suo scopo. Quindi, chiamiamo le funzioni CreateFastMA() e CreateSlowMA().

protected:
   //--- Creating MA indicators
   bool              CreateFastMA(CIndicators *indicators);
   bool              CreateSlowMA(CIndicators *indicators);
  };
//+------------------------------------------------------------------+
//| Creates indicators                                               |
//| Input:  a pointer to a collection of indicators                  |
//| Output: true if successful, otherwise false                      |
//+------------------------------------------------------------------+
bool MA_Cross::InitIndicators(CIndicators *indicators)
  {
//--- Standard check of the collection of indicators for NULL
   if(indicators==NULL) return(false);
//--- Initializing indicators and timeseries in additional filters
   if(!CExpertSignal::InitIndicators(indicators)) return(false);
//--- Creating our MA indicators
   if(!CreateFastMA(indicators))                  return(false);
   if(!CreateSlowMA(indicators))                  return(false);
//--- Reached this part, so the function was successful, return true
   return(true);
  }
//+------------------------------------------------------------------+
//| Creates the "Fast MA" indicator                                  |
//+------------------------------------------------------------------+
bool MA_Cross::CreateFastMA(CIndicators *indicators)
  {
... Some code
//--- Reached this part, so the function was successful, return true
   return(true);
  }
//+------------------------------------------------------------------+
//| Creates the "Slow MA" indicator                                  |
//+------------------------------------------------------------------+
bool MA_Cross::CreateSlowMA(CIndicators *indicators)
  {
... Some code
//--- Reached this part, so the function was successful, return true
   return(true);
  }

Questo è tutto, abbiamo solo bisogno di scrivere il codice che genera gli indicatori MA e in qualche modo integra gli handle di questi indicatori nel modulo di trading, in modo che il modulo possa utilizzare i valori ​di questi indicatori. Ecco perché un puntatore a una variabile di tipo CIndicators viene passato come parametro. Quanto segue, viene scritto nella relativa Documentazione:

Il CIndicators è una classe per la raccolta di istanze di classi temporali e indicatori tecnici. La classe CIndicators prevede la creazione di istanze di classi di indicatori tecnici, la loro memorizzazione e gestione (sincronizzazione dei dati, handle e gestione della memoria).

Ciò significa che dobbiamo creare i nostri indicatori e inserirli in questa raccolta. Poiché solo gli indicatori del modulo CIndicator e dei suoi figli possono essere archiviati nella raccolta, dovremmo usare questo fatto. Useremo CiCustom che è il figlio sopra menzionato. Per ogni media mobile, dichiariamo un oggetto di tipo CiCustom nella parte privata della classe:

class MA_Cross : public CExpertSignal
  {
private:
   CiCustom          m_fast_ma;            // The indicator as an object
   CiCustom          m_slow_ma;            // The indicator as an object
   //--- Configurable module parameters
   int              m_period_fast;   // Period of the fast MA
   ENUM_MA_METHOD    m_method_fast;    // Type of smoothing of the fast MA
   int              m_period_slow;   // Period of the slow MA
   ENUM_MA_METHOD    m_method_slow;    // Type of smoothing of the slow MA

Naturalmente, puoi creare la propria classe di indicatori che sarà derivata da CIndicator e implementare tutti i metodi necessari per l'utilizzo con MQL5 Wizard. Ma in questo caso, vogliamo mostrare come è possibile utilizzare qualsiasi indicatore personalizzato nel modulo dei segnali di trading utilizzando CiCustom.

Ecco come appare nel codice:

//+------------------------------------------------------------------+
//| Creates the "Fast MA" indicator                                  |
//+------------------------------------------------------------------+
bool MA_Cross::CreateFastMA(CIndicators *indicators)
  {
//--- Checking the pointer
   if(indicators==NULL) return(false);
//--- Adding an object to the collection
   if(!indicators.Add(GetPointer(m_fast_ma)))
     {
      printf(__FUNCTION__+": Error adding an object of the fast MA");
      return(false);
     }
//--- Setting parameters of the fast MA
   MqlParam parameters[4];
//---
   parameters[0].type=TYPE_STRING;
   parameters[0].string_value="Examples\\Custom Moving Average.ex5";
   parameters[1].type=TYPE_INT;
   parameters[1].integer_value=m_period_fast;      // Period
   parameters[2].type=TYPE_INT;
   parameters[2].integer_value=0;                  // Shift
   parameters[3].type=TYPE_INT;
   parameters[3].integer_value=m_method_fast;      // Averaging method
//--- Object initialization  
   if(!m_fast_ma.Create(m_symbol.Name(),m_period,IND_CUSTOM,4,parameters))
     {
      printf(__FUNCTION__+": Error initializing the object of the fast MA");
      return(false);
     }
//--- Number of buffers
   if(!m_fast_ma.NumBuffers(1)) return(false);
//--- Reached this part, so the function was successful, return true
   return(true);
  }

Nel metodo CreateFastMA(), controlla prima il puntatore della raccolta di indicatori, quindi aggiungi un puntatore della MA veloce m_fast_ma a questa raccolta. Quindi dichiarare la struttura MqlParam progettata appositamente per memorizzare i parametri degli indicatori personalizzati, e riempirla con i valori.

Usiamo la Media Mobile Personalizzata dal pacchetto di consegna del terminale standard come indicatore MA personalizzato. Il nome dell'indicatore deve essere indicato relativamente alla cartella data_folder/MQL5/Indicatori/. Poiché Custom Moving Average.mq5' dal pacchetto standard si trova in data_folder/MQL5/Indicators/Examples/, ne specifichiamo il percorso inclusa la cartella Examples:

parameters[0].string_value="Examples\\Custom Moving Average.ex5";

Se guardi il codice per questo indicatore, puoi vedere tutti i dati richiesti:

//--- input parameters
input int            InpMAPeriod=13;       // Period
input int            InpMAShift=0;         // Shift
input ENUM_MA_METHOD InpMAMethod=MODE_SMMA;  // Method

I valori ​​della struttura contengono le coppie tipo-valore:

  1. tipo parametro - stringa (per trasferire il nome dell'indicatore)
  2. il nome del file eseguibile dell'indicatore personalizzato - "Custom Moving Averages.exe"
  3. tipo di parametro - int (valore del periodo)
  4. periodo della media mobile
  5. tipo di parametro - int (valore di spostamento)
  6. spostamento orizzontale della media nelle barre
  7. tipo di parametro - int (il valore dell'enumerazione è un numero intero)
  8. metodo di calcolo della media

Dopo aver riempito la struttura, l'indicatore viene inizializzato con il metodo Create() di tutti i parametri richiesti: nome del simbolo e l'intervallo di tempo su cui viene calcolato, il tipo di indicatore dall'enumerazione ENUM_INDICATOR, il numero di parametri dell'indicatore e il MqlParam struttura con i valori dei parametri. E l'ultimo è specificare il numero di buffer indicatori usando il metodo NumBuffers().

Il metodo CreateSlowMA() per creare la media mobile lenta è semplice. Quando si utilizzano indicatori personalizzati nel modulo, non dimenticare che l'Expert Advisor generato da MQL5 Wizard verrà eseguito anche nel tester. Quindi all'inizio del nostro file aggiungiamo la proprietà #property tester_indicator che comunica al tester la posizione degli indicatori richiesti:

#include "..\ExpertSignal.mqh"   // The CExpertSignal class is in the file ExpertSignal
#property tester_indicator "Examples\\Custom Moving Average.ex5"

Se utilizziamo più indicatori diversi, dovremmo aggiungere questa riga per ciascuno di essi. Quindi, abbiamo aggiunto gli indicatori. Per maggiore comodità, forniamo due metodi per ricevere i valori MA:

   //--- Checking correctness of input data
   bool              ValidationSettings(void);
   //--- Creating indicators and timeseries for the module of signals
   bool              InitIndicators(CIndicators *indicators);
   //--- Access to indicator data
   double            FastMA(const int index)             const { return(m_fast_ma.GetData(0,index)); }
   double            SlowMA(const int index)             const { return(m_slow_ma.GetData(0,index)); }

Come puoi vedere, i metodi sono molto semplici, hanno utilizzato il metodo GetData() della classe genitore SIndicator, che restituisce un valore dal buffer dell'indicatore specificato nella posizione specificata.

Se hai bisogno di classi per lavorare con gli indicatori classici del pacchetto standard, sono disponibili nella sezione Classi per lavorare con gli indicatori. Siamo pronti per procedere alla fase finale.


6. Definire i metodi LongCondition e ShortCondition

Tutto è pronto per far funzionare il nostro modulo e generare segnali di trading. Questa funzionalità è fornita da due metodi che devono essere descritti in ogni figlio di CExpertSignal:

  • LongCondition() - controlla le condizioni di acquisto e restituisce la forza del segnale Long da 0 a 100.
  • ShortCondition() - controlla la condizione di vendita e restituisce la forza del segnale Short da 0 a 100.

Se la funzione restituisce un valore nullo, significa che non c'è alcun segnale di trading. Se ci sono condizioni per il segnale, puoi stimare la potenza del segnale e restituire qualsiasi valore non superiore a 100. La valutazione della potenza del segnale consente di costruire in modo flessibile sistemi di trading basati su diversi moduli e modelli di mercato. Ulteriori informazioni su questo sono disponibili in MQL5 Wizard: Nuova Versione.

Poiché stiamo scrivendo un semplice modulo di segnali di trading, possiamo concordare che i segnali di acquisto e vendita sono valutati allo stesso modo (100). Aggiungiamo i metodi necessari nella dichiarazione della classe.

   ...
   bool              InitIndicators(CIndicators *indicators);
   //--- Access to data of the indicators
   double            FastMA(const int index)             const { return(m_fast_ma.GetData(0,index)); }
   double            SlowMA(const int index)             const { return(m_slow_ma.GetData(0,index)); }
   //--- Checking buy and sell conditions
   virtual int       LongCondition();
   virtual int       ShortCondition();

Inoltre, creiamo la descrizione delle funzioni. Ecco come viene controllato il segnale di acquisto (è lo stesso con il segnale di vendita):

//+------------------------------------------------------------------+
//| Returns the strength of the buy signal                           |
//+------------------------------------------------------------------+
int MA_Cross::LongCondition()
  {
   int signal=0;
//--- For operation with ticks idx=0, for operation with formed bars idx=1
   int idx=StartIndex();
//--- Values of MAs at the last formed bar
   double last_fast_value=FastMA(idx);
   double last_slow_value=SlowMA(idx);
//--- Values of MAs at the last but one formed bar
   double prev_fast_value=FastMA(idx+1);
   double prev_slow_value=SlowMA(idx+1);
//---If the fast MA crossed the slow MA from bottom upwards on the last two closed bars
   if((last_fast_value>last_slow_value) && (prev_fast_value<prev_slow_value))
     {
      signal=100; // There is a signal to buy
     }
//--- Return the signal value
   return(signal);
  }

Si noti che abbiamo dichiarato la variabile idx, a cui viene assegnato il valore restituito dalla funzione StartIndex() della classe genitore CExpertBase. La funzione StartIndex() restituisce 0, se Expert Advisor è progettato per funzionare su tutti i tick e, in questo caso, l'analisi inizia con la barra corrente. Se l'Expert Advisor è progettato per funzionare a prezzi open, StartIndex() restituisce 1 e l'analisi inizia con l'ultima barra formata.

Di default StartIndex() restituisce 1, il che significa che l'Expert Advisor generato da MQL5 Wizard verrà eseguito solo all'apertura di una nuova barra e ignorerà i tick in arrivo durante la formazione della barra corrente.

Come attivare questa modalità e come può essere utilizzata verrà descritto più avanti nei colpi finali.

Il modulo è pronto per l'uso, quindi creiamo un robot di trading in MQL5 Wizard basato su questo modulo.


Controllo di un Expert Advisor nel Tester

Per testare l'efficienza del nostro modulo, generiamo un Expert Advisor basato su di esso in MQL5 Wizard ed eseguiamolo sul grafico. Il tab "Inputs della finestra di avvio visualizzata contiene i parametri del modulo MA_Cross.

Tutti gli altri parametri sono stati aggiunti anche da MQL5 Wizard durante la generazione dell'EA in base al modulo di gestione del denaro selezionato e al modulo di mantenimento della posizione (Trailing Stop). Quindi, abbiamo solo dovuto scrivere un modulo di segnali di trading e abbiamo ricevuto una soluzione pronta. Questo è il vantaggio principale dell'utilizzo di MQL5 Wizard! 

Ora, testiamo il robot di trading nello Strategy Tester MetaTrader 5. Proviamo a eseguire una rapida ottimizzazione dei parametri chiave.

In queste impostazioni dei parametri di input, è necessario più di mezzo milione di passaggi per l'ottimizzazione completa. Pertanto, scegliamo ottimizzazione rapida (algoritmo genetico) e utilizziamo inoltre MQL5 Cloud Network per accelerare l'ottimizzazione. L'ottimizzazione è stata eseguita in 10 minuti e abbiamo ottenuto i risultati.


Come puoi vedere, la creazione di un robot di trading in MQL5 e l'ottimizzazione dei parametri di input hanno richiesto molto meno tempo di quanto sarebbe necessario per scrivere la logica di manutenzione della gestione della posizione, il debug e la ricerca dei migliori algoritmi. 


Colpo finale

Puoi saltare questo elemento o tornarci più tardi quando ti senti completamente a tuo agio con la tecnica di scrivere un modulo di segnali di trading.

Se apri il codice sorgente dell'Expert Advisor generato da MQL5 Wizard, troverai la variabile globale Expert_EveryTick con il valore falso. In base a questa variabile, la funzione StartIndex() restituisce il suo valore. Comunica all'Expert Advisor la modalità in cui dovrebbe funzionare.

//+------------------------------------------------------------------+
//|                                                 TestMA_Cross.mq5 |
//|                        Copyright 2012, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2012, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
//+------------------------------------------------------------------+
//| Include                                                          |
//+------------------------------------------------------------------+
#include <Expert\Expert.mqh>
//--- available signals
#include <Expert\MySignals\MA_Cross.mqh>
//--- available trailing
#include <Expert\Trailing\TrailingNone.mqh>
//--- available money management
#include <Expert\Money\MoneyFixedLot.mqh>
//+------------------------------------------------------------------+
//| Inputs                                                           |
//+------------------------------------------------------------------+
//--- inputs for expert
input string         Expert_Title             ="TestMA_Cross";  // Document name
ulong               Expert_MagicNumber       =22655;          // Expert Advisor ID
bool                  Expert_EveryTick             =false;          // Work of the EA inside the bar
//--- inputs for main signal
input int            Signal_ThresholdOpen     =10;             // Signal threshold value to open [0...100]
input int            Signal_ThresholdClose    =10;             // Signal threshold value to close [0...100]

Se imposti Expert_EveryTick true e compili il codice, il robot di trading analizzerà ogni tick in entrata e, quindi, prenderà decisioni sui valori ​dell'attuale barra incompleta. Fallo solo se capisci come funziona. Non tutti i sistemi di trading sono progettati per funzionare all'interno della barra.

Puoi anche aggiungere un input di parole chiave per il parametro Expert_EveryTick, quindi avrai un nuovo parametro di input dell'Expert Advisor, che puoi impostare all'avvio di EA su un grafico o nel tester:

input bool          Expert_EveryTick         =false;          // Work of the EA inside the bar

E ora è il momento di riassumere ciò che abbiamo fatto.


6 passaggi per Creare un Modulo di Segnali di Trading

Se hai padroneggiato MQL5, non hai più bisogno di scrivere un Expert Advisor da zero. Basta creare un modulo di segnali di trading e, sulla base di questo modulo, generare automaticamente un robot di trading con i moduli abilitati di trailing e di gestione del volume degli scambi. E anche se non hai familiarità con l'OOP o non vuoi approfondire molto la struttura delle classi di trading, puoi semplicemente seguire 6 passaggi:

  1. Crea una nuova classe utilizzando in MQL5 Wizard in una cartella separata MQL5/Include/MySignals/. Il nostro modulo di segnali di trading sarà memorizzato lì.
  2. Creare un handle del modulo che descriva i parametri, il loro tipo e i valori predefiniti.
  3. Dichiarare i parametri del modulo nella classe e aggiungere metodi per l'inizializzazione nel constructor.
  4. Controllare i parametri di input e non dimenticare di chiamare ValidationSettings() della classe base CExpertSignal.
  5. Crea oggetti-indicatore e aggiungi un metodo di inizializzazione predefinito InitIndicators().
  6. Identifica le condizioni dei segnali di trading nei metodi LongCondition() e ShortCondition().

Ogni passaggio è semplice e richiede poca abilità nella programmazione MQL5. Devi solo scrivere il tuo modulo una volta, seguendo le istruzioni, e un'ulteriore verifica di qualsiasi idea di trading non richiederà più di un'ora, senza stancanti ore di codifica e debug. 


Dal Semplice al Complesso

Ricorda che la strategia di trading implementata dal tuo robot di trading creata utilizzando il MQL5 Wizard, è complessa quanto il modulo di segnali di trading che utilizza. Tuttavia, prima di iniziare a costruire un sistema di trading complesso basato su una serie di regole per l'entrata e l'uscita, suddividilo in diversi sistemi semplici e controlla ciascuno separatamente.

Sulla base di moduli semplici puoi creare strategie di trading complesse utilizzando i moduli già pronti dei segnali di trading, ma questo è un argomento per un altro articolo!

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

File allegati |
testma_cross.mq5 (7.14 KB)
ma_cross.mqh (11.57 KB)
Algoritmi per Fare Soldi che Impiegano il Trailing Stop Algoritmi per Fare Soldi che Impiegano il Trailing Stop
L'obiettivo di questo articolo è studiare la redditività degli algoritmi con diverse entrate nei trade e nelle uscite utilizzando il trailing stop. I tipi di voce da utilizzare sono l'entrata casuale e l'entrata inversa. Gli ordini di stop da utilizzare sono trailing stop e trailing take. L'articolo dimostra algoritmi per fare soldi con una redditività di circa il 30% all'anno.
Sistemi di Trading Semplici che Utilizzano Indicatori Semaforici Sistemi di Trading Semplici che Utilizzano Indicatori Semaforici
Se esaminiamo nel dettaglio qualsiasi sistema di trading complesso, vedremo che si basa su una serie di semplici segnali di trading. Pertanto, non è necessario che gli sviluppatori alle prime armi inizino immediatamente a scrivere algoritmi complessi. Questo articolo fornisce un esempio di un sistema di trading che utilizza indicatori semaforici per eseguire operazioni.
Come Creare un Robot di Trading in Pochissimo Tempo Come Creare un Robot di Trading in Pochissimo Tempo
Il trading sui mercati finanziari comporta molti rischi, incluso il più critico: il rischio di prendere una decisione di trading sbagliata. Il sogno di ogni trader è quello di trovare un robot di trading, che sia sempre in buona forma e non soggetto alle debolezze umane: paura, avidità e impazienza.
Approccio Orientato agli Oggetti per la Creazione di Pannelli Multi-Timeframe e Multi-Valuta Approccio Orientato agli Oggetti per la Creazione di Pannelli Multi-Timeframe e Multi-Valuta
Questo articolo descrive come la programmazione orientata agli oggetti può essere utilizzata per la creazione di pannelli multi-timeframe e multi-valuta per MetaTrader 5. L'obiettivo principale è quello di costruire un pannello universale, che può essere utilizzato per visualizzare diversi tipi di dati, come prezzi, variazioni di prezzo, valori degli indicatori o condizioni di acquisto/vendita personalizzate senza la necessità di modificare il codice del pannello stesso.