English Русский 中文 Español Deutsch 日本語 Português 한국어 Français Türkçe
preview
Testare i diversi tipi di media mobile per vedere quanto sono efficaci

Testare i diversi tipi di media mobile per vedere quanto sono efficaci

MetaTrader 5Tester |
214 1
Mohamed Abdelmaaboud
Mohamed Abdelmaaboud

Introduzione

Nel mio precedente articolo abbiamo preso in considerazione i tipi più diffusi di Medie Mobili (semplici, ponderate, esponenziali): Scopri come progettare diversi sistemi di Media Mobile. Continueremo questo argomento in questo articolo e utilizzeremo il tipo semplice per confrontare i suoi risultati con altri tipi di medie mobili. Molti trader utilizzano la media mobile in diverse tipologie a seconda delle loro preferenze. In questo articolo, quindi, ne considereremo in dettaglio diversi tipi, ne testeremo le prestazioni e confronteremo i risultati per definire quale di questi tipi si comporta meglio.

Ai fini di questo articolo, creeremo una semplice applicazione in modo da eseguire il backtesting delle medie nello Strategy Tester integrato di MetaTrader 5. Per capire su cosa dobbiamo concentrarci quando studiamo i risultati dei test, consultate il mio articolo precedente Comprendere e Utilizzare Efficacemente lo Strategy Tester MQL5; fornisce molte informazioni utili.

Per considerare i diversi tipi di medie mobili e vedere come si comportano, esamineremo i seguenti argomenti:

Notare che, sebbene cercherò di ottimizzare le impostazioni di ogni media mobile per ottenere i migliori risultati, è necessario effettuare più controlli e test da soli, poiché l'obiettivo qui è solo educativo. Pertanto, è necessario testare, ottimizzare e trovare le migliori impostazioni che possano dare risultati superiori. Può accadere che una o tutte queste tipologie non siano adatte al vostro stile di trading. Ma spero che possiate trovare spunti utili per migliorare il vostro trading. In generale, qualunque sia l'ideale che si incontra, è importante misurare la performance di qualsiasi strategia di trading prima di utilizzarla su un conto reale.

Avvertenza: Tutte le informazioni sono fornite "così come sono" solo a scopo didattico e non sono preparate per scopi commerciali o di consulenza. Le informazioni non garantiscono alcun tipo di risultato. Se scegliete di utilizzare questi materiali su uno qualsiasi dei vostri conti di trading, lo farete a vostro rischio e pericolo e sarete gli unici responsabili.

Test del Sistema della Media Mobile Semplice (SMA)

In questa parte, condividerò i risultati del semplice sistema basato solo su una semplice strategia con una media mobile. Trova l'incrocio tra il prezzo e la linea della media mobile semplice che genererà segnali di acquisto e di vendita. Creeremo un sistema in grado di eseguire questi segnali automaticamente.

Utilizzeremo i seguenti segnali per eseguire operazioni di trading:


Segnale di acquisto:

Il prezzo di chiusura è superiore al valore della media mobile semplice

E il prezzo di chiusura precedente era inferiore al valore della media mobile semplice precedente.

Segnale di vendita:

Il prezzo di chiusura è al di sotto del valore della media mobile semplice

E il prezzo di chiusura precedente era superiore al valore della media mobile semplice precedente.

Se volete leggere altro sulla media mobile semplice e sugli altri tipi di media mobile più diffusi, vi consiglio di leggere il mio precedente articolo Impara a progettare diversi sistemi di Medie Mobili, vi aiuterà a comprenderle bene e a capire meglio questo articolo.

Di seguito sono illustrati i passaggi per creare questo tipo di sistema di trading in grado di eseguire automaticamente gli ordini di acquisto e di vendita sulla base dei segnali citati.

Nell'ambito globale, includeremo nel software il file include, Trade, che consente di eseguire gli ordini in base ai nostri segnali utilizzando il preprocessore #include. Se volete saperne di più sul preprocessore, potete leggere l'articolo Tutto quello che c'è da apprendere sulla struttura del programma MQL5 per maggiori dettagli.

#include <Trade\Trade.mqh>

Creare tre input utente per la variabile double lotSize, la variabile ENUM_TIMEFRAMES timeFrame e la variabile integer MAPeriod da modificare secondo i desideri dell'utente con valori predefiniti:

input double lotSize = 1;
input ENUM_TIMEFRAMES timeFrame = PERIOD_H1;
input int MAPeriod= 50;

Creare le due variabili integer simpleMA e barsTotal senza assegnazione, poiché le definiremo in seguito nella parte OnInit()

int simpleMA;
int barsTotal;

Creare trade come oggetto della classe CTrade per accedere facilmente alle funzioni di trade.

CTrade trade;

