English Русский 中文 Español Deutsch 日本語 Português 한국어 Français Türkçe
Il Wizard MQL5: Come creare un modulo di gestione del rischio e del denaro

Il Wizard MQL5: Come creare un modulo di gestione del rischio e del denaro

MetaTrader 5Sistemi di trading | 17 dicembre 2021, 14:59
94 0
MetaQuotes
MetaQuotes

Introduzione

MetaTrader 5 fornisce un potente strumento che ti consente di controllare rapidamente varie idee di trading. Questa è la generazione di Expert Advisor utilizzando il Wizard MQL5 sulla base di strategie di trading già pronte.

Un Expert Advisor creato con il MQL5 Wizard, si basa su quattro pilastri, ovvero quattro classi base:

Figura 1. La struttura della classe base CExpert

Figura 1. La struttura della classe base CExpert

  1. La classe CExpert (o la sua sottoclasse) è il "motore" principale di un Expert Advisor. Un'istanza di CExpert contiene una copia di ogni classe: CExpertSignal, CExpertMoney e CExpertTrailing (o le loro sottoclassi):
  2. CExpertSignal è la base del generatore di segnali di trading. Un'istanza della classe derivata CExpertSignal, inclusa in CExpert, fornisce a un Expert Advisor informazioni sulla possibilità di entrare nel mercato, i livelli di ingresso e l'immissione di ordini protettivi sulla base di algoritmi incorporati. L'Expert Advisor decide se entrare nel mercato. Maggiori dettagli sulla classe CExpertSignal e sull'utilizzo di essa sono descritti nell'articolo "Il Wizard MQL5: Come creare un modulo di segnali di trading".
  3. La classe CExpertMoney è alla base del meccanismo di gestione del rischio e del denaro. Un'istanza della classe derivata CExpertMoney, inclusa in CExpert, fornisce a un Expert Advisor informazioni sui possibili volumi per l'apertura di posizioni e l'immissione di ordini in sospeso sulla base di algoritmi integrati. L'Expert Advisor prende una decisione sul volume.
  4. La classe CExpertTrailing è alla base del meccanismo di supporto delle posizioni aperte. Un'istanza della classe derivata CExpertTrailing, inclusa in CExpert, fornisce a un EA informazioni sulla possibilità di modificare gli ordini di protezione della posizione sulla base di algoritmi incorporati. L'Expert Advisor prende una decisione sulla modifica degli ordini. Maggiori dettagli sulla classe CExpertTrailing e sul lavoro con essa verranno descritti in un articolo separato.

Inoltre, i membri della classe CExpert sono istanze delle seguenti classi:

  • CExpertTrade (per il trading)
  • CIndicators (per il controllo degli indicatori e delle serie temporali coinvolte nell'attività dell'EA).
  • CSymbolInfo (per ottenere informazioni sullo strumento)
  • CAccountInfo (per ottenere informazioni sullo stato del conto di trading)
  • CPositionInfo (per ottenere informazioni sulle posizioni)
  • COrderInfo (per ottenere informazioni sugli ordini in sospeso)

Di seguito, con il termine "expert" si indicherà un'istanza di CExpert o una sua sottoclasse.

Maggiori dettagli su CExpert e sul suo lavoro saranno descritti in un articolo separato.


1. Classe base CExpertMoney

Come accennato in precedenza, la classe CExpertMoney è alla base del meccanismo di gestione del rischio e del denaro. Per la comunicazione con il "mondo esterno", la classe CExpertMoney ha un insieme di metodi virtuali pubblici:

Inizializzazione

Descrizione

virtual Init

L'inizializzazione dell'istanza della classe fornisce la sincronizzazione dei dati del modulo con i dati dell'EA

Percent

Impostazione del valore del parametro "Percentuale di rischio"

virtual ValidationSettings

Convalida dei parametri impostati

virtual InitIndicators

Creazione e inizializzazione di tutti gli indicatori e delle serie temporali necessarie per il funzionamento del meccanismo di gestione del rischio e del denaro

Metodi per verificare la necessità di aprire/modificare/chiudere una posizione

 

virtual CheckOpenLong

Determinazione del volume per aprire una posizione long

virtual CheckOpenShort

Determinazione del volume per aprire una posizione short

virtual CheckReverse

Determinazione del volume per invertire una posizione

virtual CheckClose

Determinazione della necessità di chiudere una posizione


Descrizione dei metodi


1.1. Metodi di inizializzazione

1.1.1 Init

Il metodo Init() viene chiamato automaticamente subito dopo l'aggiunta di un'istanza di classe all'expert. L'override del metodo non è richiesto.

virtual bool Init(CSymbolInfo* symbol, ENUM_TIMEFRAMES period, double adjusted_point);

1.1.2 Percent

