Se sei un trader e utilizzi MetaTrader 4, saprai quanto sia importante avere un quadro chiaro della tendenza del mercato. Oggi ti presento un indicatore grafico che ti permette di visualizzare la tendenza attuale su tutti i time frame in un'unica interfaccia semplice e intuitiva.
Questo indicatore si basa sul Slope Direction Trend e, a differenza di altre versioni già disponibili, mostra tutte le tendenze in un solo pannello grafico sullo schermo.
Se vuoi dare un'occhiata a vari risultati, puoi cercare su questo link.
Ho preso l'idea originale di questo indicatore e l'ho trasformata in un pannello grafico che visualizza tutti i time frame. Ho apportato alcune modifiche al codice originale. Una delle principali modifiche è la possibilità di scegliere il metodo di media mobile seconda utilizzato per la smussatura. Mentre il codice originale utilizzava una media ponderata lineare, ho dato la possibilità all'utente di selezionare il metodo per una smussatura più adeguata. Infatti, utilizzando la media ponderata per entrambi i calcoli, l'indicatore diventa troppo reattivo, e questo potrebbe portare a letture errate sulla tendenza attuale. Se invece utilizziamo una media semplice come secondo metodo di smussatura, otteniamo una tendenza più rappresentativa di dove sta andando il prezzo.
Un'altra modifica importante è la capacità di non solo rilevare la direzione della tendenza (su, giù o piatta), ma anche di ottenere il suo valore. Ne parlerò in un altro articolo che pubblicherò presto, dove spiegherò come utilizzare un indicatore double SlopeDirection per creare un Expert Advisor.