Nella parte OnInit(), definiremo la simpleMA utilizzando la funzione iMA che restituisce l'handle dell'indicatore di media mobile e i suoi parametri sono:

  • symbol: per specificare il nome del simbolo, utilizzeremo _Symbol per il simbolo corrente
  • period: per specificare il time frame utilizzeremo l'input dell'utente con un valore predefinito di 1 ora, ma l'utente può regolarlo
  • ma_period: per specificare il periodo della media mobile semplice, utilizzeremo l'input dell'utente con un valore predefinito di 50, ma l'utente può regolare anche questo.
  • ma_shift: per specificare lo spostamento orizzontale, useremo 0 
  • applied_price: per specificare il tipo di prezzo, utilizzeremo il prezzo di chiusura per il calcolo della media mobile semplice.
simpleMA = iMA(_Symbol, timeFrame, MAPeriod, 0, MODE_SMA, PRICE_CLOSE);

E barsTotal utilizzando la funzione iBars che restituisce il numero di barre; i suoi parametri sono:

  • symbol: per specificare il simbolo, useremo (_Symbol) da applicare al simbolo corrente
  • timeframe: per specificare il time frame, utilizzeremo il time frame creato dall'utente con il valore predefinito di 1 ora, che l'utente potrà regolare
   barsTotal=iBars(_Symbol,timeFrame);

Nella parte OnTick(), creeremo due array, uno per i prezzi utilizzando MqlRates per memorizzare le informazioni su prezzi, volumi e spread e l'altro per la media mobile semplice:

   MqlRates priceArray[];
   double mySMAArray[];

Per impostare il flag AS_SERIES su questi due array creati, si utilizza la funzione ArraySetAsSeries, i cui parametri sono:

  • array[]: per specificare l'array per riferimento
  • flag: per specificare la direzione di indicizzazione dell'array
   ArraySetAsSeries(priceArray,true);
   ArraySetAsSeries(mySMAArray,true);

Definire i prezzi Ask e Bid dopo aver creato due variabili double

   double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
   double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);

Ottenere i dati storici di MqlRates utilizzando la funzione CopyRates, i cui parametri sono:

  • symbol_name: per determinare il nome del simbolo
  • timeframe: per determinare il time frame
  • start_pos: per specificare la posizione iniziale
  • count: per specificare il numero di dati da copiare
  • rates_array[]: per specificare l'array di destinazione i cui copiare
int Data=CopyRates(_Symbol,_Period,0,3,priceArray);

Ottenere i dati del buffer dell'indicatore utilizzando la funzione CopyBuffer, i cui parametri sono:

  • indicator_handle: per specificare l'handle dell'indicatore che è simpleMA qui
  • buffer_num: per specificare il numero di buffer dell'indicatore, che è 0
  • start_pos: per determinare la posizione iniziale, che è 0, ovvero la candela attuale
  • count: per specificare la quantità che abbiamo bisogno di copiare, che è 3
  • buffer[]: per specificare l'array di destinazione in cui copiare, che è mySMAArray
CopyBuffer(simpleMA,0,0,3,mySMAArray);

Definizione dell'ultimo prezzo di chiusura e del valore della media mobile semplice della stessa candela dopo la creazione di due variabili double per questi due valori

   double lastClose=(priceArray[1].close);
   double SMAVal = NormalizeDouble(mySMAArray[1],_Digits);

Definire il prezzo di chiusura precedente e il valore della media mobile semplice di questa stessa candela dopo aver creato altre due variabili double per questi due valori

   double prevClose=(priceArray[2].close);
   double prevSMAVal = NormalizeDouble(mySMAArray[2],_Digits);

Creazione di una variabile integer bars da confrontare con la variabile barsTotal creata

int bars=iBars(_Symbol,timeFrame);

Verificare se è stata creata una nuova barra controllando barsTotal se non è uguale a bars

if(barsTotal != bars)

Se barsTotal non è uguale a bars, occorre aggiornare barsTotal con il valore di bars.

barsTotal=bars;

Se barsTotal non è uguale a bars, dobbiamo anche verificare le condizioni della strategia se la precedente chiusura è inferiore al valore della media mobile semplice della stessa candela e allo stesso tempo l'ultimo prezzo di chiusura è superiore al valore della media mobile semplice della stessa candela. Il programma deve chiudere la posizione aperta corrente e aprire una posizione di acquisto.

      if(prevClose<prevSMAVal && lastClose>SMAVal)
        {
         trade.PositionClose(_Symbol);
         trade.Buy(lotSize,_Symbol,Ask,0,0,NULL);
        }

Se la precedente chiusura è superiore al valore della media mobile semplice della stessa candela e allo stesso tempo l'ultimo prezzo di chiusura è inferiore al valore della media mobile semplice della stessa candela. Il programma deve chiudere la posizione aperta e aprire una posizione di vendita.

      if(prevClose>prevSMAVal && lastClose<SMAVal)
        {
         trade.PositionClose(_Symbol);
         trade.Sell(lotSize,_Symbol,Bid,0,0,NULL);
        }

Compiliamo quindi il codice e lo troveremo compilato senza errori o avvertimenti.

Di seguito viene riportato il codice completo in un unico blocco:

//+------------------------------------------------------------------+
//|                                                   SMA_System.mq5 |
//+------------------------------------------------------------------+
#include <Trade\Trade.mqh>
input double lotSize = 1;
input ENUM_TIMEFRAMES timeFrame = PERIOD_H1;
input int MAPeriod= 50;
int simpleMA;
int barsTotal;
CTrade trade;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   simpleMA = iMA(_Symbol, timeFrame, MAPeriod, 0, MODE_SMA, PRICE_CLOSE);
   barsTotal=iBars(_Symbol,timeFrame);
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   MqlRates priceArray[];
   double mySMAArray[];
   double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
   double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
   ArraySetAsSeries(priceArray,true);
   ArraySetAsSeries(mySMAArray,true);
   int Data=CopyRates(_Symbol,_Period,0,3,priceArray);
   CopyBuffer(simpleMA,0,0,3,mySMAArray);
   double lastClose=(priceArray[1].close);
   double SMAVal = NormalizeDouble(mySMAArray[1],_Digits);
   double prevClose=(priceArray[2].close);
   double prevSMAVal = NormalizeDouble(mySMAArray[2],_Digits);
   int bars=iBars(_Symbol,timeFrame);
   if(barsTotal != bars)
     {
      barsTotal=bars;
      if(prevClose<prevSMAVal && lastClose>SMAVal)
        {
         trade.PositionClose(_Symbol);
         trade.Buy(lotSize,_Symbol,Ask,0,0,NULL);
        }
      if(prevClose>prevSMAVal && lastClose<SMAVal)
        {
         trade.PositionClose(_Symbol);
         trade.Sell(lotSize,_Symbol,Bid,0,0,NULL);
        }
     }
  }
//+------------------------------------------------------------------+

Compiliamo l'EA e lo eseguiamo sui dati EURUSD per eseguire il backtest della strategia. Il periodo di test va dal 1° gennaio al 30 giugno 2022, come abbiamo fatto per tutti i tipi di media mobile menzionati. Le nostre impostazioni per la SMA saranno le seguenti:

  • Dimensioni del lotto: 1
  • Time frame: 1 ora
  • Periodo MA: 50

I risultati del test:

Risultati SMA

Come possiamo vedere, le figure seguenti devono essere studiate dopo aver testato l'indicatore SMA:

  • Utile Netto: 2700.30 (27%)
  • Saldo DD relativo: 37.07%
  • Equity DD relativo: 41.76%
  • Fattore di profitto: 1.10
  • Profitto atteso: 12.68
  • Fattore di recupero: 0.45
  • Indice di Sharpe 0.57

Media Mobile Adattiva (iAMA)

In questa parte, impareremo a conoscere un altro tipo di media mobile, la AMA (Adaptive Moving Average). È stata sviluppata da Perry J. Kaufman e si chiama (KAMA) e il concetto principale è quello di ridurre il rumore nel movimento dei prezzi. Segue il movimento dei prezzi, indipendentemente dalla volatilità di questo movimento, adattandosi ad esso. L'indicatore è un trend-follower, quindi può essere utilizzato per identificare la tendenza e i punti di svolta.

L'indicatore viene calcolato in pochi passaggi.

Primo passo: Calcolo di AMA o KAMA

passo uno

Secondo passo: Calcolo della costante di attenuazione (SC)

passo2

Terzo passo: Calcolo del Rapporto di Efficienza (ER)

 passo3

Ora, abbiamo imparato a calcolare manualmente l'indicatore AMA, ma non ne abbiamo bisogno perché possiamo inserirlo automaticamente in MetaTrader 5 scegliendolo tra gli indicatori già pronti. È il momento di creare un sistema di trading in grado di eseguire ordini di acquisto e di vendita in base all'incrocio tra il prezzo di chiusura e l'indicatore AMA. Pertanto, per la nostra strategia utilizzeremo i seguenti segnali.

Segnale d’acquisto:

Il prezzo di chiusura è superiore al valore della media mobile adattativa

E il prezzo di chiusura precedente era inferiore al valore della media mobile adattiva precedente.

Segnale di vendita:

Il prezzo di chiusura è inferiore al valore della media mobile adattiva

E il prezzo di chiusura precedente era superiore al valore della media mobile adattiva precedente.

Di seguito è riportato il codice completo per la creazione di questo tipo di sistema di trading:

//+------------------------------------------------------------------+
//|                                                  iAMA_System.mq5 |
//+------------------------------------------------------------------+
#include <Trade\Trade.mqh>
input double lotSize = 1;
input ENUM_TIMEFRAMES timeFrame = PERIOD_H1;
input int MAPeriod= 50;
input int fastMAPeriod= 5;
input int slowMAPeriod= 100;
int adaptiveMA;
int barsTotal;
CTrade trade;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   adaptiveMA = iAMA(_Symbol, timeFrame, MAPeriod,fastMAPeriod,slowMAPeriod, 0, PRICE_CLOSE);
   barsTotal=iBars(_Symbol,timeFrame);
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   MqlRates priceArray[];
   double myAMAArray[];
   double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
   double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
   ArraySetAsSeries(priceArray,true);
   ArraySetAsSeries(myAMAArray,true);
   int Data=CopyRates(_Symbol,timeFrame,0,3,priceArray);
   CopyBuffer(adaptiveMA,0,0,3,myAMAArray);
   double lastClose=(priceArray[1].close);
   double AMAVal = NormalizeDouble(myAMAArray[1],_Digits);
   double prevClose=(priceArray[2].close);
   double prevAMAVal = NormalizeDouble(myAMAArray[2],_Digits);
   int bars=iBars(_Symbol,timeFrame);
   if(barsTotal != bars)
     {
      barsTotal=bars;
      if(lastClose>AMAVal && prevClose<prevAMAVal)
        {
         trade.PositionClose(_Symbol);
         trade.Buy(lotSize,_Symbol,Ask,0,0,NULL);
        }
      if(lastClose<AMAVal && prevClose>prevAMAVal)
        {
         trade.PositionClose(_Symbol);
         trade.Sell(lotSize,_Symbol,Bid,0,0,NULL);
        }
     }
  }
//+------------------------------------------------------------------+

La differenza in questo codice è l'utilizzo della funzione iAMA che restituisce l'handle dell'indicatore della media mobile adattiva e i suoi parametri sono:

  • symbol: per specificare il nome del simbolo, utilizzeremo _Symbol per il simbolo corrente
  • period: per specificare il time frame, utilizzeremo l'input dell'utente con un valore predefinito di 1 ora
  • ama_period: per specificare il periodo della media mobile adattiva
  • fast_ma_period: per specificare il periodo di fast MA
  • slow_ma_period: per specificare il periodo di slow MA
  • ama_shift: per specificare lo spostamento orizzontale, useremo 0
  • applied_price: per specificare il tipo di prezzo, utilizzeremo il prezzo di chiusura

Per vedere i risultati dell'indicatore AMA è necessario eseguire un backtest per lo stesso periodo:

  • Dimensione del lotto =1
  • Time frame = 1 ora
  • MAperiod = 50
  • MA veloce = 5
  • MA lenta = 100

I risultati:

Risultati AMA

Come si può vedere, le figure seguenti devono essere studiate dopo aver testato l'indicatore AMA:

  • Utile Netto: 3638.20 (36.39%)
  • Saldo DD relativo: 22.48%
  • Equity DD relativo: 35.53%
  • Fattore di profitto: 1.31
  • Profitto atteso: 35.67
  • Fattore di recupero: 0.65
  • Indice di Sharpe 0.86

Doppia Media Mobile Esponenziale (iDEMA)

In questa parte identificheremo un altro tipo di media mobile, l'indicatore tecnico Double Exponential Moving Average (DEMA). Si tratta di un indicatore trend-follower sviluppato da Patrick Mulloy. L'obiettivo principale di questo indicatore è quello di ridurre il ritardo delle EMA, e di renderlo più reattivo al movimento del mercato, come vedremo nel calcolo di questo indicatore.

Questo indicatore può essere utilizzato per identificare il trend o i punti di inversione nel trend rilevando la posizione dei prezzi rispetto a questa media mobile. Le fasi di calcolo dell'indicatore sono illustrate di seguito:

1. Calcolo della prima Media Mobile Esponenziale (EMA)

EMA uno = EMA di n periodi di prezzo

2. Calcolo dell'EMA di EMA uno

EMA due = EMA di EMA uno

3. Calcolo di DEMA

DEMA = (2 * EMA uno) - EMA due

Come sappiamo, non è necessario eseguire questo calcolo manuale, ma è per comprendere bene l'indicatore, abbiamo questo indicatore come molti altri indicatori tecnici nella MetaTrader 5. Ora dobbiamo creare lo stesso sistema di trading che abbiamo creato in precedenza, ma questa volta utilizzeremo DEMA per testare i suoi risultati rispetto ad altri tipi. Questo sistema di trading eseguirà gli stessi ordini menzionati, che acquistano e vendono in base al crossover, ma questa volta si tratterà del crossover tra il prezzo e l'indicatore DEMA. I segnali saranno:

Segnale d’acquisto:

Il prezzo di chiusura è al di sopra del valore della doppia media mobile esponenziale (DEMA).

E il prezzo di chiusura precedente era inferiore al valore DEMA precedente.

Segnale di vendita:

Il prezzo di chiusura è inferiore al valore DEMA

E il prezzo di chiusura precedente era superiore al valore DEMA precedente.

