Home Indicatore tecnico Post

Indicatore per MetaTrader 4: Visualizza la Tendenza Attuale su Tutti i Time Frame

Allegato
15620.zip (2.17 KB, Scarica 0 volte)

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.

SlopeDirection

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 globali
int      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, 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                                        |
//+------------------------------------------------------------------+
void OnDeinit(const int 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!

Post correlati

Commento (0)