English Русский 中文 Español Deutsch 日本語 Português 한국어 Français Türkçe
Sistemi di Trading Semplici che Utilizzano Indicatori Semaforici

Sistemi di Trading Semplici che Utilizzano Indicatori Semaforici

MetaTrader 5Sistemi di trading | 9 dicembre 2021, 14:21
152 0
Nikolay Kositsin
Nikolay Kositsin

Introduzione

Gli indicatori semaforici o di segnali sono semplici rilevatori che indicano i momenti di entrata o di uscita dal mercato. Nel caso in cui vi sia un segnale di entrata sulla barra corrente, un'etichetta appropriata viene visualizzata su un grafico a simboli. Questa etichetta può, quindi, essere utilizzata come condizione per l'esecuzione di un’operazione.

Ci sono molti indicatori di questo tipo, ma l'essenza stessa del sistema di trading originale basato su tali indicatori non è cambiata affatto. Pertanto, è una buona idea implementarlo nella forma più semplice e universale. Ciò consentirà un ulteriore utilizzo del risultato ottenuto quando si lavora con indicatori simili senza notevoli alterazioni.

Fig.1. Indicatore di segnale semaforico ASCtrend

Fig.1. Indicatore di segnale semaforico ASCtrend

Fig.2. Indicatore ASCtrend. Segnale di trading per l'esecuzione di un’operazione 

Fig.2. Segnale di trading per l'esecuzione di un’operazione utilizzando l'indicatore di segnale semaforico ASCtrend


Esempi di Tipici Indicatori di Segnale Semaforico

Attualmente, ci sono molti di questi indicatori in Code Base. In questo articolo, fornirò solo alcuni link alle pagine web corrispondenti:

Oltre agli indicatori di segnale semaforico, esiste un gruppo di indicatori di tendenza semaforico:

Fig.3. Segnali di trading che usano l'indicatore Heiken_Ashi_Smoothed 

Fig.3. Indicatore di tendenza semaforico

 

Fig.4. Segnale di trading per l'esecuzione di un deal utilizzando l'indicatore di tendenza semaforico Heiken Ashi Smoothed

Fig.4. Segnale di trading per l'esecuzione di un’operazione utilizzando l'indicatore di tendenza semaforico Heiken Ashi Smoothed

I sistemi di trading che utilizzano tali indicatori hanno un codice leggermente diverso per ottenere segnali di trading, mentre il codice dell’Expert Advisor rimane quasi invariato.

Esempi di tipici indicatori semaforici di tendenza

Code Base contiene molti di questi indicatori. In questo articolo, fornirò solo alcuni link alle pagine web corrispondenti:

 

Dati di Base per la Creazione di un Sistema di Trading:

  1. Indicatore semaforico con i parametri di input che devono essere presenti nell'Expert Advisor;
  2. L'elenco dei parametri di trading di Expert Advisor di input aggiuntivi:
    • una quota delle risorse finanziarie di deposito utilizzate in un’operazione;
    • una dimensione di Stop Loss e Take Profit (gli ordini in sospeso non devono essere utilizzati in caso di valori zero);
    • slippage (differenza massima ammissibile tra i prezzi delle operazioni impostati ed effettivi);
    • indice della barra, da cui verranno ricevuti i segnali di trading;
    • autorizzazioni per l'apertura di posizioni lunghe e corte;
    • autorizzazioni per la chiusura forzata di posizioni lunghe e corte in base ai segnali degli indicatori.

Naturalmente, sarebbe molto più conveniente dare ordini per eseguire operazioni utilizzando funzioni di trading universali. Queste funzioni sono piuttosto complesse e dovrebbero essere racchiuse in un file di libreria specifico per rendere il codice dell'applicazione il più semplice possibile.

Il codice dell'Expert Advisor che implementa il sistema di trading semaforico:

//+------------------------------------------------------------------+
//|                                                 Exp_ASCtrend.mq5 |
//|                             Copyright © 2011,   Nikolay Kositsin | 
//|                              Khabarovsk,   farria@mail.redcom.ru | 
//+------------------------------------------------------------------+
#property copyright "Copyright © 2011, Nikolay Kositsin"
#property link      "farria@mail.redcom.ru"
#property version   "1.00"
//+----------------------------------------------+
//| Expert Advisor indicator input parameters    |
//+----------------------------------------------+
input double MM=-0.1;             // Share of a deposit in a deal, negative values - lot size
input int    StopLoss_=1000;      // Stop loss in points
input int    TakeProfit_=2000;    // Take profit in points
input int    Deviation_=10;       // Max. price deviation in points
input bool   BuyPosOpen=true;     // Permission to buy
input bool   SellPosOpen=true;    // Permission to sell
input bool   BuyPosClose=true;    // Permission to exit long positions
input bool   SellPosClose=true;   // Permission to exit short positions
//+----------------------------------------------+
//| ASCtrend indicator input parameters          |
//+----------------------------------------------+
input ENUM_TIMEFRAMES InpInd_Timeframe=PERIOD_H1; // ASCtrend indicator time frame
input int  RISK=4;                               // Risk level
input uint SignalBar=1;                          // Bar index for getting an entry signal
//+----------------------------------------------+