Di seguito è riportato il codice completo di questo sistema di trading con la piccola differenza di utilizzare la funzione iDEMA che restituisce l'handle dell'indicatore della doppia media mobile esponenziale e i suoi parametri sono:

  • symbol: per specificare il nome del simbolo, utilizzeremo (_Symbol) per il simbolo corrente
  • period: per specificare il time frame, utilizzeremo l'input dell'utente con un time frame predefinito di 1 ora
  • ma_period: per specificare il periodo della media mobile, utilizzeremo l'input dell'utente con un valore predefinito di 50
  • ma_shift: per specificare lo spostamento orizzontale, utilizzeremo 0 in quanto non abbiamo bisogno di uno spostamento sul grafico.
  • applied_price: per specificare il tipo di prezzo, useremo il prezzo di chiusura per calcolare la media mobile

Sarà uguale al blocco di codice sottostante:

//+------------------------------------------------------------------+
//|                                                 iDEMA_System.mq5 |
//+------------------------------------------------------------------+
#include <Trade\Trade.mqh>
input double lotSize = 1;
input ENUM_TIMEFRAMES timeFrame = PERIOD_H1;
input int MAPeriod= 50;
int DEMA;
int barsTotal;
CTrade trade;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   DEMA = iDEMA(_Symbol, timeFrame, MAPeriod,0, PRICE_CLOSE);
   barsTotal=iBars(_Symbol,timeFrame);
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   MqlRates priceArray[];
   double myDEMAArray[];
   double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
   double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
   ArraySetAsSeries(priceArray,true);
   ArraySetAsSeries(myDEMAArray,true);
   int Data=CopyRates(_Symbol,timeFrame,0,3,priceArray);
   CopyBuffer(DEMA,0,0,3,myDEMAArray);
   double lastClose=(priceArray[1].close);
   double DEMAVal = NormalizeDouble(myDEMAArray[1],_Digits);
   double prevClose=(priceArray[2].close);
   double prevDEMAVal = NormalizeDouble(myDEMAArray[2],_Digits);
   int bars=iBars(_Symbol,timeFrame);
   if(barsTotal != bars)
     {
      barsTotal=bars;
      if(lastClose>DEMAVal && prevClose<prevDEMAVal)
        {
         trade.PositionClose(_Symbol);
         trade.Buy(lotSize,_Symbol,Ask,0,0,NULL);
        }
      if(lastClose<DEMAVal && prevClose>prevDEMAVal)
        {
         trade.PositionClose(_Symbol);
         trade.Sell(lotSize,_Symbol,Bid,0,0,NULL);
        }
     }
  }
//+------------------------------------------------------------------+

Dopo aver compilato questo codice, possiamo effettuare il backtest sullo stesso periodo utilizzato per gli altri tipi precedenti e l'impostazione o gli input di questo indicatore saranno i seguenti:

  • Dimensione del lotto = 1
  • Time frame = 1 ora
  • Periodo MA = 50

Dopo aver eseguito il test, si ottengono i seguenti risultati:

Risultati DEMA

Come si può vedere, le figure seguenti devono essere studiate dopo aver testato iDEMA:

  • Utile netto: - 961,60 (- 9,62%)
  • Saldo DD relativo: 39.62%
  • Equity DD relativo: 41.15%
  • Fattore di profitto: 0.97
  • Profitto atteso: -3.12
  • Fattore di recupero: - 0.18
  • Indice di Sharpe: - 0.21

Tripla Media Mobile Esponenziale (iTEMA)

Ora identificheremo un altro tipo di media mobile, la Tripla Media Mobile Esponenziale (TEMA), sviluppata da Patrick Mulloy per aggiungere maggiore reattività all'indicatore e renderlo adatto al trading a breve termine. In questo indicatore utilizziamo EMA a tripla attenuazione, EMA singole e EMA a doppia attenuazione. Quindi, questo indicatore sarà più vicino al prezzo per essere più reattivo, come abbiamo detto. Così come abbiamo utilizzato la doppia media mobile esponenziale, possiamo utilizzare la TEMA allo stesso modo, oltre alla sua risposta più rapida al prezzo, può essere utilizzata per identificare la tendenza e i punti di inversione o i cambiamenti nel trend.

Di seguito sono riportati i passaggi per il calcolo dell'indicatore TEMA:

1. Calcolo della prima Media Mobile Esponenziale (EMA)

EMA uno = EMA di n periodi di prezzo

2. Calcolo dell'EMA di EMA uno

EMA due = EMA di EMA uno

3. Calcolo dell'EMA di EMA due

EMA tre = EMA di EMA due

4. Calcolo di TEMA

DEMA = (3 * EMA uno) - (3 * EMA due) + (EMA3)

Possiamo inserire questo indicatore tra gli indicatori tecnici già pronti disponibili nella MetaTrader 5, senza doverlo calcolare manualmente, quindi dobbiamo creare il nostro sistema di trading utilizzando questo indicatore TEMA per testarlo e confrontare i suoi risultati con gli altri tipi. Di seguito è riportato il codice completo per creare questo sistema di trading come abbiamo fatto in precedenza, con la differenza di utilizzare la funzione iTEMA che restituisce l'handle dell'indicatore Triple Exponential Moving Average (Tripla Media Mobile Esponenziale) e i suoi parametri sono gli stessi di quelli menzionati per DEMA e SMA.