Ma per ora, diamo un'occhiata veloce al codice. Iniziamo definendo i nomi degli oggetti che utilizzeremo. È buona pratica fare questo, in quanto ogni volta che metti un nome di oggetto tra virgolette, il programma riserva dello spazio per esso. Definendoli una sola volta (utilizzando un'istruzione #define), si utilizza spazio nel codice solo una volta.
// Definizione delle direzioni di tendenza#define UPTREND 1#define DOWNTREND -1#define FLATTREND 0// Definizione degli oggetti#define TrendPanel "TrendPanel"#define InfoLine1 "InfoLine1"#define InfoLine2 "InfoLine2"#define TrendLabel "Trend: M1 M5 M15 M30 H1 H4 D1 W1 MN"#define TrendUp "\233"#define TrendDown "\234"#define TrendFlat "\232"#define TrendUnknown "\251"#define StatObjectError "%s(%d) Impossibile creare '%s'. Errore = %d"
Successivamente, definisco due array. Uno con la posizione in pixel per ciascuno dei 9 time frame e l'altro con i time frame stessi. Questi vengono definiti come variabili globali.
// Definizione delle variabili globaliint TrendPosition[] = { 44, 64, 88, 114, 136, 156, 174, 194, 216 }; int TrendPeriods[] = { PERIOD_M1, PERIOD_M5, PERIOD_M15, PERIOD_M30, PERIOD_H1, PERIOD_H4, PERIOD_D1, PERIOD_W1, PERIOD_MN1 };
La nostra funzione OnInit() chiama una funzione per creare il pannello e gli oggetti all'interno del pannello. Effettua anche un rapido controllo sui bar utilizzati per calcolare la tendenza. Utilizzare meno di 3 è praticamente inutile.
//+------------------------------------------------------------------+//| Funzione di inizializzazione dell'indicatore personalizzato |//+------------------------------------------------------------------+int OnInit() { // Crea oggetti per il pannello dell'indicatore if(Create_Panel() && BarCount >= 3) return(INIT_SUCCEEDED); else return(INIT_FAILED); }
Non entrerò nei dettagli su come funziona la funzione GetTrend(), esistono già buone documentazioni su questo sito per questo. Diamo solo un'occhiata alla funzione grafica DisplayTrend().
//+------------------------------------------------------------------+//| Visualizza la tendenza attuale per tutti i time frame//+------------------------------------------------------------------+void DisplayTrend(void) { int i, cntr, Trend, LastTrend; string str; for(i=1; i<10; i++) { str = "Trend" + DoubleToStr(i, 0); Trend = (int)GetTrend(TrendPeriods[i-1], BarCount, Method); if(Trend == FLATTREND) { // Sono piatto, trova l'ultima direzione di tendenza cntr = 1; do { LastTrend = (int)GetTrend(TrendPeriods[i-1], BarCount, Method, false, cntr++); } while(LastTrend == Trend); ObjectSetText(str, TrendFlat, 8, "WingDings", (LastTrend == UPTREND ? Green : Red)); ObjectSetInteger(0, str, OBJPROP_YDISTANCE, 6); } else { ObjectSetText(str, (Trend == UPTREND ? TrendUp : TrendDown), 8, "WingDings", (Trend == UPTREND ? Green : Red)); ObjectSetInteger(0, str, OBJPROP_YDISTANCE, 5 + (Trend == UPTREND ? 1 : -1)); } } }
In sostanza, cicliamo attraverso l'array TrendPeriods[] per ottenere tutti i time frame e impostiamo la freccia di tendenza in base alla direzione della tendenza di quel time frame. Se la tendenza è piatta, troviamo la prima direzione che non è piatta per sapere da dove proviene la tendenza, in modo da visualizzare la freccia laterale nel colore di quella direzione.
La funzione Create_Panel() nel nostro OnInit() crea gli oggetti ancorati in basso a sinistra dello schermo e utilizza TrendPosition[] per posizionare le frecce al posto giusto.
//+------------------------------------------------------------------+//| Crea il pannello di tendenza in basso a sinistra dello schermo//+------------------------------------------------------------------+bool Create_Panel(void) { int i; string str; // Crea la finestra dell'indicatore di tendenza if(ObjectCreate(TrendPanel, OBJ_RECTANGLE_LABEL, 0, 0, 0)) { ObjectSetInteger(0, TrendPanel, OBJPROP_XDISTANCE, 1); ObjectSetInteger(0, TrendPanel, OBJPROP_YDISTANCE, 29); ObjectSetInteger(0, TrendPanel, OBJPROP_XSIZE, 240); ObjectSetInteger(0, TrendPanel, OBJPROP_YSIZE, 26); ObjectSetInteger(0, TrendPanel, OBJPROP_BGCOLOR, White); ObjectSetInteger(0, TrendPanel, OBJPROP_BORDER_TYPE, 0); ObjectSetInteger(0, TrendPanel, OBJPROP_CORNER, CORNER_LEFT_LOWER); ObjectSetInteger(0, TrendPanel, OBJPROP_COLOR, Red); ObjectSetInteger(0, TrendPanel, OBJPROP_STYLE, STYLE_SOLID); ObjectSetInteger(0, TrendPanel, OBJPROP_WIDTH, 2); ObjectSetInteger(0, TrendPanel, OBJPROP_BACK, false); ObjectSetInteger(0, TrendPanel, OBJPROP_SELECTABLE, false); ObjectSetInteger(0, TrendPanel, OBJPROP_SELECTED, false); ObjectSetInteger(0, TrendPanel, OBJPROP_HIDDEN, true); ObjectSetString(0, TrendPanel, OBJPROP_TOOLTIP, "\n"); } else { PrintFormat(StatObjectError, __FUNCTION__, __LINE__, TrendPanel, GetLastError()); return(false); } if(ObjectCreate(InfoLine1, OBJ_LABEL, 0, 0, 0)) { ObjectSet(InfoLine1, OBJPROP_CORNER, CORNER_LEFT_LOWER); ObjectSet(InfoLine1, OBJPROP_XDISTANCE, 6); ObjectSet(InfoLine1, OBJPROP_YDISTANCE, 15); ObjectSetInteger(0, InfoLine1, OBJPROP_SELECTABLE, false); ObjectSetInteger(0, InfoLine1, OBJPROP_HIDDEN, true); ObjectSetString(0, InfoLine1, OBJPROP_TOOLTIP, "\n"); ObjectSetText(InfoLine1, TrendLabel, 8, "Arial", Black); } else { PrintFormat(StatObjectError, __FUNCTION__, __LINE__, InfoLine1, GetLastError()); return(false); } if(ObjectCreate(InfoLine2, OBJ_LABEL, 0, 0, 0)) { ObjectSet(InfoLine2, OBJPROP_CORNER, CORNER_LEFT_LOWER); ObjectSet(InfoLine2, OBJPROP_XDISTANCE, 6); ObjectSet(InfoLine2, OBJPROP_YDISTANCE, 5); ObjectSetInteger(0, InfoLine2, OBJPROP_SELECTABLE, false); ObjectSetInteger(0, InfoLine2, OBJPROP_HIDDEN, true); ObjectSetString(0, InfoLine2, OBJPROP_TOOLTIP, "\n"); ObjectSetText(InfoLine2, " " + DoubleToStr(BarCount, 0) + " / " + DoubleToStr(Method, 0), 8, "Arial", Black); } else { PrintFormat(StatObjectError, __FUNCTION__, __LINE__, InfoLine2, GetLastError()); return(false); } // Crea l'oggetto tendenza e visualizza la tendenza attuale for(i=1; i<10; i++) { str = "Trend" + DoubleToStr(i, 0); if(ObjectCreate(str, OBJ_LABEL, <:number>0, 0, 0)) { ObjectSet(str, OBJPROP_CORNER, CORNER_LEFT_LOWER); ObjectSet(str, OBJPROP_XDISTANCE, TrendPosition[i-1]); ObjectSet(str, OBJPROP_YDISTANCE, 5); ObjectSetInteger(0, str, OBJPROP_SELECTABLE, false); ObjectSetInteger(0, str, OBJPROP_HIDDEN, true); ObjectSetString(0, str, OBJPROP_TOOLTIP, "\n"); } else { PrintFormat(StatObjectError, __FUNCTION__, __LINE__, str, GetLastError()); return(false); } } // Visualizza la tendenza attuale DisplayTrend(); // Tutto ok return(true); }
Questa funzione restituirà TRUE se è riuscita a creare tutti gli oggetti, oppure restituirà FALSE se si è verificato un errore durante la creazione di un oggetto. La cosa bella è che l'indicatore visualizzerà nella scheda ESPERTI della tua console il codice di errore e il numero di riga del codice dove si è verificato l'errore.
Abbiamo anche bisogno di aggiornare l'indicatore di tendenza per ogni nuovo tick che riceviamo. Questo viene fatto chiamando DisplayTrend() nella nostra funzione start().
//+------------------------------------------------------------------+//| Funzione di iterazione dell'indicatore personalizzato |//+------------------------------------------------------------------+int start() { // Visualizza la tendenza attuale per tutti i time frame DisplayTrend(); return(0); }
Infine, distruggiamo tutti gli oggetti creati dall'indicatore quando chiudiamo l'indicatore.
//+------------------------------------------------------------------+//| Funzione di deinizializzazione |//+------------------------------------------------------------------+voidOnDeinit(constint reason) { // Elimina gli oggetti dell'indicatore if(ObjectFind(TrendPanel) >= 0) ObjectDelete(TrendPanel); if(ObjectFind(InfoLine1) >= 0) ObjectDelete(InfoLine1); if(ObjectFind(InfoLine2) >= 0) ObjectDelete(InfoLine2); for(int i=1; i<10; i++) if(ObjectFind("Trend"+DoubleToStr(i, 0)) >= 0) ObjectDelete("Trend"+DoubleToStr(i, 0)); }
Questo è tutto! Ora hai un bel pannello indicatore che mostra la tendenza attuale per tutti i time frame in basso a sinistra dello schermo.
Buon trading!

Commento 0