int TimeShiftSec;
//---- declaration of integer variables for the indicators handles
int InpInd_Handle;
//---- declaration of integer variables of the start of data calculation
int min_rates_total;
//+------------------------------------------------------------------+
//| Trading algorithms                                               | 
//+------------------------------------------------------------------+
#include <TradeAlgorithms.mqh>
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---- getting ASCtrend indicator handle
   InpInd_Handle=iCustom(Symbol(),InpInd_Timeframe,"ASCtrend",RISK);
   if(InpInd_Handle==INVALID_HANDLE) Print(" Failed to get handle of ASCtrend indicator");

//---- initialization of a variable for storing a chart period in seconds  
   TimeShiftSec=PeriodSeconds(InpInd_Timeframe);

//---- initialization of variables of the start of data calculation
   min_rates_total=int(3+RISK*2+SignalBar);
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//----
   GlobalVariableDel_(Symbol());
//----
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---- checking the number of bars to be enough for calculation
   if(BarsCalculated(InpInd_Handle)<min_rates_total) return;
   
//---- uploading history for IsNewBar() and SeriesInfoInteger() functions normal operation  
   LoadHistory(TimeCurrent()-PeriodSeconds(InpInd_Timeframe)-1,Symbol(),InpInd_Timeframe);

//---- declaration of local variables
   double DnVelue[1],UpVelue[1];
//---- declaration of static variables
   static bool Recount=true;
   static bool BUY_Open=false,BUY_Close=false;
   static bool SELL_Open=false,SELL_Close=false;
   static datetime UpSignalTime,DnSignalTime;
   static CIsNewBar NB;

//+----------------------------------------------+
//| Searching for deals performing signals       |
//+----------------------------------------------+
   if(!SignalBar || NB.IsNewBar(Symbol(),InpInd_Timeframe) || Recount) // checking for a new bar
     {
      //---- zeroing out trading signals
      BUY_Open=false;
      SELL_Open=false;
      BUY_Close=false;
      SELL_Close=false;
      Recount=false;

      //---- copy newly appeared data into the arrays
      if(CopyBuffer(InpInd_Handle,1,SignalBar,1,UpVelue)<=0) {Recount=true; return;}
      if(CopyBuffer(InpInd_Handle,0,SignalBar,1,DnVelue)<=0) {Recount=true; return;}

      //---- getting buy signals
      if(UpVelue[0] && UpVelue[0]!=EMPTY_VALUE)
        {
         if(BuyPosOpen) BUY_Open=true;
         if(SellPosClose) SELL_Close=true;
         UpSignalTime=datetime(SeriesInfoInteger(Symbol(),InpInd_Timeframe,SERIES_LASTBAR_DATE))+TimeShiftSec;
        }

      //---- getting sell signals
      if(DnVelue[0] && DnVelue[0]!=EMPTY_VALUE)
        {
         if(SellPosOpen) SELL_Open=true;
         if(BuyPosClose) BUY_Close=true;
         DnSignalTime=datetime(SeriesInfoInteger(Symbol(),InpInd_Timeframe,SERIES_LASTBAR_DATE))+TimeShiftSec;
        }

      //---- searching for the last trading direction for getting positions closing signals
      //if(!MQL5InfoInteger(MQL5_TESTING) && !MQL5InfoInteger(MQL5_OPTIMIZATION)) //if execution is set to "Random delay" in the Strategy Tester 
      if((BuyPosOpen && BuyPosClose || SellPosOpen && SellPosClose) && (!BUY_Close && !SELL_Close))
        {
         int Bars_=Bars(Symbol(),InpInd_Timeframe);

         for(int bar=int(SignalBar+1); bar<Bars_; bar++)
           {
            if(SellPosClose)
              {
               if(CopyBuffer(InpInd_Handle,1,bar,1,UpVelue)<=0) {Recount=true; return;}
               if(UpVelue[0]!=0 && UpVelue[0]!=EMPTY_VALUE)
                 {
                  SELL_Close=true;
                  break;
                 }
              }

            if(BuyPosClose)
              {
               if(CopyBuffer(InpInd_Handle,0,bar,1,DnVelue)<=0) {Recount=true; return;}
               if(DnVelue[0]!=0 && DnVelue[0]!=EMPTY_VALUE)
                 {
                  BUY_Close=true;
                  break;
                 }
              }
           }
        }
     }