//+------------------------------------------------------------------+
//|                                                 iTEMA_System.mq5 |
//+------------------------------------------------------------------+
#include <Trade\Trade.mqh>
input double lotSize = 1;
input ENUM_TIMEFRAMES timeFrame = PERIOD_H1;
input int MAPeriod= 50;
int TEMA;
int barsTotal;
CTrade trade;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   TEMA = iTEMA(_Symbol, timeFrame, MAPeriod,0, PRICE_CLOSE);
   barsTotal=iBars(_Symbol,timeFrame);
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   MqlRates priceArray[];
   double myTEMAArray[];
   double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
   double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
   ArraySetAsSeries(priceArray,true);
   ArraySetAsSeries(myTEMAArray,true);
   int Data=CopyRates(_Symbol,timeFrame,0,3,priceArray);
   CopyBuffer(TEMA,0,0,3,myTEMAArray);
   double lastClose=(priceArray[1].close);
   double TEMAVal = NormalizeDouble(myTEMAArray[1],_Digits);
   double prevClose=(priceArray[2].close);
   double prevTEMAVal = NormalizeDouble(myTEMAArray[2],_Digits);
   int bars=iBars(_Symbol,timeFrame);
   if(barsTotal != bars)
     {
      barsTotal=bars;
      if(lastClose>TEMAVal && prevClose<prevTEMAVal)
        {
         trade.PositionClose(_Symbol);
         trade.Buy(lotSize,_Symbol,Ask,0,0,NULL);
        }
      if(lastClose<TEMAVal && prevClose>prevTEMAVal)
        {
         trade.PositionClose(_Symbol);
         trade.Sell(lotSize,_Symbol,Bid,0,0,NULL);
        }
     }
  }
//+------------------------------------------------------------------+

Dopo la compilazione e l'esecuzione di questo software, possiamo eseguire un backtest sullo stesso periodo per confrontare i suoi risultati con gli altri tipi di media mobile e di seguito sono riportate le impostazioni o gli input che verranno utilizzati per provare a consentire la correzione di tutti i parametri in questo processo di test:

  • Dimensione del lotto = 1
  • Time frame = 1 ora
  • Periodo MA = 50

Dopo aver eseguito e completato questo test, si ottengono risultati simili ai seguenti:

Risultati TEMA

Come si può vedere, le figure seguenti devono essere studiate:

  • Utile Netto: - 3973,10 (- 39.74%)
  • Saldo DD relativo: 63.98%
  • Equity DD relativo: 66.06%
  • Fattore di profitto: 0.90
  • Profitto Atteso: - 10.59
  • Fattore di recupero: - 0.52
  • Indice di Sharpe: - 0.83

Media Mobile Adattativa Frattale (iFrAMA)

Abbiamo l'ultimo tipo di media mobile che dobbiamo identificare in questo articolo. Si tratta dell'indicatore Media Mobile Adattativa Frattale (FrAMA), sviluppato da John Ehlers. Si tratta di un indicatore trend-following e suppone che i prezzi di mercato siano frattali. Può essere utilizzato anche per individuare tendenze e punti di inversione. Di seguito sono riportati i passaggi per il calcolarla:

 FrAMA

Possiamo inserire questo indicatore dagli indicatori tecnici già pronti disponibili nella MetaTrader 5. Ora dobbiamo creare lo stesso sistema di trading con la stessa strategia, ma utilizzeremo invece l'indicatore FrAMA per confrontare i suoi risultati dopo averli testati con gli altri tipi. La strategia si basa sull'incrocio tra il prezzo e l'indicatore FrAMA: quando il prezzo incrocia sopra FrAMA sarà un segnale di acquisto e quando incrocia sotto FrAMA è un segnale di vendita.

Segnale d’acquisto:

Il prezzo di chiusura è superiore al valore della media mobile adattiva frattale (FrAMA)

E il prezzo di chiusura precedente era inferiore al valore FrAMA precedente.

Segnale di vendita:

Il prezzo di chiusura è inferiore al valore FrAMA

E il prezzo di chiusura precedente era superiore al valore FrAMA precedente.

Di seguito è riportato il codice completo per creare questo sistema di trading, che sarà identico a quello citato in precedenza negli altri tipi, ma utilizzeremo la funzione (iFrAMA) che restituisce l'handle della media mobile adattativa frattale e i suoi parametri sono:

  • symbol: per specificare il nome del simbolo, utilizzeremo _Symbol per il simbolo corrente
  • period: per specificare il time frame, utilizzeremo l'input dell'utente con un valore predefinito di 1 ora
  • ma_period: per specificare il periodo della media mobile, utilizzeremo l'input dell'utente con un valore predefinito di 50
  • ma_shift: per specificare lo spostamento orizzontale, useremo 0 
  • applied_price: per specificare il tipo di prezzo, useremo il prezzo di chiusura
