English Русский 中文 Español Deutsch 日本語 Português 한국어 Français Türkçe
preview
Come individuare i trend e i pattern grafici utilizzando MQL5

Come individuare i trend e i pattern grafici utilizzando MQL5

MetaTrader 5Trading | 10 gennaio 2025, 14:56
500 0
Mohamed Abdelmaaboud
Mohamed Abdelmaaboud

Introduzione

Come trader, tutti noi abbiamo a che fare con i grafici e cerchiamo di leggerli correttamente per poter avere un vantaggio nel comprendere i diversi scenari che possono verificarsi nell'azione dei prezzi per prendere la decisione giusta. Perché il grafico contiene molti pattern che possono apparire e che sono utili per prevedere un potenziale movimento del prezzo se li comprendiamo. Quindi, se disponiamo di strumenti utili che possono aiutarci a farlo in modo semplice e accurato, credo sia una buona cosa. In questo articolo, proverò a darvi alcuni strumenti utili in questo contesto, in quanto fornirò come individuare qualcosa che appare sul grafico, ovvero i pattern di prezzo che tutti noi dobbiamo leggere; questi pattern sono gli stessi dei trend o pattern grafici che possono formarsi dall'azione dei prezzi.

Ne parleremo attraverso i seguenti argomenti: 

Dopo aver letto questo articolo, sarete in grado di individuare i massimi e i minimi, di identificare i tipi di trend, e di conseguenza i doppi massimi e minimi. Quindi, dovete provare a scrivere i codici citati da soli e dovete testare e sviluppare ciò che vi serve per ottenere approfondimenti e risultati migliori prima di utilizzarli sul vostro conto reale. L'obiettivo principale di questo articolo è quello di comprendere l'idea principale del rilevamento dei massimi e minimi e dei pattern grafici per sviluppare il vostro codice sempre di più per rilevare ciò che vi serve tra i pattern significativi noti o sconosciuti, poiché ci sono molti pattern rilevanti che possono essere visti sul grafico e che possono cambiare le carte in tavola per il vostro trading se capite come trarne vantaggio.

In questo articolo utilizzeremo l'IDE MQL5 (MetaQuotes Language) che è integrato nel terminale di trading MetaTrader 5. Se non sapete come usare MQL5 e volete imparare come scaricare MetaTrader 5 e usare MQL5 per scrivere codici, potete leggere l'argomento Scrivere codice MQL5 in MetaEditor da un mio articolo precedente.

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.

Rilevamento dei massimi e dei minimi

In questa parte, inizieremo a rilevare i massimi e i minimi sul grafico con MQL5 poi li utilizzeremo come base per dichiarare le nostre condizioni come base per ciascun pattern grafico. In primo luogo, come tutti sappiamo, le definizioni di massimi e minimi sono le seguenti:

Massimi:

Massimo significa che c'è stato un movimento verso l'alto fino a un livello specifico a causa della forza dei compratori, poi i venditori compaiono e spingono il prezzo verso il basso da questo livello alto. La figura seguente è un esempio.   

Massimo

Minimi:

Minimo significa che c'è stato un movimento al ribasso fino a un livello specifico a causa della forza dei venditori, poi i compratori compaiono e spingono il prezzo verso l'alto da questo livello basso. La figura seguente è un esempio.

Minimo

Dopo aver identificato questi due importanti livelli di prezzo, dobbiamo creare un programma MQL5 o un Expert Advisor in grado di rilevare questi tipi di movimenti. Ci sono molti metodi che possono essere utilizzati per farlo e noi ne forniremo uno nelle righe seguenti.

Dobbiamo determinare livelli di prezzo specifici (massimo e minimo), poi ci dirigeremo verso altri livelli di prezzo specifici (massimo e minimo) e confronteremo il massimo con il massimo e il minimo con il minimo per determinare se abbiamo un altro massimo o un altro minimo. A tal fine, è necessario seguire fasi specifiche, come quella descritta di seguito.

Creare una funzione in OnTick() per restituire il massimo o il minimo. La chiameremo (getNextMove) come una variabile intera e i parametri che dobbiamo impostare per questa funzione sono:

  • int move: per determinare il movimento se è massimo o minimo.
  • int count: per determinare il conteggio relativo alla variabile startPos.
  • int startPos: per determinare la posizione iniziale da cui partire.
int getNextMove(int move, int count, int startPos)

All'interno di questa funzione dobbiamo effettuare il seguente controllo utilizzando l'istruzione if per identificare il valore dei parametri della funzione, dobbiamo verificare se il valore (startPos) è minore di zero, dobbiamo aggiungere il valore startPos al valore del conteggio e aggiornare startPos con il valore zero per iniziare dalla barra corrente.

   if(startPos<0)
     {
      count +=startPos;
      startPos =0;
     }

Ora, abbiamo identificato le variabili (count) e (startPos) nella funzione. La variabile (move) sarà identificata nel valore restituito utilizzando l'operatore return che termina l'esecuzione della funzione e restituisce il valore move utilizzando l'operatore ternario (?:) che consiste in tre espressioni, la prima delle quali restituisce dati di tipo bool e se vera verrà eseguita la seconda espressione, mentre se falsa verrà eseguita la terza espressione.

Quindi, specificheremo se la variabile move è uguale a high e se vera, verrà restituito il valore più alto (High) e se falsa, verrà restituito il valore più basso (Low).