Il metodo Percent() viene chiamato per configurare il parametro appropriato. Il suo valore può essere compreso tra 0,0 e 100,0 inclusi. Il valore predefinito è 100,0. L'override del metodo non è richiesto.

void Percent(double percent);

1.1.3 ValidationSettings

Il metodo ValidationSettings() viene chiamato direttamente dall'expert dopo che tutti i parametri sono stati impostati. È necessario riscrivere il metodo se sono presenti parametri di configurazione aggiuntivi.

virtual bool ValidationSettings();

Il metodo riscritto deve restituire true se tutte le opzioni sono valide (utilizzabili). Se almeno uno dei parametri non è corretto, deve restituire false (ulteriori lavori sono impossibili). Il metodo riscritto deve chiamare il metodo della classe base con la verifica del risultato.

La classe base CExpertMoney ha il parametro Percent e, di conseguenza, il metodo della classe base, dopo aver eseguito la validazione del parametro, restituisce true se il valore rientra nell'intervallo consentito, altrimenti restituisce false.

1.1.4 InitIndicators

Il metodo InitIndicators() implementa la creazione e l'inizializzazione di tutti gli indicatori e le serie temporali necessarie. Viene chiamato dall'expert dopo che tutti i parametri sono stati impostati e la loro correttezza è stata verificata con successo. Il metodo deve essere ignorato se il meccanismo di gestione del rischio e del denaro utilizza almeno un indicatore o delle serie temporali.

virtual bool InitIndicators(CIndicators* indicators);

Gli indicatori e/o le serie temporali devono essere utilizzati attraverso le classi appropriate della Libreria Standard. I puntatori di tutti gli indicatori e/o le serie temporali dovrebbero essere aggiunti alla raccolta di indicatori di un expert (un puntatore al quale viene passato come parametro).

Il metodo riscritto deve restituire true se tutte le manipolazioni con gli indicatori e/o le serie temporali hanno avuto esito positivo (sono idonei per l'uso). Se almeno un'operazione con gli indicatori e/o le serie temporali fallisce, il metodo deve restituire false (impossibile eseguire ulteriori lavori).

La classe base CExpertMoney non utilizza indicatori o serie temporali, pertanto il metodo della classe base restituisce sempre true, senza eseguire alcuna azione.

1.2. Metodi per determinare il volume di una posizione

1.2.1 CheckOpenLong

Il metodo CheckOpenLong() calcola il volume per l'apertura di una posizione long. Viene chiamato da un expert per determinare il volume per l'apertura di una posizione long. Il metodo deve essere riscritto se si prevede di calcolare il volume di apertura della posizione long utilizzando l'algoritmo che differisce da quello implementato nella classe base.

\virtual double CheckOpenLong(double price, double sl);

Il metodo deve implementare l'algoritmo per il calcolo del volume per l'apertura di una posizione long. Il metodo deve restituire il volume calcolato.

La classe base CExpertMoney in realtà non ha un algoritmo integrato per calcolare il volume per l'apertura di posizioni long. Il metodo della classe base restituisce sempre il volume minimo possibile per uno strumento finanziario.

1.2.2 CheckOpenShort

Il metodo CheckOpenShort() calcola il volume per l'apertura di una posizione short. Viene chiamato da un expert per determinare il volume per l'apertura di una posizione short. Il metodo deve essere riscritto se si prevede di calcolare il volume di apertura della posizione short utilizzando l'algoritmo che differisce da quello implementato nella classe base. 

virtual double CheckOpenShort(double price, double sl);

Il metodo deve implementare l'algoritmo per il calcolo del volume per l'apertura di una posizione short. Il metodo deve restituire il volume calcolato.

La classe base CExpertMoney non ha un algoritmo integrato per il calcolo del volume per l'apertura di posizioni short. Il metodo della classe base restituisce sempre il volume minimo possibile per uno strumento finanziario.

1.2.3 CheckReverse

Il metodo CheckReverse() calcola il volume per invertire una posizione. Viene chiamato da un expert per determinare il volume di un'operazione di trading per l'inversione di una posizione. Il metodo deve essere riscritto se si prevede di calcolare il volume di inversione di posizione utilizzando l'algoritmo diverso da quello implementato nella classe base (es. inversione con doppio volume). 

virtual double CheckReverse(CPositionInfo* position, double sl);

Il metodo deve implementare l'algoritmo per il calcolo del volume per invertire una posizione le cui informazioni possono essere ottenute dal puntatore di posizione. Il metodo deve restituire il volume calcolato per l'inversione di posizione.

La classe base CExpertMoney possiede il seguente algoritmo per calcolare il volume per l'inversione della posizione, così da invertire la posizione in modo tale che il risultato sia una posizione opposta con il volume più piccolo possibile.

1.2.4 CheckClose

Il metodo CheckClose() verifica se è necessario chiudere una posizione (in termini di gestione del denaro e del rischio). Viene chiamato da un expert per determinare se è necessario chiudere una posizione. Il metodo deve essere scritto se si prevede di chiudere una posizione utilizzando un algoritmo diverso da quello implementato nella classe base (es. chiusura parziale). 

virtual double CheckClose(CPositionInfo* position);

Il metodo deve implementare l'algoritmo per definire la necessità di chiudere una posizione le cui informazioni possono essere ottenute dal puntatore di posizione. Il metodo deve restituire il volume calcolato per la chiusura della posizione.

CExpertMoney possiede il seguente algoritmo per determinare se è necessario chiudere la posizione: il metodo della classe base offre di chiudere completamente una posizione se la perdita corrente della posizione è maggiore della percentuale specificata del deposito.


2. Creare un meccanismo di gestione del denaro e del rischio

Adesso, dopo aver esaminato la struttura della classe base CExpertMoney, puoi iniziare a creare il tuo meccanismo di gestione del rischio e del denaro. Da qui in poi il meccanismo di gestione del rischio e del denaro sarà denominato "money-manager".

Come accennato in precedenza, la classe CExpertMoney è un insieme di "ropes" virtuali pubbliche, ovvero metodi attraverso il cui uso l'expert può conoscere l'opinione del gestore del denaro sul volume del mercato che entra in una direzione o nell'altra.

Pertanto, il nostro obiettivo primario è creare la nostra classe del money-manager, derivandola dalla classe CExpertMoney e riscrivendo i metodi virtuali appropriati, implementando gli algoritmi richiesti.

Il nostro secondo problema (che non è meno importante) è rendere la nostra classe "visibile" al Wizard MQL5. Ma andiamo con ordine.

2.1. Creare la classe del generatore di segnali di trading

Cominciamo.

Wizard MQL5) un file include con l'estensione mqh.