//+------------------------------------------------------------------+
//|                                                iFrAMA_System.mq5 |
//+------------------------------------------------------------------+
#include <Trade\Trade.mqh>
input double lotSize = 1;
input ENUM_TIMEFRAMES timeFrame = PERIOD_H1;
input int MAPeriod= 50;
int FrAMA;
int barsTotal;
CTrade trade;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   FrAMA = iFrAMA(_Symbol, timeFrame, MAPeriod,0, PRICE_CLOSE);
   barsTotal=iBars(_Symbol,timeFrame);
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   MqlRates priceArray[];
   double myFrAMAArray[];
   double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
   double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
   ArraySetAsSeries(priceArray,true);
   ArraySetAsSeries(myFrAMAArray,true);
   int Data=CopyRates(_Symbol,timeFrame,0,3,priceArray);
   CopyBuffer(FrAMA,0,0,3,myFrAMAArray);
   double lastClose=(priceArray[1].close);
   double FrAMAVal = NormalizeDouble(myFrAMAArray[1],_Digits);
   double prevClose=(priceArray[2].close);
   double prevFrAMAVal = NormalizeDouble(myFrAMAArray[2],_Digits);
   int bars=iBars(_Symbol,timeFrame);
   if(barsTotal != bars)
     {
      barsTotal=bars;
      if(lastClose>FrAMAVal && prevClose<prevFrAMAVal)
        {
         trade.PositionClose(_Symbol);
         trade.Buy(lotSize,_Symbol,Ask,0,0,NULL);
        }
      if(lastClose<FrAMAVal && prevClose>prevFrAMAVal)
        {
         trade.PositionClose(_Symbol);
         trade.Sell(lotSize,_Symbol,Bid,0,0,NULL);
        }
     }
  }
//+------------------------------------------------------------------+

Dopo aver compilato ed eseguito questo EA, testeremo questa strategia utilizzando l'indicatore FrAMA con le seguenti impostazioni o input:

  • Dimensioni del lotto: 1
  • Time frame: 1 ora
  • Periodo MA: 50

Proviamo questo EA nello stesso periodo di tutte le altre medie mobili menzionate e otteniamo i seguenti risultati:

Risultati di FrAMA

Come si può notare, le cifre più importanti da studiare sono le seguenti:

  • Utile netto: - 2993.70 (- 29.94%)
  • Saldo DD relativo: 73.28%
  • Equity DD relativo: 74.81%
  • Fattore di profitto: 0.93
  • Profitto atteso: -6.45
  • Fattore di recupero: - 0.33
  • Indice di Sharpe: - 0.46

Confronto dei Risultati con i Risultati della Media Mobile Semplice (SMA)

In questa parte, fornirò un confronto dei risultati per ogni tipo di media mobile menzionata e dovete sapere che cercherò di fornire i migliori risultati possibili, ma ogni media mobile può dare risultati diversi se la ottimizziamo e cambiamo i periodi o i periodi testati, poiché sappiamo che la media mobile può dare risultati differenti in base alle impostazioni dell'indicatore e alle condizioni del mercato.

L'obiettivo principale è fornire le stesse condizioni il più possibile per vedere se c'è un tipo migliore di altri con le migliori impostazioni che possiamo scegliere dal nostro punto di vista. Ma per capire cosa stiamo cercando dobbiamo vedere le misure più importanti nelle loro massime prestazioni:

  • Utile Netto: Il valore più alto è il migliore
  • Drawdown (DD): Il più basso è il migliore
  • Fattore di Profitto: Il più alto è il migliore
  • Profitto Atteso: Il valore più alto è il migliore
  • Fattore di Recupero: Quello più alto è il migliore
  • Indice di Sharpe: Lo Sharpe Ratio più elevato è il migliore

Ora confronteremo i risultati della precedente media mobile semplice con altri tipi di media mobile sulla base di questo contesto attraverso la seguente tabella:

Misura SMA AMA DEMA TEMA FrAMA
Utile Netto 2700.30 (27%) 3638.20 (36.39%) - 961.60 (- 9.62%) - 3973.10 (- 39.74%) - 2993.70 (- 29.94%)
Saldo Drawdown Relativo: 37.07% 22.48% 39.62% 63.98% 73.28%
Equity Drawdown Relativo:  41.76% 35.53% 41.15% 66.06% 74.81%
Fattore di Profitto 1.10 1.31 0.97 0.90 0.93
Profitto Atteso 12.68 35.67 - 3.12 - 10.59 - 6.45
Fattore di Recupero 0.45 0.65 - 0.18 - 0.52 - 0.33
Indice di Sharpe 0.57 0.86 - 0.21 - 0.83 - 0.46

In base ai risultati di tutti i nostri test, abbiamo due tipi che hanno le migliori prestazioni in base alle impostazioni e al periodo di prova. Si tratta della media mobile semplice e della media mobile adattiva. La migliore è la media mobile adattiva. Possiede:

  • L'utile netto più elevato
  • Il DD Relativo al saldo più basso
  • Il DD Relativo all’equity più basso
  • Il miglior Fattore di Profitto
  • Il più alto Profitto Atteso
  • Il Fattore di Recupero più elevato
  • Il più alto Sharpe Ratio