Per verificare se move è high utilizzeremo le funzioni MODE_HIGH, che è uno degli identificatori delle serie temporali utilizzati nelle funzioni iHighest() e iLowest() per restituire il prezzo high. Per i parametri delle funzioni iHighest e iLowest, che devono restituire l'indice del valore più alto e di quello più basso è necessario procedere come segue:

  • symbol: useremo Symbol() per restituire il nome del simbolo corrente come const string.
  • timeframe: utilizzeremo Period() che restituisce il time frame corrente come ENUM_TIMEFRAMES.
  • type: useremo (ENUM_SERIESMODE) move per restituire il tipo di movimento come identificatore della serie temporale. Questo tipo di valore sarà il massimo per iHighest e il minimo per iLowest.
  • count: utilizzeremo la variabile intera (count) per restituire il numero di elementi.
  • start: utilizzeremo la variabile intera (startPos) per restituire l'indice.
   return((move==MODE_HIGH)?
          iHighest(Symbol(),Period(),(ENUM_SERIESMODE)move,count,startPos):
          iLowest(Symbol(),Period(),(ENUM_SERIESMODE)move,count,startPos));

Dopo aver creato questa funzione che restituirà il move successivo, creeremo un'altra funzione intera che sarà la principale per ottenere il massimo o il minimo del corrente move. Il suo nome sarà (getmove) con tre variabili intere come parametri (move, count e startPos).

int getmove(int move, int count, int startPos)

All'interno di questa funzione dobbiamo controllare se move è diverso da MODE_HIGH o MODE_LOW, il valore restituito sarà (-1).

if(move!=MODE_HIGH && move!=MODE_LOW)
      return (-1);

Creare una nuova variabile intera (currentBar) e assegnarle (startPos).

int currentBar=startPos;

Creare una nuova variabile intera (moveReturned) e assegnarle la funzione creata getNextMove con i seguenti parametri (move, (count*2+1), currentBar-count)).

int moveReturned=getNextMove(move,count*2+1,currentBar-count);

Creare un ciclo utilizzando While per controllare un'espressione e se questa è vera, l'operatore verrà eseguito. In questo caso l'espressione da controllare è se moveReturned non è uguale a currentBar e se è vera gli operatori che dobbiamo eseguire sono:

  • Aggiornamento della variabile (currentBar) con getNextMove con i parametri (move, count,currentBar+1).
  • Aggiornamento della variabile (moveReturned) con getNextMove con i parametri (move,count*2+1,currentBar-count).
   while(moveReturned!=currentBar)
     {
      currentBar=getNextMove(move,count,currentBar+1);
      moveReturned=getNextMove(move,count*2+1,currentBar-count);
     }

Utilizzate quindi la funzione return per terminare la funzione restituendo il valore di currentBar

return(currentBar);

Poi, andremo all'interno di OnTick() e chiameremo ciò che ci ha aiutato a rilevare i massimi e i minimi. Per prima cosa creeremo tre variabili intere

   int checkBars= 5; 
   int move1;
   int move2;

Aggiornamento di move1 e move2 con la funzione getmove creata in precedenza con i parametri (MODE_HIGH,checkBars,0) per move1 e (MODE_HIGH,checkBars,move1+1) per move2 per rilevare i due massimi.

   move1=getmove(MODE_HIGH,checkBars,0);
   move2=getmove(MODE_HIGH,checkBars,move1+1);

Creare un oggetto linea al di sopra di questi due massimi con i seguenti passaggi:

L'eliminazione di qualsiasi linea esistente avviene tramite il comando (ObjectDelete), che rimuove un oggetto con un nome. Ci sono dei parametri per questa funzione, il primo è chart_id per determinare l'identificatore del grafico e useremo 0 per il grafico corrente. Il secondo parametro è name, per determinare il nome dell'oggetto useremo topLine come stringa.

ObjectDelete(0,"topLine");

Creare un nuovo oggetto topLine utilizzando la funzione ObjectCreate che crea un oggetto con un nuovo nome. I suoi parametri sono:

  • chart_id: utilizzeremo (0) per restituire un tipo long come identificatore del grafico.
  • name: useremo "topLine" per restituire un tipo string come nome dell'oggetto.
  • type: useremo OBJ_TREND per restituire un tipo ENUM_OBJECT o il tipo di oggetto.
  • nwin: utilizzeremo (0) per il grafico corrente come indice della finestra.
  • time1: per determinare l'ora dell'ancoraggio move2 e restituire il tipo datetime, useremo iTime(Symbol(),Period(),move2)
  • price1: per determinare il prezzo dell'ancoraggio move2 e restituire il tipo double, utilizzeremo iHigh(Symbol(),Period(),move2).
  • timeN=0: per determinare l'ora dell'ancoraggio move1 e restituire il tipo datetime, utilizzeremo iTime(Symbol(),Period(),move1).
  • priceN=0: per determinare il prezzo dell'ancoraggio move1 e restituire il tipo double, utilizzeremo iHigh(Symbol(),Period(),move1).

Come possiamo vedere, la funzione iHigh restituisce il prezzo massimo della barra e i suoi parametri sono symbol, timeframe e shift. La funzione iTime restituisce l'ora di apertura della barra e i suoi parametri sono gli stessi della funzione iHigh.

ObjectCreate(0,"topLine",OBJ_TREND,0,iTime(Symbol(),Period(),move2),iHigh(Symbol(),Period(),move2),iTime(Symbol(),Period(),move1),iHigh(Symbol(),Period(),move1));

Impostazione di un colore, di una larghezza specifica e di un tipo di linea per questo oggetto creato, utilizzando la funzione ObjectSetInteger. I suoi parametri sono:

  • chart_id: per determinare l'identificativo del grafico, che sarà (0).
  • name: è il nome dell'oggetto, che sarà "TopLine" per i massimi.
  • prop_id: per determinare la proprietà dell'oggetto, sarà OBJPROP_COLOR per il colore, OBJPROP_WIDTH per la larghezza e OBJPROP_RAY_RIGHT per il tipo di linea.
  • prop_value: per determinare il valore desiderato, sarà clrRed per il colore, 3 per la larghezza e true per il tipo di linea.
   ObjectSetInteger(0,"topLine",OBJPROP_COLOR,clrRed);
   ObjectSetInteger(0,"topLine",OBJPROP_WIDTH,3);
   ObjectSetInteger(0,"topLine",OBJPROP_RAY_RIGHT,true);