//+----------------------------------------------+
//| Performing deals                             |
//+----------------------------------------------+
//---- Closing a long position
   BuyPositionClose(BUY_Close,Symbol(),Deviation_);

//---- Closing a short position   
   SellPositionClose(SELL_Close,Symbol(),Deviation_);

//---- Buying
   BuyPositionOpen(BUY_Open,Symbol(),UpSignalTime,MM,0,Deviation_,StopLoss_,TakeProfit_);

//---- Selling
   SellPositionOpen(SELL_Open,Symbol(),DnSignalTime,MM,0,Deviation_,StopLoss_,TakeProfit_);
//----
  }
//+------------------------------------------------------------------+

Il codice per la realizzazione di una tale idea è abbastanza semplice e chiaro, anche se alcuni dettagli dovrebbero essere chiariti.

Il periodo del grafico utilizzato da un indicatore di segnale e da un Expert Advisor è fissato nella variabile di input InpInd_Timeframe dell'Expert Advisor. Pertanto, la modifica di un grafico in cui si trova un Expert Advisor, non altera questo parametro per l'Expert Advisor.

La funzione IsNewBar() necessaria per determinare il momento dell'arrivo di una nuova barra viene implementata come classe inserita nel file TradeAlgorithms.mqh. Ciò consente di utilizzare facilmente un numero qualsiasi di tali funzioni nel codice impostando una singola variabile CIsNewBar statica per ciascuna di esse.

Le variabili UpSignalTime e DnSignalTime vengono utilizzate per memorizzare e trasferire il tempo, dopodiché è possibile eseguire un’operazione successiva dopo quello precedente, alle funzioni di trading. Nel nostro caso, questa funzione viene utilizzata per evitare di eseguire più operazioni nella stessa direzione alla stessa barra (quando si esegue un'operazione, la funzione di trading memorizza il tempo della fine della barra corrente e non esegue nuove operazioni nella stessa direzione fino a quel momento).

Il blocco "Ricerca dell'ultima direzione di trading per ottenere segnali per la chiusura delle posizioni" nella funzione OnTick() è necessario per ricevere i segnali di chiusura delle posizioni sulle barre senza segnali di trading. In caso di un normale funzionamento di Expert Advisor, non è necessario. Ma in caso di guasto della connessione Internet, è abbastanza possibile che un nuovo segnale di trading venga perso. Non è certo una buona idea entrare nel mercato post factum, ma sarebbe una mossa saggia chiudere le posizioni aperte.

Utilizzo del Sistema di Trading con Altri Indicatori di Segnale Semaforico

Ora, se è necessario utilizzare questo codice con un altro indicatore del segnale semaforico, è necessario eseguire le seguenti azioni:

  1. Sostituire i dati dell'indicatore precedente con i parametri necessari di quello nuovo in un parametro di input dell’Expert Advisor;
  2. Modificare il codice per ottenere l'handle dell'indicatore nel blocco OnInit();
  3. Determinare gli indici per i buffer degli indicatori, utilizzati per memorizzare i segnali di trading di acquisto e vendita dal codice dell'indicatore e inserirli in modo appropriato nelle chiamate di funzione CopyBuffer() del blocco OnTick(). In questo caso vengono utilizzati buffer zero e primo indicatore;
  4. Modificare l'inizializzazione della variabile del punto di partenza del calcolo dei dati (min_rates_total) in un Expert Advisor in base al codice dell’indicatore;
  5. Cambia il blocco "Ricerca dell'ultima direzione di trading per ottenere segnali per la chiusura delle posizioni" nella funzione OnTick() in base al codice dell'indicatore. 

Utilizzo del Sistema di Trading con altri Indicatori di Tendenza Semaforici

Quando si utilizza questo sistema di trading con indicatore di tendenza semaforico, il codice dell’Expert Advisor è cambiato un po’ nel blocco per determinare i segnali per le operazioni della funzione OnTick (). Ad esempio, il codice cercherà come segue l'Expert Advisor basato sull'indicatore FiboCandles:

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---- checking the number of bars to be enough for calculation
   if(BarsCalculated(InpInd_Handle)<min_rates_total) return;
   
//---- uploading history for IsNewBar() and SeriesInfoInteger() functions  
   LoadHistory(TimeCurrent()-PeriodSeconds(InpInd_Timeframe)-1,Symbol(),InpInd_Timeframe);

//---- declaration of local variables
   double TrendVelue[2];
//---- declaration of static variables
   static bool Recount=true;
   static bool BUY_Open=false,BUY_Close=false;
   static bool SELL_Open=false,SELL_Close=false;
   static datetime UpSignalTime,DnSignalTime;
   static CIsNewBar NB;

//+----------------------------------------------+
//| Searching for deals performing signals       |
//+----------------------------------------------+
   if(!SignalBar || NB.IsNewBar(Symbol(),InpInd_Timeframe) || Recount) // checking for a new bar
     {
      //---- zeroing out trading signals
      BUY_Open=false;
      SELL_Open=false;
      BUY_Close=false;
      SELL_Close=false;
      Recount=false;

      //---- copy the newly obtained data into the arrays
      if(CopyBuffer(InpInd_Handle,4,SignalBar,2,TrendVelue)<=0) {Recount=true; return;}

      //---- getting buy signals
      if(TrendVelue[0]==1 && TrendVelue[1]==0)
        {
         if(BuyPosOpen) BUY_Open=true;
         if(SellPosClose)SELL_Close=true;
         UpSignalTime=datetime(SeriesInfoInteger(Symbol(),InpInd_Timeframe,SERIES_LASTBAR_DATE))+TimeShiftSec;
        }

      //---- getting sell signals
      if(TrendVelue[0]==0 && TrendVelue[1]==1)
        {
         if(SellPosOpen) SELL_Open=true;
         if(BuyPosClose) BUY_Close=true;
         DnSignalTime=datetime(SeriesInfoInteger(Symbol(),InpInd_Timeframe,SERIES_LASTBAR_DATE))+TimeShiftSec;
        }

      //---- searching for the last trading direction for getting positions closing signals
      //if(!MQL5InfoInteger(MQL5_TESTING) && !MQL5InfoInteger(MQL5_OPTIMIZATION)) //if execution is set to "Random delay" in the Strategy Tester 
        {
         if(SellPosOpen && SellPosClose  &&  TrendVelue[1]==0) SELL_Close=true;
         if(BuyPosOpen  &&  BuyPosClose  &&  TrendVelue[1]==1) BUY_Close=true;
        }
     }

//+----------------------------------------------+
//| Performing deals                             |
//+----------------------------------------------+
//---- Closing a long position
   BuyPositionClose(BUY_Close,Symbol(),Deviation_);

//---- Closing a short position   
   SellPositionClose(SELL_Close,Symbol(),Deviation_);

//---- Buying
   BuyPositionOpen(BUY_Open,Symbol(),UpSignalTime,MM,0,Deviation_,StopLoss_,TakeProfit_);

//---- Selling
   SellPositionOpen(SELL_Open,Symbol(),DnSignalTime,MM,0,Deviation_,StopLoss_,TakeProfit_);
//----
  }

