
Come utilizzare MQL5 per individuare i pattern di candele
Introduzione
Le candele sono uno strumento tecnico molto utile se le utilizziamo correttamente, in quanto possiamo individuare un movimento potenziale sulla base dei loro modelli. Le candele possono formare pattern specifici sul grafico e questi pattern possono essere suddivisi in due tipi: pattern a candela singola e pattern a candela mista (più di una candela). In questo articolo scopriremo come utilizzare MQL5 per rilevare automaticamente alcuni di questi pattern nel terminale di trading MetaTrader 5 e lo faremo attraverso i seguenti argomenti:
È necessario ricordare che è molto importante utilizzare questi pattern accompagnati da altri strumenti tecnici per ottenere segnali significativi. Quindi, è necessario comprendere l'idea principale del rilevamento dei pattern menzionati da MQL5 per essere parte del vostro sistema di trading per facilitare il vostro trading e ottenere buoni risultati.
Modello a candela singola
In questa parte vedremo due esempi di pattern popolari a candela singola che appaiono sul grafico. È possibile vederli in qualsiasi timeframe, ma saranno più significativi quando si troveranno al loro posto rispetto all'azione del prezzo. Vedremo i pattern Doji e Hammer.
Pattern Doji:
È molto popolare tra i pattern di candele ed è la candela che ha quasi lo stesso prezzo di apertura e chiusura, possiamo vedere un corpo molto piccolo della candela o una linea sul grafico per lo stesso prezzo del corpo superiore e inferiore o anche senza ombre. La figura seguente si riferisce a questa candela:
Questa candela Doji indica che esiste un equilibrio tra compratori e venditori e che nessuno controlla il mercato per spostare il prezzo più in alto o più in basso durante il periodo in cui appare. Può segnalare un'inversione o una correzione del mercato se appare nel punto più adatto del grafico prima di una correzione o alla fine del trend e sarà più significativa se appare nel time frame più grande. Ci sono molti tipi e formazioni per questa candela e tutti hanno molte informazioni che possono essere utilizzate a nostro favore nel trading come Dragonfly e Long-legged.
Ciò che dobbiamo fare è informare il computer di rilevare il pattern Doji definendo i prezzi e l'ora dell'ultima candela e ogni tick il programma deve controllare e confrontare questi valori in questo momento definito e determinare le posizioni di ognuno. Se l'apertura è uguale alla chiusura, il programma deve restituire un segnale che indica che si tratta di un pattern di candela Doji.
Ora, è necessario creare un programma in grado di rilevare questo pattern e di seguito sono riportati i passaggi di un metodo che può farlo:
Creeremo una funzione per questa Doji (getDoji) e la chiameremo nell'OnTick() per controllare ogni tick la ricerca di questo pattern.
void OnTick() { getDoji(); }
Creare la funzione (getDoji) creandola come variabile intera
int getDoji()
Definire questa funzione definendo l'ora, l'apertura, il massimo, il minimo e il prezzo di chiusura dell'ultima candela.
Utilizzando la funzione iTime che restituisce l'ora di apertura della candela, la funzione iOpen che restituisce il prezzo di apertura della candela, la funzione iHigh che restituisce il prezzo massimo, la funzione iLow che restituisce il prezzo minimo e la funzione iClose che restituisce il prezzo di chiusura della candela. i parametri sono gli stessi per tutte:
- symbol: per definire il nome del simbolo, useremo _Symbol per il simbolo corrente.
- timeframe: per definire il periodo o il timeframe del grafico, utilizzeremo PERIOD_CURRENT per il timeframe corrente.
- shift: per definire l'indice del valore restituito, useremo (1) per definire la candela precedente.
datetime time=iTime(_Symbol,PERIOD_CURRENT,1); double open=iOpen(_Symbol,PERIOD_CURRENT,1); double high=iHigh(_Symbol,PERIOD_CURRENT,1); double low=iLow(_Symbol,PERIOD_CURRENT,1); double close=iClose(_Symbol,PERIOD_CURRENT,1);
Impostazione della condizione della Doji che dobbiamo rilevare utilizzando l'istruzione if
if(open==close)
Se questa condizione è vera, è necessario che il programma crei un oggetto basato sulla funzione createObj che creeremo con i parametri di ora, prezzo, codice della freccia, colore e il testo di cui abbiamo bisogno. Quindi terminare la funzione restituendo 1.
if(open==close) { createObj(time,low,217, clrBlack,"Doji"); { return 1; } }
Verrà restituito 0 per terminare la funzione getDoji
return 0;
Creazione della funzione (createObj) con i parametri time, price, arrowcode, clr e txt utilizzando la funzione void
void createObj(datetime time, double price, int arrawCode, color clr, string txt)
Creazione di una variabile stringa objName assegnando il valore (" ")
string objName=" ";
Combinare le stringhe per assegnarle alla variabile objName utilizzando la funzione StringConcatenate che forma una stringa con i parametri passati e restituisce la dimensione della stringa formata. I suoi parametri sono:
- string_var: per definire la stringa che si formerà dopo la concatenazione, si utilizzerà la variabile (objName).
- argument1: per definire il parametro di qualsiasi tipo semplice, utilizzeremo il testo "Signal at ".
- argument2: per definire l'ora della candela rilevata, utilizzeremo l'ora della variabile predeterminata.
- argument3: imposteremo il testo " at ".
- argument4: si imposterà il testo del prezzo arrotondato utilizzando DoubleToString per convertire il tipo double in stringa.
- argument5: si imposterà il testo " (".
- argument6: assegneremo un valore alla variabile intera predeterminata (arrowcode) di cui abbiamo bisogno. Questo codice può essere trovato cercando Wingdings nel riferimento mql5.
- argument7: si imposterà il testo di ")".
StringConcatenate(objName, "Signal at ",time, " at ",DoubleToString(price,_Digits)," (",arrawCode,")");
Impostiamo una condizione da valutare utilizzando l'istruzione if e la funzione ObjectCreate come espressione; la funzione ObjectCreate crea un oggetto utilizzando il nome predefinito objName e i suoi parametri sono:
- chart_id: per identificare il grafico, useremo 0 per il grafico corrente.
- name: per definire il nome dell'oggetto, si utilizzerà il nome predefinito (objName).
- type: per definire il tipo di oggetto, useremo (OBJ_ARROW).
- nwin: per definire il numero della finestra secondaria del grafico, useremo (0) per la finestra principale del grafico.
- time1: per definire l'ora di ancoraggio, utilizzeremo la variabile predefinita (time).
- price1: per definire il prezzo di ancoraggio, utilizzeremo la variabile predefinita (price).
if(ObjectCreate(0,objName,OBJ_ARROW,0,time,price))
Una volta che questa condizione è vera, creando l'oggetto, dobbiamo impostarne le proprietà, la forma, determinando il codice della freccia, e il colore, utilizzando la funzione ObjectSetInteger che imposta il valore della proprietà dell'oggetto. I suoi parametri sono:
- chart_id: per identificare il grafico, useremo 0 per il grafico corrente.
- name: per definire il nome dell'oggetto, useremo objName.
- prop_id: per definire la proprietà dell'oggetto, si utilizzerà uno degli ENUM_OBJECT_PROPERTY_INTEGER che sarà OBJPROP_ARROWCODE per il codice della freccia e OBJPROP_COLOR per il colore.
- prop_value: per definire il valore della proprietà, utilizzeremo arrowCode per il codice della freccia e la variabile predefinita clr per il colore.
ObjectSetInteger(0,objName,OBJPROP_ARROWCODE,arrawCode); ObjectSetInteger(0,objName,OBJPROP_COLOR,clr);
Dopodiché, dobbiamo definire il testo che ci serve come definizione della candela, creando una variabile stringa per candleName con un'assegnazione delle variabili predefinite objName e txt
string candleName=objName+txt;
Creare e modificare l'oggetto testo utilizzando l'istruzione if e la funzione ObjectCreate come espressione e l'operatore ObjectSetString per impostare il valore della stringa della proprietà dell'oggetto e ObjectSetInteger per impostare il colore dell'oggetto testo.
ObjectSetString(0,candleName,OBJPROP_TEXT," "+txt); ObjectSetInteger(0,candleName,OBJPROP_COLOR,clr);
Ora possiamo vedere il codice completo di questo Expert Advisor come segue:
//+------------------------------------------------------------------+ //| Doji pattern detector.mq5 | //| Copyright 2023, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ void OnTick() { getDoji(); } int getDoji() { datetime time=iTime(_Symbol,PERIOD_CURRENT,1); double open=iOpen(_Symbol,PERIOD_CURRENT,1); double high=iHigh(_Symbol,PERIOD_CURRENT,1); double low=iLow(_Symbol,PERIOD_CURRENT,1); double close=iClose(_Symbol,PERIOD_CURRENT,1); //Doji if(open==close) { createObj(time,low,217, clrBlack,"Doji"); { return 1; } } return 0; } void createObj(datetime time, double price, int arrawCode, color clr, string txt) { string objName=" "; StringConcatenate(objName, "Signal at ",time, " at ",DoubleToString(price,_Digits)," (",arrawCode,")"); if(ObjectCreate(0,objName,OBJ_ARROW,0,time,price)) { ObjectSetInteger(0,objName,OBJPROP_ARROWCODE,arrawCode); ObjectSetInteger(0,objName,OBJPROP_COLOR,clr); } string candleName=objName+txt; if(ObjectCreate(0,candleName,OBJ_TEXT,0,time,price)) { ObjectSetString(0,candleName,OBJPROP_TEXT," "+txt); ObjectSetInteger(0,candleName,OBJPROP_COLOR,clr); } }
Dopo aver compilato questo codice senza errori, possiamo trovarlo nella finestra del navigatore. Trascinandolo per l'esecuzione, possiamo ottenere i suoi segnali che rilevano il pattern Doji e il seguente è un esempio di test:
Come possiamo vedere nel grafico precedente, abbiamo un oggetto freccia nero sotto la candela e il testo Doji per definire il pattern della candela.
Pattern Hammer:
Il pattern hammer è un modello di candele molto popolare che possiamo vedere sul grafico in molti timeframe. Il suo nome si riferisce alla sua forma, poiché ha una lunga ombra e un corpo piccolo. Esistono due tipi di modelli Hammer, Hammer e Inverted Hammer, a seconda della posizione del piccolo corpo. Se ha una lunga ombra inferiore e il corpo della candela è al di sopra, si tratta di un Hammer e può essere una candela rialzista o ribassista in base al prezzo di apertura e di chiusura; le figure seguenti sono esempi di questi pattern Hammer:
- Hammer rialzista
Indica che i venditori hanno cercato di spingere il prezzo più in basso, ma i compratori controllano il mercato e chiude più in alto rispetto all'apertura, il che significa forza dei compratori .
- Hammer Ribassista
Indica che i venditori hanno cercato di spingere il prezzo più in basso, ma i compratori sembrano chiudere intorno all'apertura, il che significa che i compratori sono ancora in gioco.
Se la candela ha una lunga ombra superiore e il suo corpo si trova al di sotto, si tratta di un modello Inverted Hammer e può essere anche rialzista o ribassista in base alla posizione dei prezzi di apertura e chiusura. Le figure seguenti sono esempi di questo Inverted Hammer.
- Inverted Hammer Rialzista
Indica che i compratori provano a spingere i prezzi più in alto, ma i venditori sembrano chiudere la candela intorno all'apertura e al minimo, il che significa che i venditori sono ancora in gioco nonostante la forza dei compratori.
- Inverted Hammer Ribassista
Indica che i compratori hanno cercato di spingere il prezzo più in alto, ma i venditori controllano il mercato e chiude più in basso rispetto all'apertura, il che significa forza per i venditori.
Anche questo pattern, come tutti i pattern di candele, sarà più significativo se combinato con altri strumenti tecnici.
Ora, dobbiamo creare un programma che possa essere utilizzato per rilevare questo tipo di pattern, quindi lasceremo che questo programma trovi i prezzi, l'ora e le dimensioni della candela da confrontare con il corpo e le ombre della candela stessa e abbiamo bisogno che il programma li controlli e li confronti continuamente ad ogni tick per determinare le loro posizioni. Quando il programma rileva un Hammer o un Inverted Hammer (rialzista o ribassista), deve restituire un oggetto sul grafico con il nome del suo tipo e le frecce di colore verde o rosso e sotto o sopra la candela in base al colore della candela (rialzista o ribassista).
Di seguito è riportato il codice completo per creare questo tipo di programma:
//+------------------------------------------------------------------+ //| Hammer pattern detector.mq5 | //| Copyright 2023, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ void OnTick() { getHammer(0.07,0.7); } int getHammer(double smallShadowRatio, double longShadowRatio) { datetime time=iTime(_Symbol,PERIOD_CURRENT,1); double open=iOpen(_Symbol,PERIOD_CURRENT,1); double high=iHigh(_Symbol,PERIOD_CURRENT,1); double low=iLow(_Symbol,PERIOD_CURRENT,1); double close=iClose(_Symbol,PERIOD_CURRENT,1); double candleSize=high-low; if(open<close) { if(high-close < candleSize*smallShadowRatio) { if(open-low>candleSize*longShadowRatio) createObj(time,low,217, clrGreen,"Hammer"); { return 1; } } } if(open>close) { if(high-open<candleSize*smallShadowRatio) { if(close-low>candleSize*longShadowRatio) createObj(time,high,218,clrRed,"Hammer"); { return 1; } } } if(open<close) { if(open-low < candleSize*smallShadowRatio) { if(high-close>candleSize*longShadowRatio) createObj(time,low,217, clrGreen,"Inverted Hammer"); { return -1; } } } if(open>close) { if(close-low < candleSize*smallShadowRatio) { if(high-open>candleSize*longShadowRatio) createObj(time,high,218, clrRed,"Inverted Hammer"); { return -1; } } } return 0; } void createObj(datetime time, double price, int arrawCode, color clr, string txt) { string objName=" "; StringConcatenate(objName, "Signal@",time, "at",DoubleToString(price,_Digits),"(",arrawCode,")"); if(ObjectCreate(0,objName,OBJ_ARROW,0,time,price)) { ObjectSetInteger(0,objName,OBJPROP_ARROWCODE,arrawCode); ObjectSetInteger(0,objName,OBJPROP_COLOR,clr); if(clr==clrGreen) ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_TOP); if(clr==clrRed) ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_BOTTOM); } string candleName=objName+txt; if(ObjectCreate(0,candleName,OBJ_TEXT,0,time,price)) { ObjectSetString(0,candleName,OBJPROP_TEXT," "+txt); ObjectSetInteger(0,candleName,OBJPROP_COLOR,clr); } }
Le differenze in questo codice sono le seguenti:
Chiamata della funzione getHammer in OnTick() con determinazione dei parametri desiderati per smallShadowRatio e longShadowRatio
void OnTick() { getHammer(0.07,0.7); }
Creazione della funzione getHammer con i parametri di due variabili double (smallShadowRatio) e (longShadowRatio)
int getHammer(double smallShadowRatio, double longShadowRatio)
Creazione di una variabile double per candleSize da confrontare con la proporzione
double candleSize=high-low;
Condizioni della candela Hammer,
Nel caso di un Hammer Rialzista (Open<Close), abbiamo bisogno che l'ultima candela sia rialzista, l'ombra superiore della candela (high-close) deve essere inferiore alla proporzione dell’ombra inferiore di 0,07 e l'ombra inferiore (open-low) deve essere superiore alla proporzione dell’ombra lunga che è di 0,7. Creare una freccia verde con il codice 217 di Wingdings e l'oggetto di testo "Hammer" sul grafico sotto il minimo di questa candela Hammer, quindi terminare la funzione.
if(open<close) { if(high-close < candleSize*smallShadowRatio) { if(open-low>candleSize*longShadowRatio) createObj(time,low,217, clrGreen,"Hammer"); { return 1; } } }
Nel caso di un Hammer Ribassista (open>close), abbiamo bisogno che l’ultima candela sia ribassista, l'ombra superiore della candela (high-open) sia inferiore alla proporzione dell’ombra piccola che è di 0,07, e l'ombra inferiore (close-low) sia superiore alla proporzione dell’ombra lunga che è di 0,7. Creare una freccia rossa con il codice 218 di Wingdings e l'oggetto testo "Hammer" sul grafico sopra il massimo di questa candela Hammer, quindi terminare la funzione.
if(open>close) { if(high-open<candleSize*smallShadowRatio) { if(close-low>candleSize*longShadowRatio) createObj(time,high,218,clrRed,"Hammer"); { return 1; } } }
Nel caso di un Inverted Hammer Rialzista (open<close), abbiamo bisogno che l’ultima candela sia rialzista, l'ombra inferiore della candela (open-low) è inferiore alla proporzione dell’ombra piccola che è di 0,07 e l'ombra superiore (high-close) è superiore alla proporzione dell’ombra lunga 0,7. Creare una freccia verde con il codice (217) di Wingdings e l'oggetto di testo "Inverted Hammer" sul grafico sotto il minimo di questa candela Hammer, quindi terminare la funzione.
if(open<close) { if(open-low < candleSize*smallShadowRatio) { if(high-close>candleSize*longShadowRatio) createObj(time,low,217, clrGreen,"Inverted Hammer"); { return -1; } } }
Nel caso di un Inverted Hammer Ribassista (open>close), abbiamo bisogno che l'ultima candela sia ribassista, l'ombra inferiore della candela (close-low) è inferiore alla proporzione dell’ombra piccola (0,07) e l'ombra superiore (high-open) è superiore alla proporzione dell’ombra lunga (0,7). Creare una freccia rossa con il codice 218 di Wingdings e l'oggetto testo "Inverted Hammer" sul grafico sopra il massimo di questa candela, quindi terminare la funzione.
if(open>close) { if(close-low < candleSize*smallShadowRatio) { if(high-open>candleSize*longShadowRatio) createObj(time,high,218, clrRed,"Inverted Hammer"); { return -1; } } }
Modifichiamo la posizione e il colore della freccia in base al tipo di candela utilizzando l'operatore 'if'. L'espressione sarà il colore, mentre l'operatore 'if' (se è vero) sarà usato come posizione della freccia con l'aiuto della funzione ObjectSetInteger.
Se il verde sarà sotto la candela
if(clr==clrGreen) ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_TOP);
Se il rosso sarà sopra la candela
if(clr==clrRed) ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_BOTTOM);
Dopo aver compilato questo codice senza errori e averlo eseguito, possiamo ottenere il nostro segnale e i seguenti sono esempi di test:
- Hammer Rialzista:
Come possiamo vedere, abbiamo una freccia verde e l'oggetto di testo "Hammer" verde sul grafico sotto il minimo della candela Hammer rialzista.
- Hammer Ribassista:
Come possiamo vedere, abbiamo una freccia rossa e l'oggetto di testo "Hammer" rosso sul grafico sopra il massimo della candela Hammer ribassista.
- Inverted Hammer Rialzista:
Come possiamo vedere, abbiamo una freccia verde e l'oggetto di testo "Inverted Hammer" verde sul grafico sotto il minimo della candela rialzista Inverted Hammer.
- Inverted Hammer Ribassista:
Come possiamo vedere, abbiamo una freccia rossa e l'oggetto di testo "Inverted Hammer" rosso sul grafico sopra il massimo della candela ribassista Inverted Hammer.
Pattern a doppia candela
In questa parte, vedremo un altro tipo di pattern di candele che consiste in due candele, vedremo due pattern popolari che sono Engulfing (Rialzista e Ribassista) e il pattern rialzista Piercing line e il suo pattern opposto ribassista Dark Cloud.
Pattern engulfing:
Anche questo modello di candela è molto popolare sui grafici e nell'analisi tecnica e consiste in due candele, una delle quali ingloba l'altra, il che significa che c'è una candela piccola seguita da una più grande e questa più grande copre completamente la più piccola.
Esistono diversi tipi di pattern Engulfing in base al colore o al tipo di candele:
- Bullish Engulfing:
Presenta una piccola candela ribassista seguita da una grande candela rialzista e quest'ultima inghiotte la più piccola e la figura seguente ne è la dimostrazione:
A seconda del suo significato, indica che i compratori controllano il mercato e il prezzo può continuare a salire dopo di essa.
- Bearish Engulfing:
A seconda del suo significato, indica che i venditori controllano il mercato e il prezzo può continuare a scendere dopo di essa.
Ora, se vogliamo creare un programma che possa essere utilizzato per rilevare automaticamente questo pattern, dobbiamo definire l'ora dell'ultima candela e i prezzi delle ultime due candele; il programma deve controllare continuamente questi valori ad ogni tick e determinare le posizioni reciproche per verificare se abbiamo questo tipo di pattern Engulfing o meno. Una volta ottenuto il pattern Engulfing, il programma deve restituire un segnale specifico, ovvero una freccia colorata e un oggetto di testo in base al suo tipo (Bullish or Bearish).
Di seguito è riportato il codice completo per creare questo programma:
//+------------------------------------------------------------------+ //| Engulfing pattern detector.mq5 | //| Copyright 2023, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ void OnTick() { getEngulfing(); } int getEngulfing() { datetime time=iTime(_Symbol,PERIOD_CURRENT,1); double open=iOpen(_Symbol,PERIOD_CURRENT,1); double high=iHigh(_Symbol,PERIOD_CURRENT,1); double low=iLow(_Symbol,PERIOD_CURRENT,1); double close=iClose(_Symbol,PERIOD_CURRENT,1); double open2=iOpen(_Symbol,PERIOD_CURRENT,2); double high2=iHigh(_Symbol,PERIOD_CURRENT,2); double low2=iLow(_Symbol,PERIOD_CURRENT,2); double close2=iClose(_Symbol,PERIOD_CURRENT,2); if(open<close) { if(open2>close2) { if(high>high2&&low<low2) { if(close>open2&&open<close2) { createObj(time,low,217, clrGreen,"Bullish Engulfing"); { return 1; } } } } } if(open>close) { if(open2<close2) { if(high>high2&&low<low2) { if(close<open2&&open>close2) { createObj(time,high,218, clrRed,"Bearish Engulfing"); { return -1; } } } } } return 0; } void createObj(datetime time, double price, int arrawCode, color clr, string txt) { string objName=" "; StringConcatenate(objName, "Signal@",time, "at",DoubleToString(price,_Digits),"(",arrawCode,")"); if(ObjectCreate(0,objName,OBJ_ARROW,0,time,price)) { ObjectSetInteger(0,objName,OBJPROP_ARROWCODE,arrawCode); ObjectSetInteger(0,objName,OBJPROP_COLOR,clr); if(clr==clrGreen) ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_TOP); if(clr==clrRed) ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_BOTTOM); } string candleName=objName+txt; if(ObjectCreate(0,candleName,OBJ_TEXT,0,time,price)) { ObjectSetString(0,candleName,OBJPROP_TEXT," "+txt); ObjectSetInteger(0,candleName,OBJPROP_COLOR,clr); } }
Differenze in questo codice:
Creazione di variabili double per il tempo dell'ultima candela e i prezzi delle ultime due candele nella creazione della funzione getEngulfing, time, open, high, low, and close sono per l'ultima candela e open2, high2, low2, and close2 sono per la candela precedente all'ultima.
datetime time=iTime(_Symbol,PERIOD_CURRENT,1); double open=iOpen(_Symbol,PERIOD_CURRENT,1); double high=iHigh(_Symbol,PERIOD_CURRENT,1); double low=iLow(_Symbol,PERIOD_CURRENT,1); double close=iClose(_Symbol,PERIOD_CURRENT,1); double open2=iOpen(_Symbol,PERIOD_CURRENT,2); double high2=iHigh(_Symbol,PERIOD_CURRENT,2); double low2=iLow(_Symbol,PERIOD_CURRENT,2); double close2=iClose(_Symbol,PERIOD_CURRENT,2);
Condizioni che definiscono questo tipo di pattern a candele
Nel caso del Bullish Engulfing, l'ultima candela è rialzista (open<close), la precedente è ribassista (open2>close2), high è superiore a high2 e allo stesso tempo low è inferiore a low2, close è superiore a open2 e allo stesso tempo open è inferiore a close2. Una volta identificato, creare un oggetto basato sulla funzione creata (createObj) con i seguenti parametri:
- time: sarà l'ora dell'ultima candela, che è la variabile predefinita.
- price: sarà il minimo dell'ultima candela dove abbiamo bisogno l'oggetto sottostante.
- arrowCode: sarà 217 da Wingdings.
- clr: sarà clrGreen.
- txt: sarà "Bullish Engulfing".
Quindi terminare la funzione.
if(open<close) { if(open2>close2) { if(high>high2&&low<low2) { if(close>open2&&open<close2) { createObj(time,low,217, clrGreen,"Bullish Engulfing"); { return 1; } } } } }
Nel caso del Bearish Engulfing, l'ultima candela è ribassista (open>close), la precedente è rialzista (open2<close2), high è superiore a high2, e allo stesso tempo low è inferiore a low2, close è inferiore a open2 e allo stesso tempo open è superiore a close2. Una volta identificato, creare un oggetto basato sulla funzione creata (createObj) con i seguenti parametri:
- time: sarà l'ora dell'ultima candela, che è la variabile predefinita.
- price: sarà il massimo dell'ultima candela dove abbiamo bisogno l'oggetto sopra di essa.
- arrowCode: sarà 218 da Wingdings.
- clr: sarà clrRed.
- txt: sarà "Bearish Engulfing".
Quindi terminare la funzione.
if(open>close) { if(open2<close2) { if(high>high2&&low<low2) { if(close<open2&&open>close2) { createObj(time,high,218, clrRed,"Bearish Engulfing"); { return -1; } } } } }
Dopo aver compilato questo codice senza errori ed eseguito l'EA, possiamo ottenere i segnali come negli esempi seguenti di test:
- Bullish Engulfing:
Come si vede nel grafico precedente, abbiamo una freccia verde e un testo Bullish Engulfing sotto il minimo dell'ultima candela del pattern.
- Bearish Engulfing:
Come nel grafico precedente, abbiamo una freccia rossa e un testo Bearish Engulfing sopra il massimo dell'ultima candela del pattern.
Pattern Piercing Line e Dark Cloud Cover:
- Pattern Piercing Line:
Si tratta di un pattern rialzista, composto da due candele: la prima è ribassista, seguita da una rialzista con un'apertura inferiore a quella della candela ribassista, che si muove verso l'alto e chiude sopra il punto medio della prima candela ribassista. La figura seguente mostra un grafico che lo descrive:
Ciò indica che i compratori diventano più forti e controllano il mercato dopo il controllo dei venditori. Si riferisce quindi a un passaggio dal potere di vendita a quello di acquisto, in quanto i compratori sono riusciti a spingere il prezzo sopra al punto medio della precedente candela ribassista, nonostante la presenza di un gap all'apertura.
- Pattern Dark Cloud Cover:
Si tratta della forma opposta a quella dei pattern piercing, in quanto è un pattern ribassista che presenta una struttura a due candele, la prima delle quali è rialzista ed è seguita da una candela ribassista con un gap di apertura che si chiude al di sotto del punto medio della prima candela rialzista. Di seguito è riportato il relativo grafico:
Ciò indica che i venditori diventano più forti e controllano il mercato dopo il controllo da parte dei compratori. Si tratta quindi di un passaggio dal potere di acquisto a quello di vendita, in quanto i venditori sono riusciti a spingere il prezzo al di sotto del punto medio della precedente candela rialzista, nonostante la presenza di un gap all'apertura.
Quando vogliamo creare un programma che possa essere utilizzato per rilevare questo tipo di pattern, dovremo definire l'ora e i prezzi della prima candela (time, open, high, low e close) e i prezzi della seconda candela (open2, high2, low2 e close2), la dimensione della prima candela (candleSize2) e il punto medio della prima candela (candleMidPoint2). Il programma deve controllare continuamente questi valori e determinare la loro posizione in relazione l'uno all'altro e restituire un segnale specifico in base a condizioni specifiche che sia rialzista o ribassista.
Di seguito è riportato il codice completo per creare questo programma:
//+------------------------------------------------------------------+ //| Piercing && Dark Cloud pattern detector.mq5 | //| Copyright 2023, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ void OnTick() { getPiercing(); } int getPiercing() { datetime time=iTime(_Symbol,PERIOD_CURRENT,1); double open=iOpen(_Symbol,PERIOD_CURRENT,1); double high=iHigh(_Symbol,PERIOD_CURRENT,1); double low=iLow(_Symbol,PERIOD_CURRENT,1); double close=iClose(_Symbol,PERIOD_CURRENT,1); double open2=iOpen(_Symbol,PERIOD_CURRENT,2); double high2=iHigh(_Symbol,PERIOD_CURRENT,2); double low2=iLow(_Symbol,PERIOD_CURRENT,2); double close2=iClose(_Symbol,PERIOD_CURRENT,2); double candleSize2=high2-low2; double candleMidPoint2=high2-(candleSize2/2); if(open<close) { if(open2>close2) { if(open<low2) { if(close>candleMidPoint2&&close<high2) { createObj(time,low,217, clrGreen,"Piercing"); { return 1; } } } } } if(open>close) { if(open2<close2) { if(open>high2) { if(close<candleMidPoint2&&close>low2) { createObj(time,high,218, clrRed,"Dark Cloud"); { return -1; } } } } } return 0; } void createObj(datetime time, double price, int arrawCode, color clr, string txt) { string objName=" "; StringConcatenate(objName, "Signal@",time, "at",DoubleToString(price,_Digits),"(",arrawCode,")"); if(ObjectCreate(0,objName,OBJ_ARROW,0,time,price)) { ObjectSetInteger(0,objName,OBJPROP_ARROWCODE,arrawCode); ObjectSetInteger(0,objName,OBJPROP_COLOR,clr); if(clr==clrGreen) ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_TOP); if(clr==clrRed) ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_BOTTOM); } string candleName=objName+txt; if(ObjectCreate(0,candleName,OBJ_TEXT,0,time,price)) { ObjectSetString(0,candleName,OBJPROP_TEXT," "+txt); ObjectSetInteger(0,candleName,OBJPROP_COLOR,clr); } }
Differenze in questo codice
Definizione di candleSize2 e candleMidPoint2
double candleSize2=high2-low2; double candleMidPoint2=high2-(candleSize2/2);
Condizioni del pattern
Nel caso del pattern Piercing Line:
Se l'ultima candela è rialzista (open<close), e l'open2 è maggiore di close2, l'open è minore di low2, e il close è maggiore di candleMidPoint2 e allo stesso tempo il close è minore di high2, il programma deve restituire un oggetto sul grafico con una freccia verde e il testo "Piercing" sotto il minimo del pattern, quindi terminare la funzione.
if(open<close) { if(open2>close2) { if(open<low2) { if(close>candleMidPoint2&&close<high2) { createObj(time,low,217, clrGreen,"Piercing"); { return 1; } } } } }
Nel caso del pattern Dark Cloud Cover:
Se l'ultima candela è ribassista (open>close), e l'open2 è inferiore a close2, l'open è superiore all'high2, e il close è inferiore a candleMidPoint2 e allo stesso tempo il close è superiore a low2, è necessario che il programma restituisca un oggetto sul grafico con una freccia rossa e il testo "Dark Cloud" sopra il massimo del pattern, quindi terminare la funzione.
if(open>close) { if(open2<close2) { if(open>high2) { if(close<candleMidPoint2&&close>low2) { createObj(time,high,218, clrRed,"Dark Cloud"); { return -1; } } } } }
Dopo la compilazione di questo codice e l'esecuzione dell'EA, possiamo ottenere i segnali desiderati, come negli esempi di test seguenti:
- Pattern Piercing Line:
Come possiamo vedere nel grafico precedente, abbiamo la nostra freccia verde e il testo piercing sotto il minimo del pattern, proprio come ci serve.
- Pattern Dark Cloud Cover:
Come possiamo vedere nel grafico precedente, abbiamo una freccia rossa e il testo Dark Cloud sopra il massimo del pattern, proprio come ci serve.
Pattern a tre candele
In questa parte vedremo due pattern dai modelli misti e sono il pattern Star (Morning, Evening) e il Three Inside Pattern(Up, Down).
Pattern Star:
- Morning Star:
Si tratta di una struttura a tre candele, come abbiamo detto. È formata da una piccola candela tra due candele di cui la prima è una lunga ribassista e la seconda è una lunga rialzista. Di seguito è riportato il relativo grafico:
In base al suo significato, indica uno spostamento del potere dalla vendita all'acquisto, in quanto i compratori controllano il mercato e spingono il prezzo più in alto dopo un calo dovuto al controllo dei venditori.
- Pattern Evening Star:
In base al suo significato, indica uno spostamento del potere dall'acquisto alla vendita, in quanto i venditori controllano il mercato e spingono il prezzo al ribasso dopo un rally controllato dai compratori.
Quando vogliamo creare un programma che possa essere utilizzato per rilevare questo tipo di pattern, dobbiamo definire l'ora e il prezzo dell'ultima candela e i dati di prezzo delle due candele precedenti all'ultima, la dimensione delle ultime tre candele e confrontarli tra loro per determinare le loro posizioni correlate per ottenere segnali specifici basati su condizioni specifiche.
Di seguito è riportato il codice completo per creare questo programma:
//+------------------------------------------------------------------+ //| Star pattern detector.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() { getStar(0.5); } int getStar(double middleCandleRatio) { datetime time=iTime(_Symbol,PERIOD_CURRENT,1); double open=iOpen(_Symbol,PERIOD_CURRENT,1); double high=iHigh(_Symbol,PERIOD_CURRENT,1); double low=iLow(_Symbol,PERIOD_CURRENT,1); double close=iClose(_Symbol,PERIOD_CURRENT,1); double open2=iOpen(_Symbol,PERIOD_CURRENT,2); double high2=iHigh(_Symbol,PERIOD_CURRENT,2); double low2=iLow(_Symbol,PERIOD_CURRENT,2); double close2=iClose(_Symbol,PERIOD_CURRENT,2); double open3=iOpen(_Symbol,PERIOD_CURRENT,3); double high3=iHigh(_Symbol,PERIOD_CURRENT,3); double low3=iLow(_Symbol,PERIOD_CURRENT,3); double close3=iClose(_Symbol,PERIOD_CURRENT,3); double candleSize=high-low; double candleSize2=high2-low2; double candleSize3=high3-low3; if(open<close) { if(open3>close3) { if(candleSize2<candleSize*middleCandleRatio && candleSize2<candleSize3*middleCandleRatio) { createObj(time,low,217, clrGreen,"Morning Star"); { return 1; } } } } if(open>close) { if(open3<close3) { if(candleSize2<candleSize*middleCandleRatio && candleSize2<candleSize3*middleCandleRatio) { createObj(time,high,218, clrRed,"Evening Star"); { return -1; } } } } return 0; } void createObj(datetime time, double price, int arrawCode, color clr, string txt) { string objName=" "; StringConcatenate(objName, "Signal@",time, "at",DoubleToString(price,_Digits),"(",arrawCode,")"); if(ObjectCreate(0,objName,OBJ_ARROW,0,time,price)) { ObjectSetInteger(0,objName,OBJPROP_ARROWCODE,arrawCode); ObjectSetInteger(0,objName,OBJPROP_COLOR,clr); if(clr==clrGreen) ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_TOP); if(clr==clrRed) ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_BOTTOM); } string candleName=objName+txt; if(ObjectCreate(0,candleName,OBJ_TEXT,0,time,price)) { ObjectSetString(0,candleName,OBJPROP_TEXT," "+txt); ObjectSetInteger(0,candleName,OBJPROP_COLOR,clr); } }
Differenze in questo codice
Creazione di getStar con il parametro su middleCandleRatio
int getStar(double middleCandleRatio)
Creare le variabili di tempo per l'ultima candela per i dati di prezzo (open, high, low, close) e per le dimensioni delle ultime tre candele candleSize, candleSize2 e candleSize3.
datetime time=iTime(_Symbol,PERIOD_CURRENT,1); double open=iOpen(_Symbol,PERIOD_CURRENT,1); double high=iHigh(_Symbol,PERIOD_CURRENT,1); double low=iLow(_Symbol,PERIOD_CURRENT,1); double close=iClose(_Symbol,PERIOD_CURRENT,1); double open2=iOpen(_Symbol,PERIOD_CURRENT,2); double high2=iHigh(_Symbol,PERIOD_CURRENT,2); double low2=iLow(_Symbol,PERIOD_CURRENT,2); double close2=iClose(_Symbol,PERIOD_CURRENT,2); double open3=iOpen(_Symbol,PERIOD_CURRENT,3); double high3=iHigh(_Symbol,PERIOD_CURRENT,3); double low3=iLow(_Symbol,PERIOD_CURRENT,3); double close3=iClose(_Symbol,PERIOD_CURRENT,3); double candleSize=high-low; double candleSize2=high2-low2; double candleSize3=high3-low3;
Condizioni del pattern
Nel caso del pattern Morning Star:
Se l'ultima candela è rialzista (open<close), la terza è ribassista (open3>close3), candleSize2 è inferiore a middleCandleRatio di candleSize che è 0,5 e allo stesso tempo candleSize2 è inferiore a middleCandleRatio di candleSize3, è necessario che il programma restituisca un oggetto con una freccia verde e il testo "Morning Star" sotto il minimo del pattern, per poi terminare la funzione.
if(open<close) { if(open3>close3) { if(candleSize2<candleSize*middleCandleRatio && candleSize2<candleSize3*middleCandleRatio) { createObj(time,low,217, clrGreen,"Morning Star"); { return 1; } } } }
Nel caso di Evening Star:
Se l'ultima candela è ribassista (open>close), la terza è rialzista (open3<close3), candleSize2 è inferiore a middleCandleRatio di candleSize che è 0,5 e allo stesso tempo candleSize2 è inferiore a middleCandleRatio di candleSize3, è necessario che il programma restituisca un oggetto con una freccia rossa e il testo "Evening Star" sopra il massimo del pattern, quindi terminare la funzione.
if(open>close) { if(open3<close3) { if(candleSize2<candleSize*middleCandleRatio && candleSize2<candleSize3*middleCandleRatio) { createObj(time,high,218, clrRed,"Evening Star"); { return -1; } } } }
Dopo aver compilato questo codice senza errori e aver eseguito l’EA, possiamo ottenere segnali uguali a quelli dei seguenti esempi di test:
- Morning Star:
Come si può vedere, il segnale desiderato dell'oggetto richiesto è presente sul grafico sotto il pattern rilevato.
- Evening Star:
Come si può vedere, il segnale desiderato dell'oggetto richiesto è presente sul grafico sotto il pattern rilevato.
Come nota per il pattern Star, la formazione del pattern identico ha un gap con la candela piccola centrale; potete aggiungerlo come condizione aggiuntiva nel codice, se volete ottenere il pattern identico.
Three Inside pattern:
- Three Inside Up:
Si tratta di un pattern a tre candele, la prima è una lunga candela ribassista, la seconda è una piccola candela rialzista che scambia all'interno della prima e la terza è una lunga candela rialzista che chiude sopra il massimo della prima. Di seguito è riportato un grafico di questo pattern.
In base al suo significato, indica un potenziale rialzo da parte del controllo dei compratori.
- Three Inside Down:
Si tratta di un modello a tre candele, la prima è una lunga candela rialzista, la seconda è una piccola candela ribassista che scambia all'interno della prima e la terza è una lunga candela ribassista che chiude sotto il minimo della prima. Di seguito è riportato un grafico di questo pattern.
//+------------------------------------------------------------------+ //| Three inside pattern detector.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() { getthreeInside(); } int getthreeInside() { datetime time=iTime(_Symbol,PERIOD_CURRENT,1); double open=iOpen(_Symbol,PERIOD_CURRENT,1); double high=iHigh(_Symbol,PERIOD_CURRENT,1); double low=iLow(_Symbol,PERIOD_CURRENT,1); double close=iClose(_Symbol,PERIOD_CURRENT,1); double open2=iOpen(_Symbol,PERIOD_CURRENT,2); double high2=iHigh(_Symbol,PERIOD_CURRENT,2); double low2=iLow(_Symbol,PERIOD_CURRENT,2); double close2=iClose(_Symbol,PERIOD_CURRENT,2); double open3=iOpen(_Symbol,PERIOD_CURRENT,3); double high3=iHigh(_Symbol,PERIOD_CURRENT,3); double low3=iLow(_Symbol,PERIOD_CURRENT,3); double close3=iClose(_Symbol,PERIOD_CURRENT,3); if(open3>close3) { if(open2<close2) { if(open2>low3&&close2<high3) { if(open<close&&open>open2&&open<close2) { if(close>high3) { createObj(time,low,217, clrGreen,"3 Inside Up"); { return 1; } } } } } } if(open3<close3) { if(open2>close2) { if(open2<high3&&close2>low3) { if(open>close&&open<open2&&open>close2) { if(close<low3) { createObj(time,high,218, clrRed,"3 Inside Down"); { return -1; } } } } } } return 0; } void createObj(datetime time, double price, int arrawCode, color clr, string txt) { string objName=" "; StringConcatenate(objName, "Signal@",time, "at",DoubleToString(price,_Digits),"(",arrawCode,")"); if(ObjectCreate(0,objName,OBJ_ARROW,0,time,price)) { ObjectSetInteger(0,objName,OBJPROP_ARROWCODE,arrawCode); ObjectSetInteger(0,objName,OBJPROP_COLOR,clr); if(clr==clrGreen) ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_TOP); if(clr==clrRed) ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_BOTTOM); } string candleName=objName+txt; if(ObjectCreate(0,candleName,OBJ_TEXT,0,time,price)) { ObjectSetString(0,candleName,OBJPROP_TEXT," "+txt); ObjectSetInteger(0,candleName,OBJPROP_COLOR,clr); } }
Le differenze in questo codice sono le condizioni del pattern
Nel caso di Three Inside Up
if(open3>close3) { if(open2<close2) { if(open2>low3&&close2<high3) { if(open<close&&open>open2&&open<close2) { if(close>high3) { createObj(time,low,217, clrGreen,"3 Inside Up"); { return 1; } } } } } }
Nel caso di Three Inside Down
if(open3<close3) { if(open2>close2) { if(open2<high3&&close2>low3) { if(open>close&&open<open2&&open>close2) { if(close<low3) { createObj(time,high,218, clrRed,"3 Inside Down"); { return -1; } } } } } }
Dopo aver compilato questo codice senza errori ed eseguito l’EA, si ottengono i segnali uguali a quelli degli esempi seguenti:
- Three Inside Up:
Come si può vedere dal grafico, abbiamo il segnale desiderato del Three Inside Up.
- Three Inside Down:
Come possiamo vedere dal grafico, abbiamo il segnale desiderato del Three Inside Down.
Conclusioni
Dopo aver letto gli argomenti precedenti di questo articolo, si suppone che abbiate capito come scrivere il codice per rilevare i pattern di candele nelle loro diverse formazioni, a candela singola, a doppia candela e a tre candele:
- Segnale di pattern a candela: abbiamo imparato a individuare i modelli Doji e Hammer.
- Pattern a doppia candela: abbiamo imparato a individuare i modelli Engulfing, Piecing Line e Dark Cloud Cover.
- Pattern a tre candele: abbiamo imparato a creare un programma in grado di rilevare i modelli Star e Three Inside.
Spero che questo articolo sia utile per aiutarvi a ottenere una migliore comprensione.
Tradotto dall’inglese da MetaQuotes Ltd.
Articolo originale: https://www.mql5.com/en/articles/12385





- App di trading gratuite
- Oltre 8.000 segnali per il copy trading
- Notizie economiche per esplorare i mercati finanziari
Accetti la politica del sito e le condizioni d’uso