Ottenere i due minimi aggiornando le variabili move1 e move2 come abbiamo fatto per i massimi, ma la modalità sarà MODE_LOW come identificatore della serie temporale.

   move1=getmove(MODE_LOW,checkBars,0);
   move2=getmove(MODE_LOW,checkBars,move1+1);

L’eliminazione e creazione dell'oggetto linea al di sotto di questi due minimi è identica a quella effettuata per i massimi, ma con alcune differenze nel nome dell'oggetto, che sarà "bottomLine", e nel colore verde.

   ObjectDelete(0,"bottomLine");
   ObjectCreate(0,"bottomLine",OBJ_TREND,0,iTime(Symbol(),Period(),move2),iLow(Symbol(),Period(),move2),iTime(Symbol(),Period(),move1),iLow(Symbol(),Period(),move1));
   ObjectSetInteger(0,"bottomLine",OBJPROP_COLOR,clrGreen);
   ObjectSetInteger(0,"bottomLine",OBJPROP_WIDTH,3);
   ObjectSetInteger(0,"bottomLine",OBJPROP_RAY_RIGHT,true);

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

//+------------------------------------------------------------------+
//|                                                   moveFinder.mq5 |
//|                                  Copyright 2023, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
//+------------------------------------------------------------------+
void OnTick()
  {
   int checkBars= 5; 
   int move1;
   int move2;
   move1=getmove(MODE_HIGH,checkBars,0);
   move2=getmove(MODE_HIGH,checkBars,move1+1);
   ObjectDelete(0,"topLine");
   ObjectCreate(0,"topLine",OBJ_TREND,0,iTime(Symbol(),Period(),move2),iHigh(Symbol(),Period(),move2),iTime(Symbol(),Period(),move1),iHigh(Symbol(),Period(),move1));
   ObjectSetInteger(0,"topLine",OBJPROP_COLOR,clrRed);
   ObjectSetInteger(0,"topLine",OBJPROP_WIDTH,3);
   ObjectSetInteger(0,"topLine",OBJPROP_RAY_RIGHT,true);
   move1=getmove(MODE_LOW,checkBars,0);
   move2=getmove(MODE_LOW,checkBars,move1+1);
   ObjectDelete(0,"bottomLine");
   ObjectCreate(0,"bottomLine",OBJ_TREND,0,iTime(Symbol(),Period(),move2),iLow(Symbol(),Period(),move2),iTime(Symbol(),Period(),move1),iLow(Symbol(),Period(),move1));
   ObjectSetInteger(0,"bottomLine",OBJPROP_COLOR,clrGreen);
   ObjectSetInteger(0,"bottomLine",OBJPROP_WIDTH,3);
   ObjectSetInteger(0,"bottomLine",OBJPROP_RAY_RIGHT,true);
  }
int getmove(int move, int count, int startPos)
  {
   if(move!=MODE_HIGH && move!=MODE_LOW)
      return (-1);
   int currentBar=startPos;
   int moveReturned=getNextMove(move,count*2+1,currentBar-count);
   while(moveReturned!=currentBar)
     {
      currentBar=getNextMove(move,count,currentBar+1);
      moveReturned=getNextMove(move,count*2+1,currentBar-count);
     }
   return(currentBar);
  }
int getNextMove(int move, int count, int startPos)
  {
   if(startPos<0)
     {
      count +=startPos;
      startPos =0;
     }
   return((move==MODE_HIGH)?
          iHighest(Symbol(),Period(),(ENUM_SERIESMODE)move,count,startPos):
          iLowest(Symbol(),Period(),(ENUM_SERIESMODE)move,count,startPos));
  }

Dopo aver compilato questo codice senza errori ed averlo eseguito, possiamo ottenere due linee sul grafico per individuare due massimi con una linea rossa sopra di essi e due minimi con una linea verde sotto di essi. I seguenti sono esempi di test:

segnale1 moveFinder

Come possiamo vedere nell'esempio precedente, queste due linee possono mostrare un pattern sul grafico anche per indicare il movimento del prezzo, possiamo vedere nella precedente immagine che abbiamo un forte movimento verso l'alto dato che abbiamo due linee ascendenti e l'angolo di quella superiore è più ampio di quella inferiore. Quindi, possono essere uno strumento molto utile per interpretare l'azione dei prezzi.

Di seguito è riportato un altro esempio con un pattern differente in base a un'azione di prezzo diversa:

 segnale2 moveFinder

Come possiamo vedere nel grafico precedente, abbiamo un'azione di prezzo diversa che indica un movimento differente, in quanto abbiamo due linee che si muovono parallelamente, ma la linea inferiore si muove verso l'alto e quella superiore verso il basso, indicando che c'è un equilibrio tra compratori e venditori, in quanto i compratori spingono il prezzo verso l'alto e i venditori allo stesso tempo lo spingono verso il basso.

Anche il successivo è un esempio di un altro pattern di azione dei prezzi:

segnale3 moveFinder

Come possiamo vedere nel grafico precedente, abbiamo un pattern grafico diverso, con due linee parallele discendenti che possono indicare la forza dei venditori, in grado di spingere i prezzi verso il basso.

Dopo aver appreso come rilevare i massimi e i minimi sul grafico nella parte precedente, possiamo sviluppare questo codice per rilevare i trend, poiché abbiamo rilevato due massimi e due minimi e questo è ciò che ci serve per identificare il trend. Quanto segue in questa parte dell'articolo riguarda lo sviluppo del nostro codice precedente per rilevare il trend sul grafico nei suoi tre tipi, utilizzandolo il più possibile ma con alcune differenze.