Vai su File e seleziona "Create" (o digita Ctrl+N) e indica la creazione di un file include:

Figura 2. Creare un file include utilizzando il Wizard MQL5 Wizard

Figura 2. Crea un file di inclusione utilizzando il Wizard MQL5

Da notare che affinché il file venga poi "rilevato" dal Wizard MQL5 come money-manager, deve essere creato nella cartella Include\Expert.

Per non cestinarlo nella Libreria Standard, creiamo la nostra cartella Include\Expert\Money\MyMoneys, nella quale creiamo il file SampleMoney.mqh specificando questi parametri nel Wizard MQL5:

Figura 3. Impostare la posizione del file include

Figura 3. Impostare la posizione del file include

Come risultato dell'operazione Wizard MQL5 abbiamo il seguente schema:

//+------------------------------------------------------------------+
//|                                                  SampleMoney.mqh |
//|                        Copyright 2010, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2010, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
//+------------------------------------------------------------------+
//| defines                                                          |
//+------------------------------------------------------------------+
// #define MacrosHello   "Hello, world!"
// #define MacrosYear    2010
//+------------------------------------------------------------------+
//| DLL imports                                                      |
//+------------------------------------------------------------------+
// #import "user32.dll"
//   int      SendMessageA(int hWnd,int Msg,int wParam,int lParam);
// #import "my_expert.dll"
//   int      ExpertRecalculate(int wParam,int lParam);
// #import
//+------------------------------------------------------------------+
//| EX5 imports                                                      |
//+------------------------------------------------------------------+
// #import "stdlib.ex5"
//   string ErrorDescription(int error_code);
// #import
//+------------------------------------------------------------------+

Quello che segue è soltanto un lavoro da svolgere "manualmente". Rimuovi le parti non necessarie e aggiungere ciò che ti occorre: il file include ExpertMoney.mqh della Libreria Standard con una descrizione della classe vuota.

//+------------------------------------------------------------------+
//|                                                  SampleMoney.mqh |
//|                        Copyright 2010, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2010, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
//+------------------------------------------------------------------+
//| Include files                                                    |
//+------------------------------------------------------------------+
#include <Expert\ExpertMoney.mqh>
//+------------------------------------------------------------------+
//| Class CSampleMoney.                                              |
//| Purpose: Class for risk and money management.                    |
//|             It is derived from the CExpertMoney class.           |
//+------------------------------------------------------------------+
class CSampleMoney : public CExpertMoney
  {
  };
//+------------------------------------------------------------------+

Ora è necessario scegliere gli algoritmi.

Come base per il nostro money manager prendiamo il seguente algoritmo: In condizioni "normali" si propone di utilizzare un volume di operazioni fisso e predeterminato. Ma se la posizione precedente è stata chiusa con una perdita, si propone di aprire una posizione con un volume raddoppiato.

Rifletti ciò nel nostro file.