In questo caso, i segnali di trading vengono ricevuti da un solo buffer di indicatori di colore (contenente indici di colore). I dati in questo buffer possono avere solo due valori: 0 - per il mercato ascendente e 1 - per quello discendente. Il codice di blocco "Ricerca dell'ultima direzione di trading per ottenere segnali di chiusura delle posizioni" è diventato il più semplice possibile, poiché una direzione di tendenza su qualsiasi barra può essere ricevuta direttamente dalla cella appropriata del buffer dell'indicatore.

Al blocco "Performing deals" le funzioni di chiusura delle posizioni vanno per prime, seguite dalle funzioni di apertura. In caso di sequenza opposta, sarà possibile chiudere i deal solo su una barra, non sarai in grado di aprirli contemporaneamente durante il test nella modalità "Apri solo prezzi"! Pertanto, i risultati di trading saranno seriamente compromessi.


Testare il Sistema di Trading

Prima di procedere al test del sistema di trading, è necessario chiarire un dettaglio importante. Nel caso in cui il valore della variabile di ingresso SignalBar sia uguale a zero, l'Expert Advisor otterrà i segnali di esecuzione delle operazioni dalla barra corrente. Ma il segnale della barra corrente non è affidabile nell'indicare il cambiamento della tendenza che si è mossa contro questo segnale alla barra precedente. I segnali sulla barra corrente possono comparire e scomparire, mentre una tendenza può muoversi contro tali segnali per un periodo piuttosto lungo. Questo si può vedere facilmente se un Expert Advisor viene testato su tutti i tick con visualizzazione abilitata e la variabile SignalBar uguale a zero. La visualizzazione del funzionamento dell'indicatore ASCtrend presenta una prova molto chiara di questo fatto in tal caso.

Anche in questo caso, solo la modalità "Ogni tick" è adatta per un'ottimizzazione dell’Expert Advisor con un segnale ricevuto dalla barra corrente. Nel caso in cui debba essere ricevuto da qualsiasi altra barra già chiusa, la modalità "Solo prezzi di Apertura" è abbastanza. Ciò accelera notevolmente l'analisi del comportamento del sistema di trading senza gravi perdite nella sua qualità.

Pertanto, è meglio non utilizzare i segnali dalla barra corrente per testare e ottimizzare tali sistemi di trading!

Quindi, testiamo l'Expert Advisor con parametri predefiniti su EUR/ USD dall'inizio dell'anno fino all'inizio di dicembre:

Fig.5. Risultati dei test di Exp_ASCtrend Expert Advisor con parametri predefiniti su EUR/USD H1 

Fig.5. Risultati dei test di Exp_ASCtrend Expert Advisor con parametri predefiniti su EUR/USD H1 

Dopo aver modificato leggermente le impostazioni dell’Expert Advisor nello Strategy Tester, possiamo trovare abbastanza facilmente la combinazione più adatta dei parametri dell’Expert Advisor per i dati storici esistenti:

 Fig.6. Risultati dei test di Exp_ASCtrend Expert Advisor dopo l'ottimizzazione con parametri migliori su EUR/USD H1

Fig.6. I risultati dei test di Exp_ASCtrendExpert Advisor dopo l'ottimizzazione con parametri migliori su EUR/USD H1 

Il processo di ottimizzazione del sistema di trading non ha alcuna peculiarità, ecco perché fornirò solo un link all'articolo che descrive questo processo nel dettaglio: "MQL5: Guida al Test e all'Ottimizzazione degli Expert Advisor in MQL5".

Naturalmente, sarebbe ingenuo aspettarsi alcuni profitti eccezionali da un sistema di trading così semplice. Tuttavia, è del tutto possibile ottenere buoni risultati nel caso in cui questo sistema semiautomatico sia abilmente gestito e regolarmente sintonizzato in base al comportamento corrente del mercato.

Ad esempio, c'è stata una tendenza al rialzo sul grafico EUR/USD H12 nel 2011 da gennaio a maggio. Ed era facilmente rilevabile nelle fasi iniziali:

Fig.7. Grafico EUR/USD H12 (gennaio/maggio 2011)

Fig.7. Grafico EUR/USD H12 (gennaio/maggio 2011)

Sarebbe interessante testare l'Expert Advisor su questo intervallo con le impostazioni predefinite, la possibilità di acquistare solo e l'utilizzo di solo il 5% di un deposito (MM = 0,05). Ecco i risultati dell'Expert Advisor con tali parametri testati sul grafico H1:

Fig.8. Risultati dei test di Exp_ASCtrend Expert Advisor con parametri predefiniti su EUR/USD H1 per gennaio/maggio 2011 (solo posizioni lunghe, MM=0,05) 

Fig.8. I risultati dei test di Exp_ASCtrend Expert Advisor con parametri predefiniti su EUR/USD H1 per gennaio/maggio 2011 (solo posizioni lunghe, MM=0,05)

Naturalmente, in questo caso un trader è pienamente responsabile della scelta di una direzione del deal. Ma se teniamo presente che dovrebbe essere fatto utilizzando grafici di grandi dimensioni, difficilmente avremo delle difficoltà.


Modifica del Modulo di Trading per l'Utilizzo con un Altro Indicatore

Questo articolo avrebbe potuto essere finito qui ma MetaEditor ha acquisito la possibilità di generare Expert Advisor basati su moduli di trading già pronti. Il processo di creazione di tali moduli considerando tutto il materiale qui presentato è piuttosto complesso e richiede uno studio specifico. Pertanto, mi concentrerò sui moduli di trading già creati che sono completamente analoghi ai sistemi di trading che ho suggerito. E solo dopo passerò ai dettagli di questi moduli di modifica in base agli specifici indicatori di segnale evitando spiegazioni inutili.

Supponiamo di avere già la raccolta di moduli di trading per sistemi di segnale semaforici (MySignals.zip) e vogliamo creare il modulo analogo per ogni particolare indicatore. Lascia che sia l'indicatore BykovTrendSignal.mq5 che è un tipico indicatore del segnale semaforico. Prima di tutto, dovremmo trovare l'analogo più accurato dell'indicatore di questa raccolta (Indicatori.zip). Visivamente, determiniamo che il primo indicatore di questo articolo (ASCtrend) è il più simile ad esso.  Pertanto, utilizzeremo il modulo di trading di questo indicatore per la modifica.

Considerando il suo utilizzo nel codice di programma richiesto, l'indicatore stesso (BykovTrend) ha una serie di parametri di input:

//+----------------------------------------------+
//| Indicator input parameters                   |
//+----------------------------------------------+
input int RISK=3;
input int SSP=9;
//+----------------------------------------------+

E abbiamo bisogno degli indici dei buffer di indicatori utilizzati per memorizzare i segnali per l'esecuzione di operazioni. Nel nostro caso questi sono: 0 - per i segnali di vendita e 1 - per i segnali di acquisto.

Ora che sappiamo quale modulo dovrebbe essere usato per la modifica, lo copiamo nella cartella \MQL5\Include\Expert\Signal\MySignals\ con il nome del file BykovTrendSignal.mqh e quindi lo apriamo in MetaEditor. Nel codice utilizzato, viene regolarmente rilevata l'espressione "ASCtrend" (il nome dell'indicatore precedente). Dovrebbe essere sostituito dal nome del nuovo indicatore - "BykovTrend". Per fare ciò, premere contemporaneamente i tasti "Ctrl" e "H" e apportare le modifiche necessarie:

 Sostituzione del nome dell'indicatore nel codice del modulo di trading