Semplicemente, i trend sono il movimento dell'azione dei prezzi, che può essere al rialzo, al ribasso o senza una chiara direzione né al rialzo né al ribasso e questi sono tre tipi di trend come i seguenti:

Trend rialzista:

Questo tipo di movimento dei prezzi fa sì che i prezzi continuino a muoversi verso l'alto, raggiungendo prezzi più alti, poiché i compratori sono la parte forte del mercato. Quindi, sul grafico possiamo notare che il prezzo forma chiaramente minimi e massimi crescenti. La figura seguente rappresenta un grafico di questo tipo:

Trend rialzista

Trend ribassista:

Questo tipo di trend è lo scenario opposto a quello del trend rialzista, in quanto in questo tipo di trend ribassista i venditori sono più forti dei compratori e spingono i prezzi verso il basso, raggiungendo un prezzo inferiore. Quindi, possiamo vedere sul grafico che i prezzi formano massimi e minimi decrescenti.

Di seguito viene riportato un grafico che lo descrive da un punto di vista visivo:

Trend ribassista

Lateralità:

In questo tipo, non è possibile trovare un movimento di prezzo che possa essere descritto come un trend rialzista o ribassista. Quindi, questo tipo è qualsiasi forma, tranne quella del trend rialzista o del trend ribassista, e ha molte forme; le figure seguenti sono alcune di queste forme:

noTrend noTrend2 noTrend3

Ora, dobbiamo creare un EA MQL5 in grado di rilevare se abbiamo un trend (al rialzo o al ribasso) o se non abbiamo un trend (lateralità). Il codice seguente serve a creare questo tipo di EA:

//+------------------------------------------------------------------+
//|                                                  trendFinder.mq5 |
//|                                  Copyright 2023, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
//+------------------------------------------------------------------+
void OnTick()
  {
   int checkBars= 5;
   int high1, high2, low1, low2;
   double highVal1, highVal2, lowVal1, lowVal2;
   high1=getmove(MODE_HIGH,checkBars,0);
   high2=getmove(MODE_HIGH,checkBars,high1+1);
   highVal1=NormalizeDouble(iHigh(_Symbol,_Period,high1),5);
   highVal2=NormalizeDouble(iHigh(_Symbol,_Period,high2),5);
   ObjectDelete(0,"topLine");
   ObjectCreate(0,"topLine",OBJ_TREND,0,iTime(Symbol(),Period(),high2),iHigh(Symbol(),Period(),high2),iTime(Symbol(),Period(),high1),iHigh(Symbol(),Period(),high1));
   ObjectSetInteger(0,"topLine",OBJPROP_COLOR,clrRed);
   ObjectSetInteger(0,"topLine",OBJPROP_WIDTH,3);
   ObjectSetInteger(0,"topLine",OBJPROP_RAY_RIGHT,true);
   low1=getmove(MODE_LOW,checkBars,0);
   low2=getmove(MODE_LOW,checkBars,low1+1);
   lowVal1=NormalizeDouble(iLow(_Symbol,_Period,low1),5);
   lowVal2=NormalizeDouble(iLow(_Symbol,_Period,low2),5);
   ObjectDelete(0,"bottomLine");
   ObjectCreate(0,"bottomLine",OBJ_TREND,0,iTime(Symbol(),Period(),low2),iLow(Symbol(),Period(),low2),iTime(Symbol(),Period(),low1),iLow(Symbol(),Period(),low1));
   ObjectSetInteger(0,"bottomLine",OBJPROP_COLOR,clrGreen);
   ObjectSetInteger(0,"bottomLine",OBJPROP_WIDTH,3);
   ObjectSetInteger(0,"bottomLine",OBJPROP_RAY_RIGHT,true);
   if(lowVal1>lowVal2&&highVal1>highVal2)
     {
      Comment("Uptrend",
              "\nCurrent High ",highVal1,"\nPrevious High ",highVal2,
              "\nCurrent Low ",lowVal1,"\nPrevious Low ",lowVal2);
     }
   else
      if(highVal1<highVal2&&lowVal1<lowVal2)
        {
         Comment("Downtrend",
              "\nCurrent High ",highVal1,"\nPrevious High ",highVal2,
              "\nCurrent Low ",lowVal1,"\nPrevious Low ",lowVal2);
        }
      else
        {
         Comment("Sideways",
              "\nCurrent High ",highVal1,"\nPrevious High ",highVal2,
              "\nCurrent Low ",lowVal1,"\nPrevious Low ",lowVal2);
        }
  }
int getmove(int move, int count, int startPos)
  {
   if(move!=MODE_HIGH && move!=MODE_LOW)
      return (-1);
   int currentBar=startPos;
   int moveReturned=getNextMove(move,count*2+1,currentBar-count);
   while(moveReturned!=currentBar)
     {
      currentBar=getNextMove(move,count,currentBar+1);
      moveReturned=getNextMove(move,count*2+1,currentBar-count);
     }
   return(currentBar);
  }
int getNextMove(int move, int count, int startPos)
  {
   if(startPos<0)
     {
      count +=startPos;
      startPos =0;
     }
   return((move==MODE_HIGH)?
          iHighest(Symbol(),Period(),(ENUM_SERIESMODE)move,count,startPos):
          iLowest(Symbol(),Period(),(ENUM_SERIESMODE)move,count,startPos));
  }

Di seguito sono riportate le differenze di questo codice per rilevare i trend.

Creare quattro variabili integer per due massimi e due minimi e altre quattro variabili double per i due valori massimi e i due valori minimi all'interno dell'ambito della funzione OnTick:

   int high1, high2, low1, low2;
   double highVal1, highVal2, lowVal1, lowVal2;