//+------------------------------------------------------------------+
//|                                                  SampleMoney.mqh |
//|                        Copyright 2010, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2010, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
//+------------------------------------------------------------------+
//| Include files                                                    |
//+------------------------------------------------------------------+
#include <Expert\ExpertMoney.mqh>
//+------------------------------------------------------------------+
//| Class CSampleMoney.                                              |
//| Purpose: Class for risk and money management                     |
//|             doubling the volume after a loss deal.               |
//|             It is derived from the CExpertMoney class.           |
//+------------------------------------------------------------------+
class CSampleMoney : public CExpertMoney
  {
  };
//+------------------------------------------------------------------+

Definisci un elenco di impostazioni per il nostro money-manager. In realtà, non ci sarà nessun elenco. Tutte le impostazioni sono incluse in un unico parametro che determinerà il volume di una transazione in condizioni "normali".

Il parametro verrà archiviato in un membro dati protetto della classe. L'accesso al parametro sarà implementato attraverso un apposito metodo pubblico. Nel costruttore della classe, il parametro verrà inizializzato da un valore predefinito. Per controllare i parametri, riscriviamo il metodo virtuale ValidationSettings secondo la descrizione della classe base.

Includiamo queste modifiche nel nostro file:

//+------------------------------------------------------------------+
//|                                                  SampleMoney.mqh |
//|                        Copyright 2010, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2010, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
//+------------------------------------------------------------------+
//| Include files                                                    |
//+------------------------------------------------------------------+
#include <Expert\ExpertMoney.mqh>
//+------------------------------------------------------------------+
//| Class CSampleMoney.                                              |
//| Purpose: Class for risk and money management                     |
//|             doubling the volume after a loss deal.               |
//|             It is derived from the CExpertMoney class.           |
//+------------------------------------------------------------------+
class CSampleMoney : public CExpertMoney
  {
protected:
   //--- setup parameters
   double            m_lots;   // deal volume for "normal" conditions

public:
                     CSampleMoney();
   //--- methods to set the parameters
   void              Lots(double lots) { m_lots=lots; }
  };
//+------------------------------------------------------------------+
//| Constructor CSampleMoney.                                        |
//| INPUT:  no.                                                      |
//| OUTPUT: no.                                                      |
//| REMARK: no.                                                      |
//+------------------------------------------------------------------+
void CSampleMoney::CSampleMoney()
  {
//--- setting the default values
   m_lots=0.1;
  }
//+------------------------------------------------------------------+

Separatamente, consideriamo come implementare il metodo ValidationSettings(). Il punto è che la classe base ha già un parametro di configurazione, che richiede anche la verifica.

Pertanto, nel metodo sovrascritto ValidationSettings(), dobbiamo chiamare ValidationSettings() della classe base con il controllo dei risultati dell'esecuzione.

Implementazione del metodo ValidationSettings():

//+------------------------------------------------------------------+
//| Validation of the setup parameters.                              |
//| INPUT:  no.                                                      |
//| OUTPUT: true if the settings are correct, otherwise false.       |
//| REMARK: no.                                                      |
//+------------------------------------------------------------------+
bool CSampleMoney::ValidationSettings()
  {
//--- Call the base class method
   if(!CExpertMoney::ValidationSettings()) return(false);
//--- Validation of parameters
   if(m_lots<m_symbol.LotsMin() || m_lots>m_symbol.LotsMax())
     {
      printf(__FUNCTION__+": the deal volume must be in the range %f to %f",m_symbol.LotsMin(),m_symbol.LotsMax());
      return(false);
     }
   if(MathAbs(m_lots/m_symbol.LotsStep()-MathRound(m_lots/m_symbol.LotsStep()))>1.0E-10)
     {
      printf(__FUNCTION__+": the volume of the deal must be multiple of %f",m_symbol.LotsStep());
      return(false);
     }
//--- Successful completion
   return(true);
  }

Le impostazioni sono pronte. Adesso procediamo con il funzionamento del money manager. Abbiamo bisogno di un metodo che determina se l'operazione precedente era perdente e, se necessario, ne definisce il volume. Dichiaralo nella descrizione della classe:

class CSampleMoney : public CExpertMoney
  {
protected:
   //--- Setup parameters
   double            m_lots;  // deal volume for "normal" conditions

public:
                    CSampleMoney();
   //--- Methods to set parameters
   void             Lots(double lots) { m_lots=lots; }
   //--- Methods to validate parameters
   virtual bool      ValidationSettings();

protected:
   double            CheckPrevLoss();
  };

Implementazione del metodo:

//+------------------------------------------------------------------+
//| Defines whether the prev. deal was losing.                       |
//| INPUT:  no.                                                      |
//| OUTPUT: volume of the prev. deal if it's losing, otherwise 0.0   |
//| REMARK: no.                                                      |
//+------------------------------------------------------------------+
double CSampleMoney::CheckPrevLoss()
  {
   double lot=0.0;
//--- Request the history of deals and orders
   HistorySelect(0,TimeCurrent());
//--- variables
   int       deals=HistoryDealsTotal();  // Total number of deals in the history
   CDealInfo deal;
//--- Find the previous deal
   for(int i=deals-1;i>=0;i--)
     {
      if(!deal.SelectByIndex(i))
        {
         printf(__FUNCTION__+": Error of deal selection by index");
         break;
        }
      //--- Check the symbol
      if(deal.Symbol()!=m_symbol.Name()) continue;
      //--- Check the profit
      if(deal.Profit()<0.0) lot=deal.Volume();
      break;
     }
//--- Return the volume
   return(lot);
  }

Consideriamo di nuovo i nostri algoritmi in modo più dettagliato (sebbene sia già dettagliato).

Senza entrare nei dettagli, notiamo che il nostro money manager proporrà di aumentare il volume di un operazione al ricevimento della perdita nell'operazione precedente. Se non ci sono state perdite nell'operazione precedente, offriremo l'apertura di una posizione con un volume fisso, definito da un determinato parametro.

A tal fine, riscriviamo i metodi virtuali CheckOpenLong e CheckOpenShort, compilandoli con le funzionalità corrispondenti.

Descrizione della classe:

//+------------------------------------------------------------------+
//| Class CSampleMoney.                                              |
//| Purpose: Class for risk and money management                     |
//|             doubling the volume after a loss deal.               |
//|             It is derived from the CExpertMoney class.           |
//+------------------------------------------------------------------+
class CSampleMoney : public CExpertMoney
  {
protected:
   //--- Setup parameters
   double            m_lots;  // Deal volume for "normal" conditions

public:
                    CSampleMoney();
   //--- Methods to set the parameters
   void             Lots(double lots) { m_lots=lots; }
   //--- Methods to validate the parameters
   virtual bool      ValidationSettings();
   //--- Methods to define the volume
   virtual double    CheckOpenLong(double price,double sl);
   virtual double    CheckOpenShort(double price,double sl);

protected:
   double            CheckPrevLoss();
  };

Le implementazioni di CheckOpenLong e CheckOpenShort sono praticamente identiche. Entrambi i metodi determinano la necessità di aumentare il volume chiamando il metodo CheckPrevLoss implementato in precedenza.

Successivamente dobbiamo tenere conto del fatto che non possiamo aumentare il volume degli scambi indefinitamente. Ci sono due limitazioni al volume della posizione:

  1. Il volume massimo per un'operazione per il simbolo, specificato nelle impostazioni del server (SYMBOL_VOLUME_MAX).
  2. Disponibilità dell'importo richiesto di fondi gratuiti sul deposito.

Implementazione dei metodi CheckOpenLong e CheckOpenShort:

//+------------------------------------------------------------------+
//| Defining the volume to open a long position.                     |
//| INPUT:  no.                                                      |
//| OUTPUT: lot-if successful, 0.0 otherwise.                        |
//| REMARK: not.                                                     |
//+------------------------------------------------------------------+
double CSampleMoney::CheckOpenLong(double price,double sl)
  {
   if(m_symbol==NULL) return(0.0);
//--- Select the lot size
   double lot=2*CheckPrevLoss();
   if(lot==0.0) lot=m_lots;
//--- Check the limits
   double maxvol=m_symbol.LotsMax();
   if(lot>maxvol) lot=maxvol;
//--- Check the margin requirements
   if(price==0.0) price=m_symbol.Ask();
   maxvol=m_account.MaxLotCheck(m_symbol.Name(),ORDER_TYPE_BUY,price,m_percent);
   if(lot>maxvol) lot=maxvol;
//--- Return the trade volume
   return(lot);
  }
//+------------------------------------------------------------------+
//| Defining the volume to open a short position.                    |
//| INPUT:  no.                                                      |
//| OUTPUT: lot-if successful, 0.0 otherwise.                        |
//| REMARK: no.                                                      |
//+------------------------------------------------------------------+
double CSampleMoney::CheckOpenShort(double price,double sl)
  {
   if(m_symbol==NULL) return(0.0);
//--- Select the lot size
   double lot=2*CheckPrevLoss();
   if(lot==0.0) lot=m_lots;
//--- Check the limits
   double maxvol=m_symbol.LotsMax();
   if(lot>maxvol) lot=maxvol;
//--- Check the margin requirements
   if(price==0.0) price=m_symbol.Bid();
   maxvol=m_account.MaxLotCheck(m_symbol.Name(),ORDER_TYPE_SELL,price,m_percent);
   if(lot>maxvol) lot=maxvol;
//--- Return the trade volume
   return(lot);
  }