Fig.9. Sostituzione del nome dell'indicatore nel codice del modulo di trading

La fase successiva del nostro lavoro è la più accurata. Dobbiamo sostituire tutto ciò che riguarda i parametri di input dell'indicatore nel codice del modulo di trading. Il processo è molto simile a quanto affermato nell'articolo "MQL5 Wizard: Come creare un modulo di segnali di trading".

Prima di tutto, dovremmo apportare alcune modifiche al blocco commentato della descrizione della classe dei segnali di trading MQL5 Wizard:

//+----------------------------------------------------------------------+
//| Description of the class                                             |
//| Title=The signals based on BykovTrend indicator                      |
//| Type=SignalAdvanced                                                  |
//| Name=BykovTrend                                                      |
//| Class=CBykovTrendSignal                                              |
//| Page=                                                                |
//| Parameter=BuyPosOpen,bool,true,Permission to buy                     |
//| Parameter=SellPosOpen,bool,true,Permission to sell                   |
//| Parameter=BuyPosClose,bool,true,Permission to exit a long position   |
//| Parameter=SellPosClose,bool,true,Permission to exit a short position |
//| Parameter=Ind_Timeframe,ENUM_TIMEFRAMES,PERIOD_H1,Timeframe          |
//| Parameter=RISK,int,4,Risk level                                      |
//| Parameter=SSP,int,9,SSP                                              |
//| Parameter=SignalBar,uint,1,Bar index for entry signal                |
//+----------------------------------------------------------------------+
//--- wizard description end
//+----------------------------------------------------------------------+
//| CBykovTrendSignal class.                                             |
//| Purpose: Class of generator of trade signals based on                |
//| BykovTrend indicator https://www.mql5.com/ru/code/497/.               |
//|             Is derived from the CExpertSignal class.                 |
//+----------------------------------------------------------------------+

Entrambi gli indicatori contengono la stessa variabile di input RISK, quindi può essere lasciata. Ma in questi indicatori il suo valore predefinito è diverso. In realtà, questa differenza non è critica e può essere lasciata invariata. È stata aggiunta la riga di commento sulla variabile SSP:

//| Parameter=SSP,int,9,SSP                                    |

E il link all'indicatore Code Base è stato sostituito:

//| Purpose: Class of generator of trade signals based on      |
//| BykovTrend values https://www.mql5.com/ru/code/497/.        |

Ora, tutto ciò che riguarda i cambiamenti dei parametri di input dovrebbe riflettersi nella descrizione della classe di segnali di trading CBykovTrendSignal. Abbiamo la linea della nuova dichiarazione di variabile di classe m_SSP globale nei parametri delle impostazioni:

   uint              m_SSP;              // SSP

 e la riga della nuova dichiarazione del metodo di installazione dei parametri delle impostazioni SSP():

   void               SSP(uint value)                         { m_SSP=value;              } 

Tutto ciò che riguarda la variabile di input RISK nel modulo dei segnali di trading che creiamo è equivalente al modulo di input e, pertanto, non ci sono cambiamenti nel corrente e in qualsiasi altro blocco del modulo di trading.

Passiamo ora al constructor della classe CBykovTrendSignal::CBykovTrendSignal(). L'inizializzazione di una nuova variabile deve essere aggiunta in questo blocco:

   m_SSP=4;

Il controllo della correttezza della nuova variabile deve essere eseguito nel blocco di verifica dei parametri delle impostazioni CBykovTrendSignal::ValidationSettings():

   if(m_SSP<=0)
     {
      printf(__FUNCTION__+": SSP must be above zero");
      return(false);
     }

Dopodiché, possiamo passare al blocco di inizializzazione dell'indicatore BykovTrend - BykovTrendSignal::InitBykovTrend(). Il nuovo indicatore ha un numero diverso di variabili di input e, pertanto, anche la dimensione per l’array di parametri di input dichiarati sarà diversa:

//--- setting the indicator parameters
   MqlParam parameters[3];

Nel nostro caso, abbiamo bisogno di una dimensione per il nome della stringa dell'indicatore e altre due per i suoi parametri di input.

Ora dobbiamo inizializzare una nuova cella degli array di parametri di input, indicando il tipo di variabile che verrà memorizzata in essa:

   parameters[2].type=TYPE_INT;
   parameters[2].integer_value=m_SSP;

 Dopodiché, cambia il numero di variabili di input di 3 in questo blocco nella chiamata per l'inizializzazione dell'indicatore:

//--- object initialization   
   if(!m_indicator.Create(m_symbol.Name(),m_Ind_Timeframe,IND_CUSTOM,3,parameters))