Aggiornare i due valori dei massimi (highVal1, highVal2) utilizzando la funzione NormalizeDouble per arrotondare il risultato del valore dei massimi e i suoi parametri sono:

  • value: il numero che dobbiamo normalizzare; utilizzeremo la funzione iHigh per restituire il prezzo massimo e i suoi parametri sono symbol che sarà (_Symbol) per quello corrente, timeframe che sarà (_Period) per il timeframe corrente e shift per l'indice che sarà high1 e high2.
  • digits: il numero di cifre dopo la virgola decimale, sarà 5.
   highVal1=NormalizeDouble(iHigh(_Symbol,_Period,high1),5);
   highVal2=NormalizeDouble(iHigh(_Symbol,_Period,high2),5);

Aggiornare i due valori minimi (lowVal1, lowVal2) utilizzando la funzione NormalizeDouble con gli stessi parametri indicati in precedenza, con le seguenti differenze:

  • value: utilizza la funzione iLow per restituire il prezzo minimo e i suoi parametri sono gli stessi, tranne lo scostamento dell'indice che sarà low1 e low2.
   lowVal1=NormalizeDouble(iLow(_Symbol,_Period,low1),5);
   lowVal2=NormalizeDouble(iLow(_Symbol,_Period,low2),5);

Per le condizioni che dobbiamo impostare per identificare i trend, utilizzeremo l'istruzione if, dobbiamo lasciare che l'EA verifichi continuamente quattro valori massimi e minimi e decida le loro posizioni in relazione l'una all'altra, per poi decidere se abbiamo un trend (al rialzo o al ribasso) o se non abbiamo un trend (lateralità).

Condizione del trend rialzista:

Se lowVal1 è maggiore di lowVal2 e allo stesso tempo highVal1 è maggiore di highVal2, abbiamo un trend rialzista e abbiamo bisogno che l'EA restituisca un commento sul grafico con quanto segue:

  • Trend rialzista
  • Massimo Corrente
  • Massimo Precedente
  • Minimo Corrente
  • Minimo Precedente
   if(lowVal1>lowVal2&&highVal1>highVal2)
     {
      Comment("Uptrend",
              "\nCurrent High ",highVal1,"\nPrevious High ",highVal2,
              "\nCurrent Low ",lowVal1,"\nPrevious Low ",lowVal2);
     }

Condizione del trend ribassista:

Se highVal1 è inferiore a highVal2 e allo stesso tempo lowVal1 è inferiore a lowVal2, abbiamo una trend ribassista e abbiamo bisogno che l'EA restituisca un commento sul grafico con quanto segue:

  • Trend ribassista
  • Massimo Corrente
  • Massimo Precedente
  • Minimo Corrente
  • Minimo Precedente
   else
      if(highVal1<highVal2&&lowVal1<lowVal2)
        {
         Comment("Downtrend",
              "\nCurrent High ",highVal1,"\nPrevious High ",highVal2,
              "\nCurrent Low ",lowVal1,"\nPrevious Low ",lowVal2);
        }

Condizione di Lateralità:

Se le posizioni dei quattro valori sono diverse dalle condizioni di trend rialzista e trend ribassista, abbiamo una fase laterale e abbiamo bisogno che l'EA restituisca quanto segue come commento sul grafico:

      else
        {
         Comment("Sideways",
              "\nCurrent High ",highVal1,"\nPrevious High ",highVal2,
              "\nCurrent Low ",lowVal1,"\nPrevious Low ",lowVal2);
        }

Dopo aver compilato questo codice senza errori ed eseguito il suo EA, possiamo ricevere i segnali sui trend di cui abbiamo bisogno. Di seguito sono riportati alcuni esempi di test in base al tipo di trend e alle sue condizioni.

Trend rialzista:

trendFinder - Segnale trend rialzista

Nella figura precedente possiamo vedere che abbiamo un esempio di trend rialzista, in quanto abbiamo minimi e massimi crescenti nell’azione del prezzo di questo grafico. Abbiamo quindi ricevuto un segnale di trend rialzista come commento nell'angolo in alto a sinistra del grafico.

Trend ribassista:

trendFinder - Segnale trend ribassista

Come possiamo vedere chiaramente nel grafico precedente, siamo in presenza di un trend ribassista, in quanto abbiamo massimi e minimi decrescenti in base all'azione dei prezzi. Quindi, abbiamo un segnale di trend ribassista come commento sul grafico.

Lateralità:

trendFinder - Segnale laterale

Come possiamo vedere nell'esempio precedente, abbiamo una forma diversa da trend rialzista e trend ribassista e abbiamo massimi decrescenti e minimi crescenti cioè lateralità. Quindi, abbiamo un segnale laterale come commento sul grafico.

Rilevamento del Doppio Massimo del grafico

Dopo aver imparato a rilevare i massimi e i minimi, abbiamo individuato i trend, in base a ciò, sviluppando il codice di base per il rilevamento dei massimi e dei minimi. Quindi, se pensiamo di poter sviluppare di più nel codice possiamo cercare di rilevare specifici pattern grafici o di price action che possono indicare un potenziale movimento.

In questa parte, fornirò un esempio di questi pattern grafici con un piccolo sviluppo del codice per comprendere l'idea principale ed eseguire un maggior sviluppo per individuare pattern più significativi, soprattutto se si uniscono alcuni strumenti tecnici utili nel codice. In questa parte dell'articolo vedremo uno dei modelli grafici più popolari che possono essere visti sul grafico, ovvero i Doppi Massimi.

Il Doppio Massimo è un pattern grafico che possiamo vedere sul grafico e consiste in massimi semi-uguali che indicano una debolezza nel potere d'acquisto e un potenziale movimento dei prezzi verso il basso. Ci sono molti dettagli significativi, ma se citiamo solo la sua forma, è la stessa che abbiamo menzionato. Il grafico seguente è un esempio visivo di un potenziale pattern Doppio Massimo:

Potenziale DT

Se avete notato che nell'esempio precedente abbiamo menzionato che si tratta di un pattern potenziale e che sarà un pattern confermato quando i prezzi romperanno e chiuderanno al di sotto del minimo tra i due massimi, come nel grafico seguente:

DT

Ora, dobbiamo creare un EA MQL5 che possa essere utilizzato per rilevare queste due figure nella MetaTrader 5. Abbiamo bisogno che l'EA controlli continuamente i due massimi e i due minimi e determini la loro posizione in relazione l'uno all'altro e poi restituisca un risultato specifico basato su una condizione specifica che è quella del pattern Doppio Massimo. Qui, cercheremo di descrivere un pattern pratico in modo semplice, in quanto può presentarsi con un massimo leggermente inferiore o superiore, non solo con lo stesso massimo, quindi se il massimo attuale è inferiore o uguale al precedente e allo stesso tempo il minimo attuale è superiore al precedente, questo sarà un segnale di potenziale Doppio Massimo. Se il massimo attuale è inferiore o uguale al precedente e allo stesso tempo il minimo attuale è inferiore al precedente, questo sarà un segnale di Doppio Massimo.

Di seguito è riportato il codice completo per farlo:

//+------------------------------------------------------------------+
//|                                             DT patternFinder.mq5 |
//|                                  Copyright 2023, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
//+------------------------------------------------------------------+
void OnTick()
  {
   int checkBars= 5;
   int high1, high2, low1, low2;
   double highVal1, highVal2, lowVal1, lowVal2;
   high1=getmove(MODE_HIGH,checkBars,0);
   high2=getmove(MODE_HIGH,checkBars,high1+1);
   highVal1=NormalizeDouble(iHigh(_Symbol,_Period,high1),5);
   highVal2=NormalizeDouble(iHigh(_Symbol,_Period,high2),5);
   ObjectDelete(0,"topLine");
   ObjectCreate(0,"topLine",OBJ_TREND,0,iTime(Symbol(),Period(),high2),iHigh(Symbol(),Period(),high2),iTime(Symbol(),Period(),high1),iHigh(Symbol(),Period(),high1));
   ObjectSetInteger(0,"topLine",OBJPROP_COLOR,clrRed);
   ObjectSetInteger(0,"topLine",OBJPROP_WIDTH,3);
   ObjectSetInteger(0,"topLine",OBJPROP_RAY_RIGHT,true);
   low1=getmove(MODE_LOW,checkBars,0);
   low2=getmove(MODE_LOW,checkBars,low1+1);
   lowVal1=NormalizeDouble(iLow(_Symbol,_Period,low1),5);
   lowVal2=NormalizeDouble(iLow(_Symbol,_Period,low2),5);
   ObjectDelete(0,"bottomLine");
   ObjectCreate(0,"bottomLine",OBJ_TREND,0,iTime(Symbol(),Period(),low2),iLow(Symbol(),Period(),low2),iTime(Symbol(),Period(),low1),iLow(Symbol(),Period(),low1));
   ObjectSetInteger(0,"bottomLine",OBJPROP_COLOR,clrGreen);
   ObjectSetInteger(0,"bottomLine",OBJPROP_WIDTH,3);
   ObjectSetInteger(0,"bottomLine",OBJPROP_RAY_RIGHT,true);
   if(highVal1<=highVal2&&lowVal1>lowVal2)
     {
      Comment("Potential Double Top",
              "\nCurrent High ",highVal1,"\nPrevious High ",highVal2,
              "\nCurrent Low ",lowVal1,"\nPrevious Low ",lowVal2);
     }

   else
      if(highVal1<=highVal2&&lowVal1<lowVal2)
        {
         Comment("Double Top",
                 "\nCurrent High ",highVal1,"\nPrevious High ",highVal2,
                 "\nCurrent Low ",lowVal1,"\nPrevious Low ",lowVal2);
        }
      else
         Comment(" ");
  }
int getmove(int move, int count, int startPos)
  {
   if(move!=MODE_HIGH && move!=MODE_LOW)
      return (-1);
   int currentBar=startPos;
   int moveReturned=getNextMove(move,count*2+1,currentBar-count);
   while(moveReturned!=currentBar)
     {
      currentBar=getNextMove(move,count,currentBar+1);
      moveReturned=getNextMove(move,count*2+1,currentBar-count);
     }
   return(currentBar);
  }
int getNextMove(int move, int count, int startPos)
  {
   if(startPos<0)
     {
      count +=startPos;
      startPos =0;
     }
   return((move==MODE_HIGH)?
          iHighest(Symbol(),Period(),(ENUM_SERIESMODE)move,count,startPos):
          iLowest(Symbol(),Period(),(ENUM_SERIESMODE)move,count,startPos));
  }

Le differenze in questo codice sono le condizioni del pattern.

Nel caso di un Potenziale Doppio Massimo, se highVal1 è inferiore o uguale a highVal2 e lowVal1 è superiore a lowVal2, dobbiamo ottenere un segnale come commento sul grafico con i seguenti valori:

  • Potenziale Doppio Massimo
  • Massimo Corrente
  • Massimo Precedente
  • Minimo Corrente
  • Minimo Precedente
   if(highVal1<=highVal2&&lowVal1>lowVal2)
     {
      Comment("Potential Double Top",
              "\nCurrent High ",highVal1,"\nPrevious High ",highVal2,
              "\nCurrent Low ",lowVal1,"\nPrevious Low ",lowVal2);
     }

Nel caso di Doppio Massimo, se highVal1 è inferiore o uguale a highVal2 e lowVal1 è inferiore a lowVal2, dobbiamo ottenere un segnale come commento sul grafico con i seguenti valori:

  • Doppio Massimo
  • Massimo Corrente
  • Massimo Precedente
  • Minimo Corrente
  • Minimo Precedente
   else
      if(highVal1<=highVal2&&lowVal1<lowVal2)
        {
         Comment("Double Top",
                 "\nCurrent High ",highVal1,"\nPrevious High ",highVal2,
                 "\nCurrent Low ",lowVal1,"\nPrevious Low ",lowVal2);
        }

