
Come creare un indicatore True Strength Index personalizzato utilizzando MQL5
Introduzione
Gli indicatori tecnici possono essere molto utili se li utilizziamo correttamente, in quanto possono fornire ulteriori informazioni, difficilmente individuabili osservando solo l'azione del prezzo. Ci sono molti indicatori tecnici già pronti che possiamo utilizzare, ma a volte ci accorgiamo che abbiamo bisogno di personalizzarli per indicarci o darci indicazioni specifiche oppure dobbiamo crearne uno nuovo in base alle nostre idee vincenti. Esiste un modo per creare questi indicatori personalizzati in MQL5 e utilizzarli nella piattaforma di trading MetaTrader 5. In questo articolo condividerò con voi come creare l'indicatore True Strength Index da zero. Impareremo le specifiche di questo indicatore e vedremo come calcolarlo nel nostro codice. Non solo, ma impareremo come utilizzare questo indicatore personalizzato in un sistema di trading creando un Expert Advisor. Tratteremo tutto questo attraverso i seguenti argomenti:
- Definizione di True Strenght Index (TSI)
- Un semplice indicatore TSI personalizzato
- Un EA TSI personalizzato
- Sistema EA TSI
- Conclusioni
Dopo aver compreso gli argomenti precedentemente menzionati, saremo in grado di capire bene come utilizzare e interpretare l'indicatore True Strength Index, saremo in grado di calcolarlo e di codificare questo indicatore come indicatore personalizzato nel linguaggio MQL5 da utilizzare in MetaTrader 5. Sarete anche in grado di implementare l'indicatore in altri sistemi di trading o EA. Se volete sviluppare le vostre capacità di codifica, vi consiglio di provare a codificare i contenuti qui presenti da soli, poiché questa pratica è un passaggio molto importante in qualsiasi processo di apprendimento o percorso. Utilizzeremo MetaTrader 5 per scrivere il nostro codice MQL5 nell'IDE integrata del terminale di trading MetaTrader 5. Se non avete la piattaforma o non sapete come scaricarla e usarla, potete leggere l'argomento "Scrivere codice MQL5 in MetaEditor" nei miei articoli precedenti.
Definizione di True Strenght Index (TSI)
In questa parte, identificheremo l'indicatore tecnico True Strength Index (TSI) per comprenderlo correttamente. È stato sviluppato da William Blau come indicatore tecnico che misura il momentum dell'azione del prezzo, ossia misura la forza dello strumento, se è forte o debole. Oscilla intorno alla linea dello zero, quindi è un indicatore oscillatore di momentum . È possibile utilizzare una linea di segnale per ottenere ulteriori segnali di acquisto o di vendita sulla base degli incroci tra queste linee. Tuttavia, possiamo ottenere segnali basati solo sulla linea del TSI, in base al suo incrocio con il livello zero. Se è al di sopra della linea dello zero, significa che il momentum è rialzista, mentre se è al di sotto dello zero significa che il momentum è ribassista. Può essere utilizzato per individuare aree di ipercomprato e ipervenduto e per rilevare divergenze rialziste e ribassiste. Poiché sappiamo che è necessario confermare i suoi segnali per aumentare il peso delle prove, è meglio utilizzarlo insieme ad altri strumenti tecnici, che dovremmo usare nello stesso contesto della price action per ottenere informazioni migliori.
Vediamo ora come calcolare questo indicatore. Il calcolo viene eseguito in diverse fasi, che sono:
Calcolare il momentum con doppia attenuazione:
- Calcolo del momentum (variazione di prezzo) sottraendo il prezzo precedente da quello attuale
- Calcolo della prima attenuazione ottenendo l'EMA a 25 periodi del momentum calcolato
- Calcolo della seconda attenuazione ottenendo l'EMA a 13 periodi della prima attenuazione (EMA a 25 periodi del momentum calcolato)
Calcolare il momentum con doppia attenuazione assoluto:
- Calcolo del momentum assoluto sottraendo il prezzo assoluto precedente dal prezzo assoluto attuale
- Calcolo della prima attenuazione ottenendo l'EMA a 25 periodi del momentum assoluto calcolato
- Calcolo della seconda attenuazione ottenendo l'EMA a 13 periodi della prima attenuazione (EMA a 25 periodi del momentum assoluto calcolato)
Calcolare TSI = 100*( Momentum con doppia attenuazione / Momentum assoluto con doppia attenuazione)
Questo calcolo si tradurrà in una linea oscillante intorno allo zero che misura il momentum dell'azione del prezzo e individua le aree di ipercomprato e ipervenduto, come abbiamo detto e altro.
Un Indicatore TSI Semplice e Personalizzato
Il linguaggio di programmazione MQL5 dispone di molti indicatori tecnici predefiniti e possiamo utilizzarli nei nostri sistemi tramite le funzioni predefinite. Abbiamo già parlato di molti di questi indicatori nei precedenti articoli di questa serie, discutendo di come progettare un sistema di trading basato su questi popolari indicatori tecnici. Potete consultare gli articoli precedenti e magari trovare qualcosa di utile. La domanda ora è come creare un indicatore se non esiste nel pacchetto standard di fornitura della piattaforma o anche se esiste come creare un indicatore personalizzato per ottenere i segnali o le attivazioni desiderate. La risposta breve è quella di creare un indicatore personalizzato utilizzando il linguaggio di programmazione principale ed è quello che faremo in questa parte.
Impareremo come creare il nostro indicatore True Strength Index personalizzato utilizzando MQL5. Poi utilizzeremo le sue caratteristiche in altri sistemi o EA. I passaggi seguenti servono a creare questo indicatore personalizzato.
Creare i parametri aggiuntivi utilizzando #property e dopo di esso specificare il valore dell'identificatore e i seguenti sono i parametri da specificare:
- (indicator_separate_window) - per mostrare l'indicatore in una finestra separata.
- (indicator_buffers) - per specificare il numero di buffer dell'indicatore, specificheremo (8).
- (indicator_plots) - per specificare il numero di serie grafiche nell'indicatore, specificheremo (1).
- (indicator_label1) - per impostare l'etichetta del numero della serie grafica, specificheremo (TSI).
- (indicator_type1) - per specificare il tipo di tracciato grafico specificando un valore tra i valori ENUM_DRAW_TYPE, specificheremo (DRAW_LINE).
- (indicator_color1) - per specificare il colore della linea dell'indicatore che viene visualizzata, specificheremo (clrBlue).
- (indicator_style1) - per specificare lo stile della linea dell'indicatore, specificheremo (STYLE_SOLID).
- (indicator_width1) - per specificare lo spessore della linea dell'indicatore, specificheremo (3).
#property indicator_separate_window #property indicator_buffers 8 #property indicator_plots 1 #property indicator_label1 "TSI" #property indicator_type1 DRAW_LINE #property indicator_color1 clrBlue #property indicator_style1 STYLE_SOLID #property indicator_width1 3
È necessario includere il file MovingAverage.mqh per utilizzare i suoi componenti nel nostro calcolo; questo file è presente nella cartella Include utilizzando il comando #include. Assicuratevi di scrivere il nome del file allo stesso modo del nome del file.
#include <MovingAverages.mqh>
È necessario impostare due input per i periodi di attenuazione che verranno utilizzati nel calcolo dell'indicatore, utilizzando la classe input per inserire questi valori da parte dell'utente, nel caso in cui sia necessario aggiornare i valori predefiniti specificati nel programma. Successivamente, determineremo il tipo di dati delle variabili (InpSmPeriod1, InpSmPeriod2) che dobbiamo dichiarare utilizzando uint, che è un numero intero senza segno. Quindi assegneremo (25) a InpSmPeriod1 e (13) a InpSmPeriod2 come valori predefiniti.
input uint InpSmPeriod1 = 25; // Smoothing period 1 input uint InpSmPeriod2 = 13; // Smoothing period 2
Creare due variabili intere per i periodi di attenuazione (smperiod1,smperiod2).
int smperiod1; int smperiod2;
Creazione di sette array per i buffer dell’indicatore
double indBuff[]; double momBuff[]; double momSmBuff1[]; double momSmBuff2[]; double absMomBuff[]; double absMomSmBuff1[]; double absMomSmBuff2[];
All'interno della funzione OnInit () verranno eseguiti i seguenti passaggi:
Dichiarare le variabili di (smperiod1,smperiod2) che restituiscono il valore 2 se l'input dell'utente di InpSmPeriod1 e InpSmPeriod2 è inferiore a 2 o restituiscono i valori di InpSmPeriod1 e InpSmPeriod2 se c'è altro.
smperiod1=int(InpSmPeriod1<2 ? 2 : InpSmPeriod1); smperiod2=int(InpSmPeriod2<2 ? 2 : InpSmPeriod2);
Legare i buffer dell’indicatore con gli array utilizzando la funzione (SetIndexBuffer). I suoi parametri sono:
index: per impostare il numero del buffer dell'indicatore partendo dal numero 0 a 7 nel nostro programma.
buffer[]: per specificare l'array dichiarato nell'indicatore personalizzato.
data_type: per specificare il tipo di dati memorizzati nell'array dell’indicatore.
SetIndexBuffer(0,indBuff,INDICATOR_DATA); SetIndexBuffer(2,momBuff,INDICATOR_CALCULATIONS); SetIndexBuffer(3,momSmBuff1,INDICATOR_CALCULATIONS); SetIndexBuffer(4,momSmBuff2,INDICATOR_CALCULATIONS); SetIndexBuffer(5,absMomBuff,INDICATOR_CALCULATIONS); SetIndexBuffer(6,absMomSmBuff1,INDICATOR_CALCULATIONS); SetIndexBuffer(7,absMomSmBuff2,INDICATOR_CALCULATIONS);
L'impostazione del valore della proprietà dell'indicatore corrispondente, questa proprietà dell'indicatore (prop value) deve essere di tipo stringa utilizzando la funzione (IndicatorSetString) con la variante di chiamata con l'indicazione del solo identificatore della proprietà. Questa fase serve a impostare un nome breve per l'indicatore e a determinare i periodi da visualizzare nella parte superiore sinistra della finestra dell'indicatore. I suoi parametri:
- prop_id: per specificare l'identificatore della proprietà dell'indicatore, che sarà una dall’enumerazione (ENUM_CUSTOMIND_PROPERTY_STRING). Nel nostro programma sarà (INDICATOR_SHORTNAME).
- prop_value: per specificare il valore della proprietà, che sarà un tipo di dato stringa. Sarà "True Strength Index ("+(string)smperiod1+", "+(string)smperiod2+")".
IndicatorSetString(INDICATOR_SHORTNAME,"True Strength Index ("+(string)smperiod1+","+(string)smperiod2+")");
Impostazione di un altro valore della proprietà dell'indicatore in un tipo di dati intero per normalizzare il valore dell'indicatore in base alle cifre utilizzando la funzione (IndicatorSetInteger) con la variante di chiamata che specifica solo l'identificatore della proprietà. I suoi parametri:
- prop_id: per specificare l'identificatore della proprietà dell'indicatore, che sarà una dall’enumerazione (ENUM_CUSTOMIND_PROPERTY_INTEGER). Nel nostro programma sarà (INDICATOR_DIGITS).
- prop_value: per specificare il valore della proprietà, che sarà di tipo intero. Sarà Digits().
IndicatorSetInteger(INDICATOR_DIGITS,Digits());
Impostazione del flag AS_SERIES all’array mediante il comando (ArraySetAsSeries).
ArraySetAsSeries(indBuff,true); ArraySetAsSeries(momBuff,true); ArraySetAsSeries(momSmBuff1,true); ArraySetAsSeries(momSmBuff2,true); ArraySetAsSeries(absMomBuff,true); ArraySetAsSeries(absMomSmBuff1,true); ArraySetAsSeries(absMomSmBuff2,true);
Dopo la funzione OnCalculate,
- Impostiamo il flag AS_SERIES sull'array close dalla parte OnCalculate e poi controlliamo se rates_total è inferiore a 2 restituire 0.
- Creare una variabile intera (limit) che sia uguale a (rates_total-prev_calculated).
- Verificare se la variabile limit è maggiore di 1, nel qual caso è necessario eseguire i seguenti passaggi:
- Aggiornamento della variabile limit con il risultato di (rates_total - 2).
- Inizializzazione degli array numerici di tipo double con un valore prestabilito mediante la funzione (ArrayInitialize). I suoi parametri sono array[] per specificare l'array numerico che deve essere inizializzato e l'altro parametro è value per specificare il nuovo valore che deve essere impostato.
ArraySetAsSeries(close,true); if(rates_total<2) return 0; int limit=rates_total-prev_calculated; if(limit>1) { limit=rates_total-2; ArrayInitialize(indBuff,EMPTY_VALUE); ArrayInitialize(momBuff,0); ArrayInitialize(momSmBuff1,0); ArrayInitialize(momSmBuff2,0); ArrayInitialize(absMomBuff,0); ArrayInitialize(absMomSmBuff1,0); ArrayInitialize(absMomSmBuff2,0); }
Creare un ciclo per aggiornare momBuff[i], absMomBuff[i]. Le nuove funzioni utilizzate in questa fase sono:
- Ciclo (for) con le sue tre espressioni e un operatore eseguibile.
- IsStopped() per verificare se si è verificato un arresto forzato del programma mql5.
- MathAbs che restituisce il valore assoluto (modulo) e possiamo usare la funzione fabs() per ottenere lo stesso risultato.
for(int i=limit; i>=0 && !IsStopped(); i--) { momBuff[i]=close[i]-close[i+1]; absMomBuff[i]=MathAbs(momBuff[i]); }
Verificare quanto segue utilizzando la funzione ExponentialMAOnBuffer del file Include (MovingAverage).
if(ExponentialMAOnBuffer(rates_total,prev_calculated,0,smperiod1,momBuff,momSmBuff1)==0) return 0; if(ExponentialMAOnBuffer(rates_total,prev_calculated,0,smperiod1,absMomBuff,absMomSmBuff1)==0) return 0; if(ExponentialMAOnBuffer(rates_total,prev_calculated,smperiod1,smperiod2,momSmBuff1,momSmBuff2)==0) return 0; if(ExponentialMAOnBuffer(rates_total,prev_calculated,smperiod1,smperiod2,absMomSmBuff1,absMomSmBuff2)==0) return 0;
Creare un altro ciclo per aggiornare la variabile indBuff[i] utilizzando la funzione for
for(int i=limit; i>=0 && !IsStopped(); i--) indBuff[i]=(absMomSmBuff2[i]!=0 ? 100.0*momSmBuff2[i]/absMomSmBuff2[i] : 0);
Alla fine del programma, è presente la funzione return (rates_total)
return(rates_total);
Ora abbiamo terminato il codice per creare il nostro indicatore personalizzato TSI; è inoltre possibile modificare le preferenze del codice per ulteriori personalizzazioni. Di seguito è riportato il codice completo in un blocco dell'indicatore creato:
//+------------------------------------------------------------------+ //| simple TSI.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" #property indicator_separate_window #property indicator_buffers 8 #property indicator_plots 1 #property indicator_label1 "TSI" #property indicator_type1 DRAW_LINE #property indicator_color1 clrBlue #property indicator_style1 STYLE_SOLID #property indicator_width1 3 #include <MovingAverages.mqh> input uint InpSmPeriod1 = 25; // Smoothing period 1 input uint InpSmPeriod2 = 13; // Smoothing period 2 int smperiod1; int smperiod2; double indBuff[]; double momBuff[]; double momSmBuff1[]; double momSmBuff2[]; double absMomBuff[]; double absMomSmBuff1[]; double absMomSmBuff2[]; int OnInit() { smperiod1=int(InpSmPeriod1<2 ? 2 : InpSmPeriod1); smperiod2=int(InpSmPeriod2<2 ? 2 : InpSmPeriod2); SetIndexBuffer(0,indBuff,INDICATOR_DATA); SetIndexBuffer(2,momBuff,INDICATOR_CALCULATIONS); SetIndexBuffer(3,momSmBuff1,INDICATOR_CALCULATIONS); SetIndexBuffer(4,momSmBuff2,INDICATOR_CALCULATIONS); SetIndexBuffer(5,absMomBuff,INDICATOR_CALCULATIONS); SetIndexBuffer(6,absMomSmBuff1,INDICATOR_CALCULATIONS); SetIndexBuffer(7,absMomSmBuff2,INDICATOR_CALCULATIONS); IndicatorSetString(INDICATOR_SHORTNAME,"True Strength Index ("+(string)smperiod1+","+(string)smperiod2+")"); IndicatorSetInteger(INDICATOR_DIGITS,Digits()); ArraySetAsSeries(indBuff,true); ArraySetAsSeries(momBuff,true); ArraySetAsSeries(momSmBuff1,true); ArraySetAsSeries(momSmBuff2,true); ArraySetAsSeries(absMomBuff,true); ArraySetAsSeries(absMomSmBuff1,true); ArraySetAsSeries(absMomSmBuff2,true); return(INIT_SUCCEEDED); } int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { ArraySetAsSeries(close,true); if(rates_total<2) return 0; int limit=rates_total-prev_calculated; if(limit>1) { limit=rates_total-2; ArrayInitialize(indBuff,EMPTY_VALUE); ArrayInitialize(momBuff,0); ArrayInitialize(momSmBuff1,0); ArrayInitialize(momSmBuff2,0); ArrayInitialize(absMomBuff,0); ArrayInitialize(absMomSmBuff1,0); ArrayInitialize(absMomSmBuff2,0); } for(int i=limit; i>=0 && !IsStopped(); i--) { momBuff[i]=close[i]-close[i+1]; absMomBuff[i]=MathAbs(momBuff[i]); } if(ExponentialMAOnBuffer(rates_total,prev_calculated,0,smperiod1,momBuff,momSmBuff1)==0) return 0; if(ExponentialMAOnBuffer(rates_total,prev_calculated,0,smperiod1,absMomBuff,absMomSmBuff1)==0) return 0; if(ExponentialMAOnBuffer(rates_total,prev_calculated,smperiod1,smperiod2,momSmBuff1,momSmBuff2)==0) return 0; if(ExponentialMAOnBuffer(rates_total,prev_calculated,smperiod1,smperiod2,absMomSmBuff1,absMomSmBuff2)==0) return 0; for(int i=limit; i>=0 && !IsStopped(); i--) indBuff[i]=(absMomSmBuff2[i]!=0 ? 100.0*momSmBuff2[i]/absMomSmBuff2[i] : 0); return(rates_total); }
Dopo aver compilato questo codice senza errori, troveremo l'indicatore tra quelli disponibili nella cartella Indicatori del navigatore, trascinandolo sul grafico desiderato, troveremo la finestra dell'indicatore e gli input uguali a quelli seguenti:
Abbiamo quindi due input che l'utente può determinare e i valori predefiniti sono 25 per il periodo 1 di attenuazione e 13 per il periodo 2 di attenuazione. Tuttavia, l'utente può modificarle in base alle proprie preferenze, come abbiamo detto.
Come si può vedere nell'immagine precedente, nella scheda Colori l'utente può scegliere il colore, la larghezza e lo stile della linea TSI. Dopo aver determinato le nostre preferenze di input e stile dell'indicatore, come abbiamo detto, possiamo trovare l'indicatore sul grafico come segue:
Come possiamo vedere nel grafico precedente, la linea dell'indicatore TSI si trova in una finestra separata sotto i prezzi e oscilla intorno allo zero. Abbiamo poi l'etichetta dell'indicatore, i periodi di attenuazione e il valore dell'indicatore.
Un EA TSI personalizzato
In questa parte impareremo in modo molto semplice come utilizzare il nostro indicatore personalizzato in un sistema automatizzato in modo che possa generare un segnale o un'azione specifica una volta che una determinata condizione viene attivata. Inizieremo a creare un sistema molto semplice tramite un Expert Advisor, che genererà un commento sul grafico con il valore attuale del TSI, prima di sviluppare un EA che esegua istruzioni più complesse.
Di seguito sono riportati i passaggi necessari per creare il nostro Expert Advisor:
- Creazione di una variabile intera (TSI).
- Definire TSI utilizzando la funzione iCustom che restituisce l'handle dell'indicatore e i suoi parametri sono:
- symbol: per specificare il nome del simbolo, useremo _Symbol da applicare al simbolo corrente.
- period: per specificare il timeframe, si utilizzerà _period da applicare al timeframe corrente.
- name: per specificare il percorso dell'indicatore personalizzato.
- Stampa del testo "TSI System Removed" nella parte OnDeinit(const int reason) dopo la rimozione dell'EA.
- Creare un array tsiVal[]
- Ottenere i dati del buffer dell'indicatore TSI utilizzando la funzione CopyBuffer con la variante di chiamata tramite la prima posizione e il numero di elementi richiesti. I suoi parametri sono:
- indicator_handle: per specificare l'handle dell'indicatore restituito dall'indicatore, utilizzeremo (TSI).
- buffer_num: per specificare il numero di buffer dell'indicatore, useremo (0).
- start_pos: per specificare la posizione iniziale da copiare, useremo (0).
- count: per specificare il numero di dati da copiare, useremo (1).
- buffer[]: per specificare l'array in cui copiare, useremo (tsiVal).
- Utilizzeremo la funzione Comment per mostrare il valore TSI corrente convertito in una stringa mediante la funzione (DoubleToString) con i parametri value per specificare il valore TSI corrente e digits per specificare il numero di cifre, utilizzeremo (_Digits) per quello corrente.
Il codice completo sarà uguale al seguente:
//+------------------------------------------------------------------+ //| customSimpleTSI-EA.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" int TSI; int OnInit() { TSI=iCustom(_Symbol,_Period,"My Files\\TSI\\simpleTSI"); return(INIT_SUCCEEDED); } void OnDeinit(const int reason) { Print("TSI System Removed"); } void OnTick() { double tsiVal[]; CopyBuffer(TSI,0,0,1,tsiVal); Comment("TSI Value ",DoubleToString(tsiVal[0],_Digits)); }
Dopo aver compilato il codice senza errori e averlo eseguito, verrà allegato al grafico. Di seguito è riportato un esempio di segnale dai test:
Come si può notare, nel grafico in alto a sinistra è presente un commento con il valore attuale TSI. Se vogliamo essere sicuri che il segnale sia lo stesso dell'indicatore, possiamo allegare l'EA e inserire l'indicatore allo stesso tempo per avere dei valori. Il seguente è per assicurarsi del nostro lavoro:
Come possiamo vedere in alto a destra abbiamo l'EA allegato e il suo segnale appare nell'angolo in alto a sinistra con il valore TSI corrente; allo stesso tempo abbiamo l'indicatore TSI inserito nel grafico come finestra separata sotto i prezzi e il suo valore sopra la sua linea nell'angolo a sinistra è lo stesso del segnale dell'EA.
EA Sistema TSI
In questa parte, svilupperemo un EA basato sull'indicatore TSI personalizzato creato per ottenere segnali basati su una strategia specifica. Si prega di notare che la strategia che stiamo per discutere ha uno scopo puramente educativo. Avrà comunque bisogno di ottimizzazioni, proprio come qualsiasi altra strategia. È quindi necessario testarla prima di utilizzarla per un conto reale per assicurarsi che sia utile per voi.
Utilizzeremo l'indicatore TSI personalizzato combinato con le due medie mobili per ottenere segnali di acquisto e di vendita basati su una strategia specifica, che è la seguente:
Utilizzeremo due medie mobili semplici, una veloce con un periodo di 10 e l'altra lenta con un periodo di 20, oltre al nostro indicatore TSI personalizzato. Se il valore della precedente MA veloce è inferiore alla precedente MA lenta e allo stesso tempo la MA veloce corrente è maggiore della MA lenta corrente, significa che abbiamo un incrocio di MA rialzista, quindi verificheremo se il valore del TSI corrente è maggiore di zero e dobbiamo ottenere un segnale di acquisto come commento sul grafico. Se il valore della precedente MA veloce è maggiore della precedente MA lenta e allo stesso tempo la MA veloce attuale è minore della MA lenta attuale, significa che abbiamo un incrocio di MA ribassista, quindi verificheremo se il valore attuale del TSI è minore di zero, per ottenere un segnale di vendita come commento sul grafico.
Semplicemente,
Se fastMA[1]>slowMA[1] && fastMA[0]<slowMA[0] && tsiVal[0]<0 ==> Segnale di vendita
Di seguito è riportato il codice completo per creare questo tipo di sistema:
//+------------------------------------------------------------------+ //| TSI System EA.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" input ENUM_MA_METHOD inpMAType = MODE_SMA; //Moving Average Type input ENUM_APPLIED_PRICE inpPriceType = PRICE_CLOSE; //Price type input int inpFastMAPeriod = 10; // Fast moving average period input int inpSlowMAPeriod = 20; //Slow moving average period int tsi; double fastMAarray[], slowMAarray[]; int OnInit() { tsi=iCustom(_Symbol,_Period,"My Files\\TSI\\simpleTSI"); return(INIT_SUCCEEDED); } void OnDeinit(const int reason) { Print("TSI System Removed"); } void OnTick() { double tsiVal[]; CopyBuffer(tsi,0,0,1,tsiVal); int fastMA =iMA(_Symbol,_Period,inpFastMAPeriod,0,inpMAType,inpPriceType); int slowMA =iMA(_Symbol,_Period,inpSlowMAPeriod,0,inpMAType,inpPriceType); ArraySetAsSeries(fastMAarray,true); ArraySetAsSeries(slowMAarray,true); CopyBuffer(fastMA,0,0,3,fastMAarray); CopyBuffer(slowMA,0,0,3,slowMAarray); if(fastMAarray[1]<slowMAarray[1]&&fastMAarray[0]>slowMAarray[0]) { if(tsiVal[0]>0) { Comment("Buy Signal", "\nTSI Value ",DoubleToString(tsiVal[0],_Digits), "\nfastMA ",DoubleToString(fastMAarray[0],_Digits), "\nslowMA ",DoubleToString(slowMAarray[0],_Digits)); } } if(fastMAarray[1]>slowMAarray[1]&&fastMAarray[0]<slowMAarray[0]&&tsiVal[0]<0) { if(tsiVal[0]<0) { Comment("Sell Signal", "\nTSI Value ",DoubleToString(tsiVal[0],_Digits), "\nfastMA ",DoubleToString(fastMAarray[0],_Digits), "\nslowMA ",DoubleToString(slowMAarray[0],_Digits)); } } }
Le differenze in questo codice sono le seguenti:
Creare quattro input da parte dell'utente per il tipo di media mobile, per il tipo di prezzo applicato, per il periodo della MA veloce e per il periodo della MA lenta e assegnare loro dei valori predefiniti.
input ENUM_MA_METHOD inpMAType = MODE_SMA; //Moving Average Type input ENUM_APPLIED_PRICE inpPriceType = PRICE_CLOSE; //Price type input int inpFastMAPeriod = 10; // Fast moving average period input int inpSlowMAPeriod = 20; //Slow moving average period
Creare due array per l'array MA veloce e MA lento.
double fastMAarray[], slowMAarray[];
Definire le due medie mobili utilizzando la funzione iMA predefinita che restituisce l'handle della media mobile e i suoi parametri sono:
- symbol: utilizzeremo _Symbol da applicare a quello corrente.
- period: utilizzeremo _period per applicare il timeframe corrente.
- ma_period: utilizzeremo l'input dell'utente per le MA veloci e lente.
- ma_shift: useremo (0) perché non è necessario lo scostamento.
- ma_method: utilizzeremo l'input dell'utente per il tipo di MA.
- applied_price: utilizzeremo l'input dell'utente per il tipo di prezzo.
int fastMA =iMA(_Symbol,_Period,inpFastMAPeriod,0,inpMAType,inpPriceType); int slowMA =iMA(_Symbol,_Period,inpSlowMAPeriod,0,inpMAType,inpPriceType);
Impostazione del flag AS_SERIES mediante la funzione ArraySetAsSeries per le MA lente e veloci
ArraySetAsSeries(fastMAarray,true); ArraySetAsSeries(slowMAarray,true);
Ottenere i dati dal buffer delle due medie mobili utilizzando la funzione CopyBuffer
CopyBuffer(fastMA,0,0,3,fastMAarray); CopyBuffer(slowMA,0,0,3,slowMAarray);
Definizione delle condizioni della strategia,
In caso di segnale di acquisto:
Se fastMA precedente è inferiore a slowMA precedente e la fastMA attuale è maggiore della slowMA attuale e allo stesso tempo tsiVal attuale è maggiore di zero, abbiamo bisogno che l'EA restituisca il segnale di acquisto come commento sul grafico, come l'ordine seguente:
- Segnale di Acquisto
- Valore di TSI
- Il valore di fastMA
- Il valore di slowMA
if(fastMAarray[1]<slowMAarray[1]&&fastMAarray[0]>slowMAarray[0]) { if(tsiVal[0]>0) { Comment("Buy Signal", "\nTSI Value ",DoubleToString(tsiVal[0],_Digits), "\nfastMA ",DoubleToString(fastMAarray[0],_Digits), "\nslowMA ",DoubleToString(slowMAarray[0],_Digits)); } }
In caso di segnale di vendita:
Se fastMA precedente è maggiore della slowMA precedente e la fastMA attuale è minore della slowMA attuale e allo stesso tempo tsiVal attuale è minore di zero, è necessario che l'EA restituisca il segnale di vendita come commento sul grafico, come nell'ordine seguente:
- Segnale di Vendita
- Valore di TSI
- Il valore di fastMA
- Il valore di slowMA
if(fastMAarray[1]>slowMAarray[1]&&fastMAarray[0]<slowMAarray[0]&&tsiVal[0]<0) { if(tsiVal[0]<0) { Comment("Sell Signal", "\nTSI Value ",DoubleToString(tsiVal[0],_Digits), "\nfastMA ",DoubleToString(fastMAarray[0],_Digits), "\nslowMA ",DoubleToString(slowMAarray[0],_Digits)); } }
Dopo aver compilato questo codice senza errori e averlo trascinato per l'esecuzione per ottenere i suoi segnali, possiamo trovare la sua finestra uguale alla seguente per la scheda Inputs:
Come possiamo vedere, abbiamo i quattro input per il tipo di MA, il tipo di prezzo, del periodo della MA veloce e del periodo della MA lenta. Dopo aver impostato le nostre preferenze e aver premuto OK, possiamo notare che l'EA è allegato al grafico e i suoi segnali saranno i seguenti:
In caso di segnale di acquisto
Come possiamo vedere nel grafico precedente, abbiamo un segnale di acquisto come commento nell'angolo in alto a sinistra, secondo le condizioni della nostra strategia, uguali a quelle seguenti:
- Segnale di Acquisto
- Valore di TSI
- Il valore di fastMA
- Il valore di slowMA
In caso di segnale di vendita:
Come si può vedere nel grafico precedente, abbiamo un segnale di vendita come commento nell'angolo in alto a sinistra, in base alle condizioni della nostra strategia, come le seguenti:
- Segnale di Vendita
- Valore di TSI
- Il valore di fastMA
- Il valore di slowMA
Conclusioni
In questo articolo abbiamo appreso come sia possibile creare il proprio indicatore tecnico True Strength Index per implementare le proprie impostazioni e preferenze specifiche. Abbiamo visto quali informazioni e spunti fornisce questo indicatore, che possono essere molto utili nel trading. Abbiamo anche imparato come utilizzare questo indicatore personalizzato in un semplice sistema di trading per generare il valore corrente dell'indicatore TSI come commento sul grafico. Abbiamo anche visto come utilizzare l'indicatore in un sistema di trading automatico creando un EA che utilizza i dati del TSI in combinazione con un altro strumento tecnico, che nel nostro caso è la media mobile. Questa combinazione tra il TSI personalizzato e le due medie mobili ha generato segnali di acquisto e vendita basati su una strategia specifica, che abbiamo esaminato in dettaglio nell'argomento EA Sistema TSI.
Spero che questo articolo sia utile per l'apprendimento del trading e della programmazione. Se volete leggere altri articoli sugli indicatori e imparare a creare sistemi di trading basati sugli indicatori tecnici più diffusi, consultate i miei articoli precedenti, in cui tratto gli indicatori più comuni come la media mobile, le Bande di Bollinger, l'RSI, il MACD, lo Stocastico, il SAR parabolico, l'ATR e altri.
Tradotto dall’inglese da MetaQuotes Ltd.
Articolo originale: https://www.mql5.com/en/articles/12570





- 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