Quindi abbiamo risolto il primo problema. Il codice sopra è un "codice sorgente" della classe money manager che soddisfa il nostro compito principale.


2.2. Creazione di una descrizione della classe money manager generata per la procedura guidata MQL5

Passiamo ora alla risoluzione del secondo problema. Il nostro money manager dovrebbe essere "riconosciuto" dal generatore di strategie di trading del Wizard MQL5.

Abbiamo soddisfatto la prima condizione necessaria: abbiamo posizionato il file dove verrà "trovato" dal Wizard MQL5. Ma ciò non è sufficiente. La procedura guidata MQL5 non deve solo "trovare" il file, ma anche "riconoscerlo". Per fare ciò dobbiamo aggiungere al testo originale il descrittore di classe per il Wizard MQL5.

Un descrittore di classe è un blocco di commenti composto secondo determinate regole.

Prendiamo in considerazione queste regole.

1. Il blocco di commenti deve iniziare con le seguenti righe:

// wizard description start
//+------------------------------------------------------------------+
//| Description of the class                                         |

2. La riga successiva è un descrittore di testo (ciò che vedremo nel Wizard MQL5 quando si sceglie il segnale) nel formato "//| Title=<Text> |". Se il testo è troppo grande per una riga, dopo di quest’ultima puoi aggiungere un'altra riga (ma non di più). 

Nel nostro caso abbiamo quanto segue:

//| Title=Trade with a doubling of lot after a loss                  |

3. Quindi arriva una riga con il tipo di classe specificato nel formato "//| Type=<Type> |". Il campo <Type> deve avere il valore Money (oltre ai money manager, il Wizard MQL5 conosce altri tipi di classi).

Scrivi:

//| Type=Money                                                       |