In caso di assenza del potenziale pattern o del doppio massimo, non viene restituito nulla come commento.

      else
         Comment(" ");

Dopo aver compilato questo codice senza errori ed eseguito il suo EA, possiamo trovare il seguente esempio di test come segnali.

Nel caso di Potenziale Doppio Massimo:

Segnale di potenziale DT patternFinder

Come si può vedere nel grafico precedente, abbiamo un potenziale segnale di doppio massimo, in quanto c'è corrispondenza con le condizioni impostate, che sono un minimo superiore e un massimo equivalente.

Nel caso di Doppio Massimo:

 DT patternFinder DT signa

Come si può vedere nel grafico precedente, abbiamo un segnale di doppio massimo in quanto c'è una corrispondenza con le condizioni prestabilite, cioè un massimo inferiore o equivalente e un minimo inferiore.

Rilevamento del Doppio Minimo del Grafico

In questa parte impareremo a individuare il pattern opposto al doppio massimo, ovvero il pattern doppio minimo. Il Doppio Minimo è un pattern grafico che possiamo vedere sul grafico e consiste in minimi semi-uguali che indicano che c'è una debolezza nel potere di vendita e c'è un potenziale movimento dei prezzi verso l'alto, ci sono molti dettagli importanti, ma se parliamo solo della sua forma troveremo che è la stessa che abbiamo menzionato. Il grafico seguente è un esempio visivo di un potenziale pattern Doppio Minimo:

 Potenziale DB

Il precedente potenziale pattern di doppio minimo sarà confermato quando i prezzi romperanno e chiuderanno al di sopra del massimo tra i due minimi, come nel grafico seguente:

DB

È necessario creare un altro EA MQL5 che possa essere utilizzato per rilevare le due figure precedenti nella MetaTrader 5. Abbiamo bisogno che l'EA controlli continuamente i due minimi e i due massimi e determini la loro posizione in relazione l'un l'altro, per poi restituire un risultato specifico in base alla condizione del pattern Doppio Minimo. Lo stesso semplice sviluppo del codice sarà applicato al caso opposto per avvicinarsi a un pattern pratico con un minimo leggermente più alto o più basso non solo lo stesso minimo, quindi se il minimo attuale è superiore o uguale a quello precedente e allo stesso tempo il massimo attuale è inferiore a quello precedente, questo sarà un segnale di potenziale Doppio Minimo. Se il minimo attuale è maggiore o uguale a quello precedente e allo stesso tempo il massimo attuale è superiore a quello precedente, si tratterà di un segnale di Doppio Minimo.

Di seguito è riportato il codice completo per farlo:

//+------------------------------------------------------------------+
//|                                             DB patternFinder.mq5 |
//|                                  Copyright 2023, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
//+------------------------------------------------------------------+
void OnTick()
  {
   int checkBars= 5;
   int high1, high2, low1, low2;
   double highVal1, highVal2, lowVal1, lowVal2;
   high1=getmove(MODE_HIGH,checkBars,0);
   high2=getmove(MODE_HIGH,checkBars,high1+1);
   highVal1=NormalizeDouble(iHigh(_Symbol,_Period,high1),5);
   highVal2=NormalizeDouble(iHigh(_Symbol,_Period,high2),5);
   ObjectDelete(0,"topLine");
   ObjectCreate(0,"topLine",OBJ_TREND,0,iTime(Symbol(),Period(),high2),iHigh(Symbol(),Period(),high2),iTime(Symbol(),Period(),high1),iHigh(Symbol(),Period(),high1));
   ObjectSetInteger(0,"topLine",OBJPROP_COLOR,clrRed);
   ObjectSetInteger(0,"topLine",OBJPROP_WIDTH,3);
   ObjectSetInteger(0,"topLine",OBJPROP_RAY_RIGHT,true);
   low1=getmove(MODE_LOW,checkBars,0);
   low2=getmove(MODE_LOW,checkBars,low1+1);
   lowVal1=NormalizeDouble(iLow(_Symbol,_Period,low1),5);
   lowVal2=NormalizeDouble(iLow(_Symbol,_Period,low2),5);
   ObjectDelete(0,"bottomLine");
   ObjectCreate(0,"bottomLine",OBJ_TREND,0,iTime(Symbol(),Period(),low2),iLow(Symbol(),Period(),low2),iTime(Symbol(),Period(),low1),iLow(Symbol(),Period(),low1));
   ObjectSetInteger(0,"bottomLine",OBJPROP_COLOR,clrGreen);
   ObjectSetInteger(0,"bottomLine",OBJPROP_WIDTH,3);
   ObjectSetInteger(0,"bottomLine",OBJPROP_RAY_RIGHT,true);
   if(lowVal1>=lowVal2&&highVal1<highVal2)
     {
      Comment("Potential Double Bottom",
              "\nCurrent High ",highVal1,"\nPrevious High ",highVal2,
              "\nCurrent Low ",lowVal1,"\nPrevious Low ",lowVal2);
     }
   else
      if(lowVal1>=lowVal2&&highVal1>highVal2)
        {
         Comment("Double Bottom",
                 "\nCurrent High ",highVal1,"\nPrevious High ",highVal2,
                 "\nCurrent Low ",lowVal1,"\nPrevious Low ",lowVal2);
        }
      else
         Comment(" ");
  }
int getmove(int move, int count, int startPos)
  {
   if(move!=MODE_HIGH && move!=MODE_LOW)
      return (-1);
   int currentBar=startPos;
   int moveReturned=getNextMove(move,count*2+1,currentBar-count);
   while(moveReturned!=currentBar)
     {
      currentBar=getNextMove(move,count,currentBar+1);
      moveReturned=getNextMove(move,count*2+1,currentBar-count);
     }
   return(currentBar);
  }