Come abbiamo detto in precedenza, potremmo ottenere risultati migliori con una maggiore ottimizzazione delle impostazioni e delle strategie, ma l'obiettivo è quello di comprendere e applicare il processo di test su un esempio reale, per poi poter utilizzare lo stesso processo per qualsiasi scopo di test.

Conclusioni

In questo articolo abbiamo considerato i risultati delle performance dei seguenti tipi di media mobile:

  • La Media Mobile Adattiva (AMA)
  • La Doppia Media Mobile Esponenziale (DEMA)
  • La Tripla Media Mobile Esponenziale (TEMA)
  • La Media Mobile Adattativa Frattale (FrAMA)

Abbiamo creato sistemi di trading per ogni tipo e confrontato i loro risultati con la media mobile semplice, che è il tipo di media mobile più popolare. In base ai risultati dei test, abbiamo scoperto che i risultati migliori sono stati generati dalla media mobile semplice e dalla media mobile adattiva, di cui la migliore è quella adattiva (AMA). Abbiamo analizzato e confrontato le seguenti metriche per identificare il vincitore:

  • Utile Netto
  • Drawdown (DD)
  • Fattore di Profitto
  • Profitto Atteso
  • Fattore di Recupero
  • Indice di Sharpe

I test sono un argomento molto importante nel trading. Pertanto, vi incoraggio a eseguire più test su più strategie. Oltre a valutare la strategia in sé, può farvi ottenere delle intuizioni inaspettate, poiché ogni test approfondisce la vostra comprensione.

Grazie per il tempo dedicato alla lettura di questo articolo. Spero che questo articolo vi sia stato utile e che abbia aggiunto valore alle vostre conoscenze. Se volete leggere altri articoli sulla creazione di sistemi di trading basati sugli indicatori tecnici popolari come RSI, MACD, Stocastico, Bande di Bollinger e altri argomenti, potete consultare i miei articoli attraverso le Pubblicazioni, spero che anche voi li troviate utili.

Tradotto dall’inglese da MetaQuotes Ltd.
Articolo originale: https://www.mql5.com/en/articles/13130

File allegati |
SMA_System.mq5 (2.07 KB)
iAMA_System.mq5 (2.15 KB)
iDEMA_System.mq5 (2.06 KB)
iTEMA_System.mq5 (2.06 KB)
iFrAMA_System.mq5 (2.08 KB)
Ultimi commenti | Vai alla discussione (1)
go123
go123 | 26 feb 2024 a 03:27
È possibile ottenere un profitto utilizzando solo una media adattiva per il forex a ciclo di 1 ora? Perché sto perdendo denaro con la maggior parte degli elementi del forex quando faccio il backtest?
Comprendere il piazzamento degli ordini in MQL5 Comprendere il piazzamento degli ordini in MQL5
Quando si crea un qualsiasi sistema di trading, c'è un compito che dobbiamo affrontare in modo efficace. Questo compito è l'inserimento degli ordini o la gestione automatica degli ordini da parte del sistema di trading creato, perché è fondamentale in qualsiasi sistema. In questo articolo troverete quindi la maggior parte degli argomenti che dovete comprendere per creare il vostro sistema di trading in termini di inserimento degli ordini in modo efficiente.
Introduzione a MQL5 Algo Forge Introduzione a MQL5 Algo Forge
Stiamo introducendo MQL5 Algo Forge - un portale dedicato agli sviluppatori di trading algoritmico. Combina la potenza di Git con un'interfaccia intuitiva per gestire e organizzare i progetti all'interno dell'ecosistema MQL5. Qui è possibile seguire autori interessanti, formare team e collaborare a progetti di trading algoritmico.
Passaggio a MQL5 Algo Forge (parte 1): Creazione del repository principale Passaggio a MQL5 Algo Forge (parte 1): Creazione del repository principale
Quando si lavora su progetti in MetaEditor, gli sviluppatori si trovano spesso a dover gestire le versioni del codice. MetaQuotes ha recentemente annunciato la migrazione a GIT e il lancio di MQL5 Algo Forge con funzionalità di controllo delle versioni del codice e di collaborazione. In questo articolo discuteremo come utilizzare in modo più efficiente i nuovi strumenti e quelli già esistenti.
Tutto quello che c'è da apprendere sulla struttura del programma MQL5 Tutto quello che c'è da apprendere sulla struttura del programma MQL5
Qualsiasi programma in qualsiasi linguaggio di programmazione ha una struttura specifica. In questo articolo, imparerete le parti essenziali della struttura del programma MQL5, comprendendo le basi della programmazione di ogni parte della struttura del programma MQL5 che può essere molto utile quando creiamo il nostro sistema di trading MQL5 o strumento di trading che può essere eseguito nella MetaTrader 5.