4. La riga seguente nel formato "//| Name=<Name> |" è il nome breve del segnale (viene utilizzato dal Wizard MQL5 per generare i nomi delle variabili globali dell'expert).

Otteniamo quanto segue:

//| Name=Sample                                                      |

5. Il nome di una classe è un elemento importante della descrizione. Nella riga con il formato "//| Class=<ClassNameа> |", il parametro <ClassName> deve corrispondere al nome della nostra classe:

//| Class=CSampleMoney                                               |

6. Non compiliamo questa riga, ma deve essere presente (questo è un collegamento alla sezione di riferimento del linguaggio):

//| Page=                                                            |

7. Inoltre, ci sono le descrizioni dei parametri di configurazione del segnale.

Questo è un insieme di righe (il numero di righe è uguale al numero di parametri).

Il formato di ogni riga è "//| Parameter=<NameOfMethod>,<TypeOfParameter>,<DefaultValue> |".

Ecco il nostro set di parametri:

//| Parameter=Lots,double,0.1                                        |
//| Parameter=Percent,double,100.0                                   |

8. Il blocco di commento deve terminare con le seguenti righe:

//+------------------------------------------------------------------+
// wizard description end

2-7 Dobbiamo dare ulteriori spiegazioni ai punti 2-7. Le sezioni del descrittore di classe contengono parole chiave (Title, Type, Name, Class, Page, Parameter). Sfortunatamente, Wizard MQL5 non può interpretare tutte le possibili combinazioni di caratteri come parte della descrizione della classe.

Pertanto, per evitare errori non necessari, scrivilo in questo modo:
[Slash][Slash][VerticalLine][Space]<Keyword>[EqualitySign]<Description>;

<Description> può contenere spazi solo per la parola chiave Title. I paragrafi 1 e 8 devono essere copiati "così come sono".

Il descrittore di classe (prima riga) deve essere trovato nel file entro e non oltre la 20^ riga.

Aggiungiamo il descrittore al codice sorgente.

//+------------------------------------------------------------------+
//|                                                  SampleMoney.mqh |
//|                        Copyright 2010, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2010, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
//+------------------------------------------------------------------+
//| Include files                                                    |
//+------------------------------------------------------------------+
#include <Expert\ExpertMoney.mqh>
#include <Trade\DealInfo.mqh>
// wizard description start
//+------------------------------------------------------------------+
//| Description of the class                                         |
//| Title=Trading with lot doubling after a loss                     |
//| Type=Money                                                       |
//| Name=Sample                                                      |
//| Class=CSampleMoney                                               |
//| Page=                                                            |
//| Parameter=Lots,double,0.1                                        |
//| Parameter=Percent,double,100.0                                   |
//+------------------------------------------------------------------+
// wizard description end
//+------------------------------------------------------------------+
//| Class CSampleMoney.                                              |
//| Purpose: Class for risk and money management                     |
//|             doubling the volume after a loss deal.               |
//|             It is derived from the CExpertMoney class.           |
//+------------------------------------------------------------------+
class CSampleMoney : public CExpertMoney
  {
protected:
   //--- Setup parameters
   double            m_lots;  // Deal volume for "normal" conditions

public:
                     CSampleMoney();
   //--- Methods to set the parameters
   void              Lots(double lots) { m_lots=lots; }
   //--- Methods to validate the parameters
   virtual bool      ValidationSettings();
   //--- Methods to define the volume
   virtual double    CheckOpenLong(double price,double sl);
   virtual double    CheckOpenShort(double price,double sl);

protected:
   double            CheckPrevLoss();
  };
//+------------------------------------------------------------------+
//| Constructor CSampleMoney.                                        |
//| INPUT:  no.                                                      |
//| OUTPUT: no.                                                      |
//| REMARK: no.                                                      |
//+------------------------------------------------------------------+
void CSampleMoney::CSampleMoney()
  {
//--- Setting default values
   m_lots=0.1;
  }
//+------------------------------------------------------------------+
//| Validation of the setup parameters.                              |
//| INPUT:  no.                                                      |
//| OUTPUT: true if the settings are correct, otherwise false.       |
//| REMARK: no.                                                      |
//+------------------------------------------------------------------+
bool CSampleMoney::ValidationSettings()
  {
//--- Call the base class method
   if(!CExpertMoney::ValidationSettings()) return(false);
//--- Validating the parameters
   if(m_lots<m_symbol.LotsMin() || m_lots>m_symbol.LotsMax())
     {
      printf(__FUNCTION__+": The deal volume must be in the range %f to %f",m_symbol.LotsMin(),m_symbol.LotsMax());
      return(false);
     }
   if(MathAbs(m_lots/m_symbol.LotsStep()-MathRound(m_lots/m_symbol.LotsStep()))>1.0E-10)
     {
      printf(__FUNCTION__+": The deal volume must be multiple of  %f",m_symbol.LotsStep());
      return(false);
     }
//--- Successful completion
   return(true);
  }
//+------------------------------------------------------------------+
//| Defining the volume to open a long position.                     |
//| INPUT:  no.                                                      |
//| OUTPUT: lot-if successful, 0.0 otherwise.                        |
//| REMARK: no.                                                      |
//+------------------------------------------------------------------+
double CSampleMoney::CheckOpenLong(double price,double sl)
  {
   if(m_symbol==NULL) return(0.0);
//--- Select the lot size
   double lot=2*CheckPrevLoss();
   if(lot==0.0) lot=m_lots;
//--- Check the limits
   double maxvol=m_symbol.LotsMax();
   if(lot>maxvol) lot=maxvol;
//--- Check the margin requirements
   if(price==0.0) price=m_symbol.Ask();
   maxvol=m_account.MaxLotCheck(m_symbol.Name(),ORDER_TYPE_BUY,price,m_percent);
   if(lot>maxvol) lot=maxvol;
//--- Return the trade volume
   return(lot);
  }
//+------------------------------------------------------------------+
//|Defining the volume to open a short position.                     |
//| INPUT:  no.                                                      |
//| OUTPUT: lot-if successful, 0.0 otherwise.                        |
//| REMARK: no.                                                      |
//+------------------------------------------------------------------+
double CSampleMoney::CheckOpenShort(double price,double sl)
  {
   if(m_symbol==NULL) return(0.0);
//--- Select the lot size
   double lot=2*CheckPrevLoss();
   if(lot==0.0) lot=m_lots;
//--- Check the limits
   double maxvol=m_symbol.LotsMax();
   if(lot>maxvol) lot=maxvol;
//--- Check the margin requirements
   if(price==0.0) price=m_symbol.Bid();
   maxvol=m_account.MaxLotCheck(m_symbol.Name(),ORDER_TYPE_SELL,price,m_percent);
   if(lot>maxvol) lot=maxvol;
//--- Return the trade volume
   return(lot);
  }
//+------------------------------------------------------------------+
//| Defines whether the prev. deal was losing.                       |
//| INPUT:  no.                                                      |
//| OUTPUT: Volume of the prev. deal if it's losing, otherwise 0.0   |
//| REMARK: no.                                                      |
//+------------------------------------------------------------------+
double CSampleMoney::CheckPrevLoss()
  {
   double lot=0.0;
//--- Request the history of deals and orders
   HistorySelect(0,TimeCurrent());
//--- variables
   int       deals=HistoryDealsTotal();  // Total number of deals in the history
   CDealInfo deal;
//--- Find the previous deal
   for(int i=deals-1;i>=0;i--)
     {
      if(!deal.SelectByIndex(i))
        {
         printf(__FUNCTION__+": Error of deal selection by index");
         break;
        }
      //--- Check the symbol
      if(deal.Symbol()!=m_symbol.Name()) continue;
      //---Check the profit
      if(deal.Profit()<0.0) lot=deal.Volume();
      break;
     }
//--- Return the volume
   return(lot);
  }
//+------------------------------------------------------------------+

Bene, questo è tutto. Il gestore di denaro è pronto per l'uso.

Affinché il generatore di strategie di trading del Wizard MQL5 sia in grado di utilizzare il nostro money manager, dobbiamo riavviare MetaEditor (il Wizard MQL5 scansiona la cartella Include\Expert solo all'avvio).

Dopo aver riavviato MetaEditor, il modulo money manager creato può essere utilizzato nel Wizard MQL5:

Figura 5. Il money manager creato nel Wizard MQL5

Figura 5. Il money manager creato nel Wizard MQL5

Sono ora disponibili i parametri di input specificati nella sezione di descrizione dei parametri money manager:

Figura 6. Parametri di input del money manager creato nel Wizard MQL5

Figura 6. Parametri di input del money manager creato nel Wizard MQL5

I migliori valori dei parametri di input della strategia di trading implementata possono essere trovati utilizzando lo Strategy Tester del MetaTrader 5.

La Figura 7 mostra i risultati dei test dell'Expert Advisor che opera secondo questo sistema di gestione del denaro (EURUSD H1, il periodo di test: 01.01.2010-05.01.2011).

Figura 7. I risultati del test sulla cronologia della strategia con il modulo Money Management con raddoppio dopo una perdita

Figura 7. I risultati dei test sulla cronologia della strategia con il modulo di gestione del denaro con un raddoppio dopo una perdita

Durante la creazione di un Expert Advisor, abbiamo utilizzato il modulo dei segnali di trading implementato nell'articolo "Il Wizard MQL5: Come creare un modulo di segnali di trading". I parametri dell'Expert Advisor: (PeriodMA=12, ShiftMA=0, MethodMA=MODE_EMA, AppliedMA=PRICE_CLOSE, Limit=-70, StopLoss=145, TakeProfit=430, Expiration=10, Lots=0.1, Percent=100).


Conclusione

Il generatore di strategie di trading del Wizard MQL5 semplifica enormemente il test delle idee di trading. Il codice dell'expert generato si basa sulle classi di strategie di trading della Libreria Standard che vengono utilizzate per creare determinate implementazioni di classi di segnali di trading, classi di gestione del denaro e del rischio e classi di supporto della posizione. 

L'articolo descrive come sviluppare un modulo personalizzato di gestione del rischio e del denaro e abilitarlo nella procedura guidata MQL5. Ad esempio, abbiamo considerato un algoritmo di gestione del denaro in cui la dimensione del volume degli scambi è determinata dai risultati dell'operazione precedente. Vengono inoltre descritti la struttura e il formato della descrizione della classe creata per il Wizard MQL5.

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

File allegati |
samplemoney.mqh (7.15 KB)
Il Wizard MQL5: Come creare un modulo di segnali di trading Il Wizard MQL5: Come creare un modulo di segnali di trading
L'articolo parla di come scrivere la propria classe di segnali di trading con l'implementazione dei segnali sull'incrocio del prezzo e della media mobile e come includerla nel generatore di strategie di trading del Wizard MQL5, oltre a descriverne la struttura e il formato della descrizione della classe generata per la procedura guidata MQL5.
Wizard MQL5: Come creare un modulo di trailing delle posizioni aperte Wizard MQL5: Come creare un modulo di trailing delle posizioni aperte
Il generatore di strategie di trading del Wizard MQL5 semplifica enormemente la verifica delle idee di trading. L'articolo parla di come scrivere e connettere al generatore di strategie di trading Wizard MQL5 la tua classe di gestione delle posizioni aperte spostando il livello di Stop Loss in una zona senza perdite quando il prezzo va nella direzione della posizione, consentendo di proteggere i tuoi drawdown di diminuzione del profitto quando fai trading. Descrive anche la struttura e il formato della descrizione della classe creata per il Wizard MQL5.
Approccio econometrico all'analisi dei grafici Approccio econometrico all'analisi dei grafici
Questo articolo descrive in particolare i metodi econometrici di analisi, l'analisi di autocorrelazione e l'analisi della varianza condizionale. Qual è il vantaggio dell'approccio qui descritto? L'uso dei modelli GARCH non lineari consente di rappresentare formalmente la serie analizzata dal punto di vista matematico e di creare una previsione per un numero specificato di passaggi.
Gli indicatori dei trend micro, medie e principali Gli indicatori dei trend micro, medie e principali
Lo scopo di questo articolo è indagare le possibilità del trading e dell'analisi sulla base di alcune idee tratte dal libro di James Hyerczyk "Pattern, Price & Time: Using Gann Theory in Trading Systems" sotto forma di indicatori ed Expert Advisor. Senza pretendere di essere esaustivi, qui indagheremo solo il Modello, la prima parte della teoria di Gann.