Il numero di buffer di indicatori nell'indicatore rimane lo stesso e uguale a due, pertanto, non è necessario modificare nulla nella linea di inizializzazione del numero di buffer dell'indicatore nel nostro caso:

//--- number of buffers
   if(!m_indicator.NumBuffers(2))  return(false);

Gli indicatori ASCtrend e BykovTrend hanno due buffer di indicatori ciascuno. Le funzioni dei buffer sono completamente simili. Lo zero buffer viene utilizzato per memorizzare i segnali di vendita, mentre il buffer con indice 1 viene utilizzato per memorizzare i segnali di acquisto. Quindi, non è necessario modificare nulla nei blocchi di funzioni per la consegna di CBykovTrendSignal::LongCondition() e CBykovTrendSignal::ShortCondition() i segnali di trading e il lavoro sulla modifica del modulo dei segnali di trading possono essere considerati completati.

Ma in generale, tutti gli indicatori semaforici sono diversi e, quindi, questi blocchi per diversi indicatori semaforici possono differire notevolmente l'uno dall'altro. L'archivio del modulo di trading MySignals.zip ed il relativo archivio Indicators.zip contengono una quantità sufficiente di esempi per la creazione di vari indicatori. Dopo una certa analisi, è possibile scoprire i dettagli del processo di sostituzione e le possibili versioni del codice per questo scopo.

Ora, vorrei concentrarmi su Ind_Timeframe variabile di input del modulo dei segnali di trading. Questa variabile consente di scaricare un intervallo adeguato nell'indicatore. Tuttavia, l'Expert Advisor generato opera nell'intervallo di tempo al quale è stato assegnato. Significa che il time frame della variabile di input Ind_Timeframe non dovrebbe mai superare un periodo del grafico su cui opera l'Expert Advisor per fornire il normale funzionamento del modulo.

Infine, vorrei rivelare un'altra peculiarità della creazione di moduli di segnali di trading. A volte le enumerazioni personalizzate vengono implementate nel codice dell'indicatore di base come tipi per le variabili di input del modulo. Per esempio, l'enumerazione personalizzata Smooth_Method viene usata come tipo di variabile MA_SMethod per l'indicatore Candles_Smoothed:

//+-----------------------------------+
//|  Declaration of enumerations      |
//+-----------------------------------+
enum Smooth_Method
  {
   MODE_SMA_,  // SMA
   MODE_EMA_,  // EMA
   MODE_SMMA_, // SMMA
   MODE_LWMA_, // LWMA
   MODE_JJMA,  // JJMA
   MODE_JurX,  // JurX
   MODE_ParMA, // ParMA
   MODE_T3,    // T3
   MODE_VIDYA, // VIDYA
   MODE_AMA,   // AMA
  }; */
//+----------------------------------------------+
//| Indicator input parameters                   |
//+----------------------------------------------+
input Smooth_Method MA_SMethod=MODE_LWMA; // Smoothing method
input int MA_Length=30;                   // Smoothing depth                    
input int MA_Phase=100;                   // Smoothing parameter
                                          // for JJMA varying within the range -100 ... +100,
                                          // for VIDIA it is a CMO period, for AMA it is a slow average period
//+----------------------------------------------+

In tal caso le variabili di input di questo tipo e tutti gli elementi associati nel modulo dei segnali di negoziazione (Candles_SmoothedSignal.mqh) dovrebbero essere modificati nelle variabili di tipo int o uint. Inoltre, la procedura inversa delle enumerazioni personalizzate fino ai parametri di input dell’Expert Advisor e la sostituzione dei tipi di variabili di input necessari (ExpM_Candles_Smoothed Expert Advisor) dovrebbe essere eseguita per la facilità d'uso di queste variabili di input nel codice già generato dell'Expert Advisor finito:

//+------------------------------------------------------------------+
//|  Declaration of enumerations                                     |
//+------------------------------------------------------------------+
enum Smooth_Method
  {
   MODE_SMA_,  // SMA
   MODE_EMA_,  // EMA
   MODE_SMMA_, // SMMA
   MODE_LWMA_, // LWMA
   MODE_JJMA,  // JJMA
   MODE_JurX,  // JurX
   MODE_ParMA, // ParMA
   MODE_T3,    // T3
   MODE_VIDYA, // VIDYA
   MODE_AMA,   // AMA
  };