int getNextMove(int move, int count, int startPos)
  {
   if(startPos<0)
     {
      count +=startPos;
      startPos =0;
     }
   return((move==MODE_HIGH)?
          iHighest(Symbol(),Period(),(ENUM_SERIESMODE)move,count,startPos):
          iLowest(Symbol(),Period(),(ENUM_SERIESMODE)move,count,startPos));
  }

Le differenze in questo codice sono le condizioni del pattern.

Nel caso del Potenziale Doppio Minimo, se lowVal1 è maggiore o uguale a lowVal2 e highVal1 è inferiore a highVal2, dobbiamo ottenere un segnale come commento sul grafico con i seguenti valori:

  • Potenziale Doppio Minimo
  • Massimo Corrente
  • Massimo Precedente
  • Minimo Corrente
  • Minimo Precedente
   if(lowVal1>=lowVal2&&highVal1<highVal2)
     {
      Comment("Potential Double Bottom",
              "\nCurrent High ",highVal1,"\nPrevious High ",highVal2,
              "\nCurrent Low ",lowVal1,"\nPrevious Low ",lowVal2);
     }

Nel caso di Doppio Minimo, se lowVal1 è maggiore o uguale a lowVal2 e highVal1 è maggiore di highVal2, dobbiamo ottenere un segnale come commento sul grafico con i seguenti valori:

  • Doppio Minimo
  • Massimo Corrente
  • Massimo Precedente
  • Minimo Corrente
  • Minimo Precedente
   else
      if(lowVal1>=lowVal2&&highVal1>highVal2)
        {
         Comment("Double Bottom",
                 "\nCurrent High ",highVal1,"\nPrevious High ",highVal2,
                 "\nCurrent Low ",lowVal1,"\nPrevious Low ",lowVal2);
        }

Dopo aver compilato questo codice senza errori e aver eseguito il suo EA, possiamo ottenere i seguenti segnali come esempi di test.

Nel caso di Potenziale Doppio Minimo:

 Segnale potenziale DB patternFinder

Come si può vedere nel grafico precedente, abbiamo un potenziale segnale di doppio minimo in quanto vi è una corrispondenza con le condizioni impostate, ovvero un massimo inferiore e un minimo equivalente o superiore.

Nel caso di Doppio Minimo:

DB

Come si può vedere nel grafico precedente, abbiamo un segnale di doppio minimo in quanto si verifica una corrispondenza con le condizioni prestabilite che prevedono un massimo superiore e un minimo equivalente o superiore.

Conclusioni

L'azione dei prezzi è la cosa più importante per i trader, che operano in base alla comprensione della price action e se la comprendono bene, possono prendere decisioni di investimento o di trading migliori. L'azione dei prezzi forma molti pattern che dobbiamo leggere e comprendere. In questo articolo abbiamo cercato di fornire ciò che può rendere più facile questo compito, creando sistemi MQL5 da utilizzare nel terminale di trading MetaTrader 5.

Abbiamo imparato ad individuare i trend (trend rialzista, trend ribassista e lateralità) e uno dei pattern grafici più popolari, il doppio massimo e il suo opposto doppio minimo, dopo aver imparato ad individuare i massimi e i minimi. Abbiamo anche fornito una buona base per ogni concetto di trend e di questo tipo di grafico, per poter sviluppare i programmi o i sistemi citati in base alle vostre condizioni. Inoltre, dopo aver appreso il concetto principale per creare un sistema in grado di rilevare i massimi e i minimi, è possibile sviluppare questo sistema sempre di più per essere in grado di rilevare altri pattern grafici come testa e spalle, triangoli, rettangoli... ecc. Spero che questo articolo vi sia utile per sviluppare il vostro trading e il vostro sistema di trading di conseguenza per ottenere risultati migliori dalla vostra attività di trading.

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

File allegati |
moveFinder.mq5 (2.24 KB)
trendFinder.mq5 (3.18 KB)
MetaTrader 5 su macOS MetaTrader 5 su macOS
Forniamo uno speciale installatore per la piattaforma di trading MetaTrader 5 su macOS. È una procedura guidata completa che consente di installare l'applicazione in modo nativo. Il programma di installazione esegue tutti i passaggi necessari: identifica il sistema, scarica e installa l'ultima versione di Wine, la configura e quindi installa MetaTrader al suo interno. Tutti i passaggi vengono completati in modalità automatica e puoi iniziare ad utilizzare la piattaforma immediatamente dopo l'installazione.
Algoritmo di riacquisto: Simulazione di trading multivaluta Algoritmo di riacquisto: Simulazione di trading multivaluta
In questo articolo creeremo un modello matematico per la simulazione dei prezzi multivaluta e completeremo lo studio del principio di diversificazione come parte della ricerca dei meccanismi per aumentare l'efficienza del trading, iniziata nel precedente articolo con calcoli teorici.
Come creare un indicatore personalizzato (Heiken Ashi) utilizzando MQL5 Come creare un indicatore personalizzato (Heiken Ashi) utilizzando MQL5
In questo articolo impareremo a creare un indicatore personalizzato con MQL5 in base alle nostre preferenze, da utilizzare in MetaTrader 5 per aiutarci a leggere i grafici o per utilizzarli negli Expert Advisor automatici.
Algoritmo di riacquisto: Modello matematico per aumentare l'efficienza Algoritmo di riacquisto: Modello matematico per aumentare l'efficienza
In questo articolo utilizzeremo l'algoritmo di riacquisto per una comprensione più approfondita dell'efficienza dei sistemi di trading e inizieremo a lavorare sui principi generali del miglioramento dell'efficienza del trading utilizzando la matematica e la logica, oltre ad applicare metodi non standard per aumentare l'efficienza in termini di utilizzo di qualsiasi sistema di trading.