//+------------------------------------------------------------------+
//| Inputs                                                           |
//+------------------------------------------------------------------+
//--- inputs for expert
input string          Expert_Title         ="Candles_Smoothed"; // Document name
ulong                 Expert_MagicNumber   =29976;              // 
bool                  Expert_EveryTick     =false;              // 
//--- inputs for main signal
input int             Signal_ThresholdOpen =40;                 // Signal threshold value to open [0...100]
input int             Signal_ThresholdClose=20;                 // Signal threshold value to close [0...100]
input double          Signal_PriceLevel    =0.0;                // Price level to execute a deal
input double          Signal_StopLevel     =50.0;               // Stop Loss level (in points)
input double          Signal_TakeLevel     =50.0;               // Take Profit level (in points)
input int             Signal_Expiration    =1;                  // Expiration of pending orders (in bars)
input bool            Signal__BuyPosOpen   =true;               // Candles_Smoothed() Permission to buy
input bool            Signal__SellPosOpen  =true;               // Candles_Smoothed() Permission to sell
input bool            Signal__BuyPosClose  =true;               // Candles_Smoothed() Permission to exit a long position
input bool            Signal__SellPosClose =true;               // Candles_Smoothed() Permission to exit a short position
input ENUM_TIMEFRAMES Signal__Ind_Timeframe=PERIOD_H1;            // Candles_Smoothed() Timeframe
input Smooth_Method   Signal__MA_SMethod   =4;                  // Candles_Smoothed() Smoothing method (1 - 10)
input uint            Signal__MA_Length    =30;                 // Candles_Smoothed() Smoothing depth
input uint            Signal__MA_Phase     =100;                // Candles_Smoothed() Smoothing parameter
input uint            Signal__SignalBar    =1;                  // Candles_Smoothed() Bar index for the entry signal
input double          Signal__Weight       =1.0;                // Candles_Smoothed() Weight [0...1.0]
//--- inputs for money
input double          Money_FixLot_Percent =10.0;               // Percent
input double          Money_FixLot_Lots    =0.1;                // Fixed volume

Nel nostro caso questo è stato fatto con la variabile di input Signal__MA_SMethod.

È possibile accelerare notevolmente la modifica del codice, se si aprono entrambe le versioni del codice (ASCtrendSignal.mqh e BykovTrendSignal.mqh) contemporaneamente nell'editor (posizionandone una sul lato sinistro e l'altra sul lato destro) e confrontare attentamente entrambe le versioni del codice.

Conclusione

Ho inserito una quantità sufficiente di Expert Advisor basati sul sistema di trading semaforico nell’archivio Experts.zip allegato a questo articolo per consentire ai creatori degli Expert Advisors alle prime armi di comprendere facilmente tutte le funzionalità della scrittura di un tale codice o almeno lavorare con Expert Advisor già pronti utilizzando indicatori abbastanza popolari.

Tutti gli Expert Advisor allegati sono, inoltre, presentati come moduli di trading per coloro che desiderano utilizzare il generatore di strategie di trading come base per i propri sistemi di trading. Questi moduli si trovano in MySignals.zip, mentre i sistemi di trading basati su di essi possono essere trovati in Expertsez.zip. Gli indicatori utilizzati negli Expert Advisor si trovano in Indicators.zip. I percorsi per l'estrazione dei file sono i seguenti:

  • Experts.zip: "\MQL5\Experts\";
  • Expertsez.zip: "\MQL5\Experts\"; 
  • MySignals.zip: "\MQL5\Include\Expert\Signal\MySignals\"; 
  • Indicators.zip: "\MQL5\Indicators\";
  • SmoothAlgorithms.mqh: "\Include\";
  • TradeAlgorithms.mqh: "\Include\".

Riavvia MetaEditor, apri la finestra Navigator, fai click con il pulsante destro del mouse sull'etichetta MQL5 e seleziona "Compile" nel menu a comparsa.

Il file SmoothAlgorithms.mqh è necessario per la compilazione di alcuni indicatori da Indicators.zip, mentre il file TradeAlgorithms.mqh è necessario per la compilazione di tutti gli Expert Advisor di Experts.zip.

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

File allegati |
expertsez.zip (31.51 KB)
mysignals.zip (44.08 KB)
indicators.zip (39.15 KB)
experts.zip (34.67 KB)
Crea il Tuo Robot di Trading in 6 Passaggi! Crea il Tuo Robot di Trading in 6 Passaggi!
Se non sai come vengono costruite le classi di trading e hai paura delle parole "Programmazione Orientata agli Oggetti", allora questo articolo fa per te. In effetti, non è necessario conoscere i dettagli per scrivere il proprio modulo di segnali di trading. Basta seguire alcune semplici regole. Tutto il resto verrà fatto da MQL5 Wizard e otterrai un robot di trading pronto all'uso!
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.
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.
Le Basi della Programmazione Orientata agli Oggetti Le Basi della Programmazione Orientata agli Oggetti
Non hai bisogno di sapere cosa sono il polimorfismo, l'incapsulamento, ecc. per usare la programmazione orientata agli oggetti (OOP) ... puoi semplicemente usare queste funzionalità. Questo articolo descrive le basi dell'OOP attraverso degli esempi pratici.