English Русский 中文 Español Deutsch 日本語 Português 한국어 Français Türkçe
Creazione di un Indicatore Multivaluta, Utilizzando un Numero di Buffer di Indicatori Intermedi

Creazione di un Indicatore Multivaluta, Utilizzando un Numero di Buffer di Indicatori Intermedi

MetaTrader 5Indicatori | 16 dicembre 2021, 10:28
188 0
Alexey Klenov
Alexey Klenov

Introduzione

Tutto è iniziato quando ho sentito parlare per la prima volta degli indicatori di cluster dall'articolo Basi Teoriche per la Costruzione di Indicatori di Cluster per FOREX. Questo è stato molto interessante per me all'epoca e ho deciso di scrivere qualcosa di simile in termini di analisi multi-mercato. Inizialmente ho implementato la mia versione dell'indicatore, nome in codice MultiCurrencyIndex, in cui i valori calcolati degli indici valutari vengono utilizzati per calcolare i tassi degli indicatori classici (RSI, MACD, CCI). 

E ora ti dirò come ho trasferito questo indicatore su una nuova piattaforma, MetaTrader 5 in complemento con MQL5, tranne che invece di calcolare il CCI, calcolerò l'indicatore di Stochastics (Stochastic Oscillator), che è più lungimirante ( secondo me).

Cominciamo con alcune definizioni.

Indice del dollaro - - doppio valore calcolato dalla formula, gentilmente fornitami da Neutron.

La formula per calcolare l'indice USD,

dove c'è USD/YYY - tutte le quotazioni dirette, come USD/CHF, XXX/USD - tutte all'indietro, come EUR/USD.

Altri indici sono calcolati dai valori delle coppie di valute Close, contenenti USD.

Linee principali: due linee dell'indicatore, che riflettono i dati calcolati, correlate direttamente al grafico corrente. Ad esempio, sul grafico EURUSD verranno visualizzate le linee delle valute EUR e USD.

Linee supplementari - altre linee dell'indicatore calcolate, non correlate al grafico corrente. Ad esempio, per lo stesso grafico EURUSD, saranno le linee delle valute GBP, CHF, JPY, CAD, AUD e NZD.

Close - il valore del prezzo di chiusura della barra del timeframe corrente (tipo double) per la coppia di valute necessaria.

Cominciamo.

L'impostazione del problema

Per cominciare dobbiamo impostare il problema.

  1. Sincronizzare i grafici delle coppie di valute interessate di questo timeframe.
  2. Ottieni l'accesso ai dati di Close di sette coppie di valute: EURUSD, GBPUSD, USDCHF, USDJPY, USDCAD, AUDUSD, NZDUSD e inseriscili nei buffer degli indicatori, progettati per calcoli ausiliari.
  3. Sulla base dei dati ottenuti al punto (2), calcola per la barra correntel'indice del dollaro.
  4. Conoscendo l'indice del dollaro per la barra corrente, calcola gli indici di valuta rimanenti.
  5. Eseguire i calcoli dei dati (voci 3 e 4) il numero di volte richiesto per la durata della cronologia selezionata.
  6. A seconda della destinazione dell'indicatore, calcolare i valori di valuta per ciascuno degli indici selezionati:
    • Indice di forza relativa (indice di forza relativa, RSI);
    • Convergenza/Divergenza Medie Mobili (Media Mobile Convergenza/Divergenza, MACD);
    • Oscillatore Stocastico (Stochastic Oscillator);
    • In futuro, l'elenco potrebbe essere arricchito.

Per questo avremo bisogno di:

31 indicatori buffer:

  • 0-7 inclusi - buffer per il rendering delle righe finali;
  • 8-14 inclusi - buffer delle principali coppie di valute, che contengono USD;
  • 15-22 compreso - buffer di indici valutari;
  • 23-30 inclusi - buffer di dati stocastici intermedi di tipo close/close senza smoothing.

Per selezionare la destinazione di un indicatore, creeremo un tipo enumerato enum :

enum Indicator_Type
  {
   Use_RSI_on_indexes             = 1, // RSI of the index  
   Use_MACD_on_indexes            = 2, // MACD from the index  
   Use_Stochastic_Main_on_indexes = 3  // Stochastic on the index
  };
Successivamente, utilizzando il comando di input, nella finestra delle preferenze dell'indicatore, deriveremo per le selezioni dell'utente da questo elenco 
input Indicator_Type ind_type=Use_RSI_on_indexes;  // type of the indicator from the index

È possibile creare un modo più intuitivo per visualizzare i nomi dei parametri di input nella scheda "Inputs". Per fare ciò utilizziamo allo scopo il commento urgente, che deve essere posto dopo la descrizione del parametro di input, nella stessa riga. Pertanto, i parametri di input possono essere confrontati con nomi più facilmente comprensibili per l'utente.

Le stesse regole si applicano per i comandi di lista enum. Cioèse il nome mnemonico è associato a un commento, come mostrato nel nostro esempio, al posto del nome mnemonico, verrà visualizzato il contenuto di questo commento. Ciò fornisce una maggiore flessibilità per la scrittura di programmi con chiare descrizioni di parametri di input.

Gli sviluppatori hanno cercato di fornire all'utente finale mezzi convenienti per lavorare con il programma MQL5, assicurandosi che vedesse nomi comprensibili dei parametri invece di ciò che è scritto nel codice. Ulteriori informazioni possono essere trovate qui.

 Figura 1. Selezione del tipo di indicatore

Figura 1. Selezione del tipo di indicatore

Forniamo all'utente una scelta delle valute necessarie per il rendering dell'indicatore e del suo colore:

input bool USD=true;
input bool EUR=true;
input bool GBP=true;
input bool JPY=true;
input bool CHF=true;
input bool CAD=true;
input bool AUD=true;
input bool NZD=true;

input color Color_USD = Green;            // USD line color
input color Color_EUR = DarkBlue;         // EUR line color
input color Color_GBP = Red;             // GBP line color
input color Color_CHF = Chocolate;        // CHF line color
input color Color_JPY = Maroon;           // JPY line color
input color Color_AUD = DarkOrange;       // AUD line color
input color Color_CAD = Purple;          // CAD line color
input color Color_NZD = Teal;            // NZD line color

Figura 2. Selezione del colore delle linee dell'indicatore

Figura 2. Selezione del colore delle linee dell'indicatore

Alcuni altri parametri configurabili:

input string rem000        =  ""; // depending on the type of the indicator
input string rem0000       =  ""; // requires a value :
input int rsi_period       =   9; // period RSI
input int MACD_fast        =   5; // period MACD_fast
input int MACD_slow        =  34; // period MACD_slow
input int stoch_period_k   =   8; // period Stochastic %K
input int stoch_period_sma =   5; // period of smoothing for Stochastics %K
input int shiftbars        = 500; // number of bars for calculating the indicator

Figura 3. Parametri dell'indicatore

Figura 3. Parametri dell'indicatore

Un limite di 500 barre per il calcolo dell'indicatore è artificiale, ma è sufficiente per dimostrare il concetto di calcolo. Ma dobbiamo ricordare che ogni buffer dell'indicatore richiede memoria e un display di dimensioni variabili molto grandi (in milioni di barre) può far sì che il computer non disponga di memoria sufficiente.

Buffer dell’Indicatore

double  EURUSD[], // quotes
        GBPUSD[],
        USDCHF[],
        USDJPY[],
        AUDUSD[],
        USDCAD[],
        NZDUSD[];   
               
double    USDx[], // indexes
          EURx[],
          GBPx[],
          JPYx[],
          CHFx[],
          CADx[],
          AUDx[],
          NZDx[];
                         
double USDplot[], // results of currency lines
       EURplot[],
       GBPplot[],
       JPYplot[],
       CHFplot[],
       CADplot[],
       AUDplot[],
       NZDplot[]; 

double USDStoch[], // buffers of intermediate data schotastics by the close/close type without smoothing
       EURStoch[],
       GBPStoch[],
       JPYStoch[],
       CHFStoch[],
       CADStoch[],
       AUDStoch[],
       NZDStoch[];
Avremo anche bisogno di alcune variabili globali (a livello di indicatore):
int              i,ii;
int           y_pos=0; // Y coordinate variable for the informatory objects  
datetime   arrTime[7]; // Array with the last known time of a zero valued bar (needed for synchronization)  
int        bars_tf[7]; // To check the number of available bars in different currency pairs  
int        countVal=0; // Number of executable Rates  
int           index=0;
datetime  tmp_time[1]; // Intermediate array for the time of the bar 

E ora arriviamo a una funzionalità piuttosto lunga OnInit, utilizzandola distribuiremo i buffer degli indicatori in base ai loro scopi.

Poiché i calcoli iniziali passano attraverso l'indice del dollaro, allora per USD stabiliamo semplicemente la possibilità di disabilitare il rendering dei buffer dell'indicatore di valuta.

Sembra così:

if(USD)
  {
   countVal++;
   SetIndexBuffer(0,USDplot,INDICATOR_DATA);               // array for rendering
   PlotIndexSetString(0,PLOT_LABEL,"USDplot");              // name of the indicator line (when selected with a mouse)
   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,shiftbars);       // from which we begin rendering
   PlotIndexSetInteger(0,PLOT_DRAW_TYPE,DRAW_LINE);         // drawing style (line)
   PlotIndexSetInteger(0,PLOT_LINE_COLOR,Color_USD);       // color of line rendering
   if(StringFind(Symbol(),"USD",0)!=-1)
     {PlotIndexSetInteger(0,PLOT_LINE_WIDTH,wid_main);}    // if the symbol name contains USD 
                                                       // then draw a line of appropriate width 
   else
     {PlotIndexSetInteger(0,PLOT_LINE_STYLE,style_slave);}
   ArraySetAsSeries(USDplot,true);                       // indexation of array as a timeseries   
   ArrayInitialize(USDplot,EMPTY_VALUE);                  // zero values 
   f_draw("USD",Color_USD);                            // rendering in the indicator information window 
  }
SetIndexBuffer(15,USDx,INDICATOR_CALCULATIONS);            // array of dollar index for calculations
                                                      // (is not displayed in the indicator as a line) 
ArraySetAsSeries(USDx,true);                            // indexation of an array as a time series
ArrayInitialize(USDx,EMPTY_VALUE);                       // zero values

if(ind_type==Use_Stochastic_Main_on_indexes)
  {
   SetIndexBuffer(23,USDstoch,INDICATOR_CALCULATIONS);     // if the destination of the indicator as a Use_Stochastic_Main_on_indexes,
                                                           // then this intermediate array is needed
   ArraySetAsSeries(USDstoch,true);                        // indexation of array as a time series
   ArrayInitialize(USDstoch,EMPTY_VALUE);                  // zero values
  }
Per la valuta EUR il codice della funzione OnInit è simile a questo:
if(USD)
  {
   countVal++;
   SetIndexBuffer(0,USDplot,INDICATOR_DATA);              // array for rendering
   PlotIndexSetString(0,PLOT_LABEL,"USDplot");             // name of the indicator line (when selected with a mouse)
   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,shiftbars);       // from which we begin rendering
   PlotIndexSetInteger(0,PLOT_DRAW_TYPE,DRAW_LINE);         // drawing style (line)
   PlotIndexSetInteger(0,PLOT_LINE_COLOR,Color_USD);       // color of line rendering
   if(StringFind(Symbol(),"USD",0)!=-1)
     {PlotIndexSetInteger(0,PLOT_LINE_WIDTH,wid_main);}    // if the symbol name contains USD 
                                                       // then draw a line of appropriate width 
   else
     {PlotIndexSetInteger(0,PLOT_LINE_STYLE,style_slave);}
   ArraySetAsSeries(USDplot,true);                       // indexation of array as a timeseries
   ArrayInitialize(USDplot,EMPTY_VALUE);                  // zero values 
   f_draw("USD",Color_USD);                             // rendering in the indicator information window 
  }
SetIndexBuffer(15,USDx,INDICATOR_CALCULATIONS);             // array of dollar index for calculations
                                                       // (is not displayed in the indicator as a line) 
ArraySetAsSeries(USDx,true);                             // indexation of an array as a time series
ArrayInitialize(USDx,EMPTY_VALUE);                        // zero values

if(ind_type==Use_Stochastic_Main_on_indexes)
  {
   SetIndexBuffer(23,USDstoch,INDICATOR_CALCULATIONS);      // if the destination of the indicator as a Use_Stochastic_Main_on_indexes,
                                                       // then this intermediate array is needed
   ArraySetAsSeries(USDstoch,true);                      // indexation of array as a time series
   ArrayInitialize(USDstoch,EMPTY_VALUE);                 // zero values
  }

if(EUR)
  {
   countVal++;
   SetIndexBuffer(1,EURplot,INDICATOR_DATA);              // array for rendering
   PlotIndexSetString(1,PLOT_LABEL,"EURplot");             // name of the indicator line (when pointed to with a mouse)
   PlotIndexSetInteger(1,PLOT_DRAW_BEGIN,shiftbars);       // which we begin rendering from
   PlotIndexSetInteger(1,PLOT_DRAW_TYPE,DRAW_LINE);         // drawing style (lines)
   PlotIndexSetInteger(1,PLOT_LINE_COLOR,Color_EUR);       // the color of rendering lines
   if(StringFind(Symbol(),"EUR",0)!=-1)
     {PlotIndexSetInteger(1,PLOT_LINE_WIDTH,wid_main);}    // if the symbol name contains EUR
                                                       // then we draw a line of the appropriate width 
   else
     {PlotIndexSetInteger(1,PLOT_LINE_STYLE,style_slave);}  // if the symbol name does NOT contain EUR,
                                                       // then we draw a line of an appropriate style (on the crosses)
   ArraySetAsSeries(EURplot,true);                       // indexation of the array as a time series
   ArrayInitialize(EURplot,EMPTY_VALUE);                  // zero values
   SetIndexBuffer(8,EURUSD,INDICATOR_CALCULATIONS);        // data of Close currency pair EURUSD
   ArraySetAsSeries(EURUSD,true);                        // indexation of the array as a time series
   ArrayInitialize(EURUSD,EMPTY_VALUE);                   // zero values
   SetIndexBuffer(16,EURx,INDICATOR_CALCULATIONS);         // array of the EURO index for calculations
                                                      // (not displayed on the indicator as a line) 
   ArraySetAsSeries(EURx,true);
   ArrayInitialize(EURx,EMPTY_VALUE);
   if(ind_type==Use_Stochastic_Main_on_indexes)
     {
      SetIndexBuffer(24,EURstoch,INDICATOR_CALCULATIONS);   // if the indicator destination as a Use_Stochastic_Main_on_indexes,
                                                       // then this intermediate array is needed
      ArraySetAsSeries(EURstoch,true);                   // indexation of the array as a time series
      ArrayInitialize(EURstoch,EMPTY_VALUE);              // zero values
     }
   f_draw("EUR",Color_EUR);                            // rendering in the indicator information window
  }
Per analogia con l'EUR, il codice avrà un aspetto simile per le valute, come GBP, JPY, CHF, CAD, AUD e NZD, spostando gli indici dei buffer degli indicatori. Il codice per queste valute può essere trovato nel file allegato dell'indicatore.

Questo completa la descrizione dell'inizializzazione dell'indicatore.

Successivamente, avremo bisogno di alcune funzionalità personalizzate dell'utente:

  • Il calcolo dell'RSI sul buffer dell'utente
  • Calcolo MACD
  • Calcolo della SMA sul buffer utente
  • Calcolo della chiusura/chiusura stocastica senza livellamento
  • Oggetti di rendering (informazioni)
  • Commento nell'angolo in basso a destra dell'indicatore (indicatore di stato)
  • Inizializzazione delle coppie di valute TF interessate

Breve descrizione di ciascuno di questi:

  • Il calcolo dell'RSI sul buffer dell'utente

Parametri di Input:

double f_RSI(double &buf_in[], int period,int shift),

dove buf_in[] - tipo di array double (come le timeserie), periodo - periodo dell'indicatore RSI, shift - per quale barra dell'indice calcoliamo l'indicatore. Restituisce un valore di tipo double.

  • Calcolo MACD

Parametri di Input:

double f_MACD(double &buf_in[], int period_fast,int period_slow,int shift),

dove buf_in[] - array di tipo double (come le serie temporali), period_fast - period fast МА, period_slow - period slow МА, shift - per quale barra dell'indice calcoliamo l'indicatore. Restituisce un valore di tipo double.

  • Calcolo del SMA

Parametri di Input:

double SimpleMA(const int position,const int period,const double &price[]),

dove posizione - per quale barra dell'indice calcoliamo l'indicatore. periodo - periodo dell'indicatore SMA, price[] - array di tempo doppio (come le serie temporali). Restituisce un valore di tipo double.

  • Calcolo della chiusura/chiusura Stocastica senza smoothing

Parametri di Input:

double f_Stoch(double &price[], int period_k, int shift),

dove price[] - array di tipo double (come le serie temporali), period_fast - periodo %K linea dell'indicatore, shift - per quale barra dell'indice calcoliamo l'indicatore. Restituisce un valore di tipo double.

  • Rendering di oggetti

Parametri di Input:

int f_draw(string name, color _color)

dove nome - nome oggetto, _color - colore oggetto. La funzione è a scopo informativo. A partire dall'angolo superiore destro della finestra di visualizzazione e più in basso, questa funzione visualizza i nomi delle valute interessate. Il testo della valuta è dello stesso colore della linea dell'indicatore, relativa a questa valuta.

  • I commenti sono nell'angolo in basso a destra dell'indicatore

Parametri di Input:

int f_comment(string text)

testo - Il testo che deve essere posizionato nell'angolo in basso a destra dell'indicatore. Una sorta di barra di stato del lavoro dell'indicatore.

Infine, la conclusione e una delle funzioni più importanti:

  • Inizializzazione delle coppie di valute TF interessate

Nessun parametro di Input

In MetaTrader 5 la cronologia è memorizzata sotto forma di dati minuti di TF per ogni strumento. Pertanto, prima di avviare il programma, vengono costruiti tutti i grafici (interessati) necessari, basati sugli stessi dati dei minuti TF, una volta aperto il terminale. La costruzione avviene anche quando viene commutata la TF di traffico corrente o durante un tentativo di accesso al grafico della TF tramite il codice di programma MQL5.

Perciò:

  • Durante la prima volta che il terminale viene lanciato, è necessario del tempo per la costruzione (forse anche dello sfondo, cioè l'utente non li vede) dei necessari TF delle coppie di valute utilizzate.
  • sincronizzare la barra zero per tutte le valute interessate, al fine di visualizzare con precisione l'indicatore. In altre parole, se su un grafico c'è un nuovo tick in entrata, che apre una nuova barra (es. barra delle ore), bisognerà attendere l'entrata dei tick per le altre coppie di valute, che a loro volta , aprono una nuova barra (nuova ora). Solo allora puoi procedere al calcolo di un indicatore per la nuova barra.

La prima parte di questa attività viene implementata utilizzando la funzione Bars incorporata, che restituisce il numero di barre nella cronologia in base al periodo corrispondente al simbolo. È sufficiente utilizzare la versione di questa funzione che viene mostrata di seguito.

int  Bars(
   string          symbol_name,   // symbol name
   ENUM_TIMEFRAMES   timeframe    // period
   );

Nell’?????? annunciato appositamente per questo array, raccogliamo il numero di barre disponibili per tutte le coppie di valute interessate. Controlliamo ogni valore per la quantità minima di cronologia necessaria (la variabile "numero di barre per il calcolo dell'indicatore" nei parametri dell'indicatore). Se il numero di barre disponibili nella storia di qualsiasi strumento è inferiore al valore di questa variabile, allora consideriamo che la costruzione non è andata a buon fine e riesaminiamo il numero di dati disponibili. Una volta che c'è più cronologia disponibile, per tutte le coppie di valute, rispetto a quella richiesta dall'utente, allora possiamo considerare che questa parte dell'inizializzazione è stata completata con successo.

La seconda parte dell'attività di sincronizzazione viene implementata utilizzando la funzione CopyTime.

 In un array creato appositamente per questo scopo, copiamo l'apertura della barra zero di ogni strumento interessato. Se tutti gli elementi di questo array sono uguali e non sono pari a 0, consideriamo che la nostra barra zero è sincronizzata e iniziamo il calcolo. Per capire in maniera dettagliata come questo viene implementato, si veda il codice dell'indicatore allegato.

Questo conclude la descrizione delle funzioni aggiuntive e passiamo all'implementazione della funzione OnCalculate. Poiché si tratta di un indicatore multivaluta, avremo bisogno della seconda versione della richiesta di questa funzione.

int OnCalculate(const int     rates_total, // size of incoming time series
                const int prev_calculated, // processing of bars on the previous request
                const datetime&    time[], // Time
                const double&      open[], // Open
                const double&      high[], // High
                const double&       low[], // Low
                const double&     close[], // Close
                const long& tick_volume[], // Tick Volume
                const long&      volume[], // Real Volume
                const int&       spread[]  // Spread
   );

Determinare la quantità di barre necessarie per il calcolo:

   int limit=shiftbars;

   if(prev_calculated>0)
     {limit=1;}
   else
     {limit=shiftbars;}

Sincronizza i grafici delle coppie di valute:

   init_tf();

Successivamente, utilizzando la funzione CopyClose, copiamo i dati Close di tutte le coppie di valute necessarie, nei buffer degli indicatori, registrati appositamente per questo. (Per ulteriori informazioni sull'accesso ai dati di altri TF dello strumento corrente e/o di altri strumenti, è possibile trovare nella Guida)

Se, per qualsiasi motivo, la funzione non ha copiato i dati e ha restituito una risposta -1, viene visualizzato un messaggio di errore di coppia di valute nel commento e si attende la ricezione di un nuovo tick per lo strumento corrente.

   if (EUR){copied=CopyClose("EURUSD",PERIOD_CURRENT,0,shiftbars,EURUSD); if (copied==-1){f_comment("Wait...EURUSD");return(0);}}
   if (GBP){copied=CopyClose("GBPUSD",PERIOD_CURRENT,0,shiftbars,GBPUSD); if (copied==-1){f_comment("Wait...GBPUSD");return(0);}}
   if (CHF){copied=CopyClose("USDCHF",PERIOD_CURRENT,0,shiftbars,USDCHF); if (copied==-1){f_comment("Wait...USDCHF");return(0);}}
   if (JPY){copied=CopyClose("USDJPY",PERIOD_CURRENT,0,shiftbars,USDJPY); if (copied==-1){f_comment("Wait...USDJPY");return(0);}}
   if (AUD){copied=CopyClose("AUDUSD",PERIOD_CURRENT,0,shiftbars,AUDUSD); if (copied==-1){f_comment("Wait...AUDUSD");return(0);}}
   if (CAD){copied=CopyClose("USDCAD",PERIOD_CURRENT,0,shiftbars,USDCAD); if (copied==-1){f_comment("Wait...USDCAD");return(0);}}
   if (NZD){copied=CopyClose("NZDUSD",PERIOD_CURRENT,0,shiftbars,NZDUSD); if (copied==-1){f_comment("Wait...NZDUSD");return(0);}}  

Successivamente nel ciclo (da 0 a limite) produciamo:

  • Il calcolo dell'indice del dollaro;
  • Calcolo di indici di altre valute sulla base di Close e dell'indice del dollaro per la barra corrente;
for (i=limit-1;i>=0;i--)
   {
      //calculation of USD index
      USDx[i]=1.0;
      if (EUR){USDx[i]+=EURUSD[i];}         
      if (GBP){USDx[i]+=GBPUSD[i];}
      if (CHF){USDx[i]+=1/USDCHF[i];}
      if (JPY){USDx[i]+=1/USDJPY[i];}
      if (CAD){USDx[i]+=1/USDCAD[i];}
      if (AUD){USDx[i]+=AUDUSD[i];}
      if (NZD){USDx[i]+=NZDUSD[i];}
      USDx[i]=1/USDx[i];
      //calculation of other currency values
      if (EUR){EURx[i]=EURUSD[i]*USDx[i];}
      if (GBP){GBPx[i]=GBPUSD[i]*USDx[i];}
      if (CHF){CHFx[i]=USDx[i]/USDCHF[i];}
      if (JPY){JPYx[i]=USDx[i]/USDJPY[i];}
      if (CAD){CADx[i]=USDx[i]/USDCAD[i];}
      if (AUD){AUDx[i]=AUDUSD[i]*USDx[i];}
      if (NZD){NZDx[i]=NZDUSD[i]*USDx[i];}
   }

I dati vengono inseriti negli appositi buffer indicatori. Verificare quale tipo di indicatore è stato selezionato dall'utente durante l'inizializzazione e, su questa base, produrre calcoli pertinenti.

Se è stato dimostrato il desiderio di guardare l'RSI degli indici, eseguire il codice seguente:

if (ind_type==Use_RSI_on_indexes)
   {
      if (limit>1){ii=limit - rsi_period - 1;}
      else{ii=limit - 1;}
      for(i=ii;i>=0;i--)
         {
            if (USD){USDplot[i]=f_RSI(USDx,rsi_period,i);}
            if (EUR){EURplot[i]=f_RSI(EURx,rsi_period,i);}
            if (GBP){GBPplot[i]=f_RSI(GBPx,rsi_period,i);}
            if (CHF){CHFplot[i]=f_RSI(CHFx,rsi_period,i);}
            if (JPY){JPYplot[i]=f_RSI(JPYx,rsi_period,i);}
            if (CAD){CADplot[i]=f_RSI(CADx,rsi_period,i);}
            if (AUD){AUDplot[i]=f_RSI(AUDx,rsi_period,i);}
            if (NZD){NZDplot[i]=f_RSI(NZDx,rsi_period,i);}                  
         }
   }  

Se volessimo vedere il MACD dagli indici, allora andiamo qui (ma finora è implementato solo sulla base di SimpleMA e verrà implementato sulla base di EMA in seguito):

if (ind_type==Use_MACD_on_indexes)
   {
      if (limit>1){ii=limit - MACD_slow - 1;}
      else{ii=limit - 1;}
      for(i=ii;i>=0;i--)
         {
           if (USD){USDplot[i]=f_MACD(USDx,MACD_fast,MACD_slow,i);}
           if (EUR){EURplot[i]=f_MACD(EURx,MACD_fast,MACD_slow,i);}
           if (GBP){GBPplot[i]=f_MACD(GBPx,MACD_fast,MACD_slow,i);}
           if (CHF){CHFplot[i]=f_MACD(CHFx,MACD_fast,MACD_slow,i);}
           if (JPY){JPYplot[i]=f_MACD(JPYx,MACD_fast,MACD_slow,i);}
           if (CAD){CADplot[i]=f_MACD(CADx,MACD_fast,MACD_slow,i);}
           if (AUD){AUDplot[i]=f_MACD(AUDx,MACD_fast,MACD_slow,i);}
           if (NZD){NZDplot[i]=f_MACD(NZDx,MACD_fast,MACD_slow,i);}                  
         }
   } 

Se Stochastis, devi prima calcolare la linea% K, quindi smussarla con il metodo SimpleMA. La linea smussata finale deve essere visualizzata sul grafico.

if (ind_type==Use_Stochastic_Main_on_indexes)
   {
      if (limit>1){ii=limit - stoch_period_k - 1;}
      else{ii=limit - 1;}
      for(i=ii;i>=0;i--)
         {
           if (USD){USDstoch[i]=f_Stoch(USDx,rsi_period,i);}
           if (EUR){EURstoch[i]=f_stoch(EURx,stoch_period_k,i);}
           if (GBP){GBPstoch[i]=f_stoch(GBPx,stoch_period_k,i);}
           if (CHF){CHFstoch[i]=f_stoch(CHFx,stoch_period_k,i);}
           if (JPY){JPYstoch[i]=f_stoch(JPYx,stoch_period_k,i);}
           if (CAD){CADstoch[i]=f_stoch(CADx,stoch_period_k,i);}
           if (AUD){AUDstoch[i]=f_stoch(AUDx,stoch_period_k,i);}
           if (NZD){NZDstoch[i]=f_stoch(NZDx,stoch_period_k,i);}                  
         }
      if (limit>1){ii=limit - stoch_period_sma - 1;}
      else{ii=limit - 1;}
      for(i=ii;i>=0;i--)
         {
            if (USD){USDplot[i]=SimpleMA(i,stoch_period_sma,USDstoch);}
            if (EUR){EURplot[i]=SimpleMA(i,stoch_period_sma,EURstoch);}
            if (GBP){GBPplot[i]=SimpleMA(i,stoch_period_sma,GBPstoch);}
            if (CHF){CHFplot[i]=SimpleMA(i,stoch_period_sma,CHFstoch);}
            if (JPY){JPYplot[i]=SimpleMA(i,stoch_period_sma,JPYstoch);}
            if (CAD){CADplot[i]=SimpleMA(i,stoch_period_sma,CADstoch);}
            if (AUD){AUDplot[i]=SimpleMA(i,stoch_period_sma,AUDstoch);}
            if (NZD){NZDplot[i]=SimpleMA(i,stoch_period_sma,NZDstoch);}                  
          }                     
   }       

Questo completa il calcolo degli indicatori. Le figure 4-6 mostrano alcune immagini dei diversi tipi di indicatori.

Figura 4. RSI per indici

Figura 4. RSI dagli indici

Figura 5. MACD per gli indici delle valute

Figura 5. MACD dagli indici delle valute

Figura 6. Stochastis dagli indici delle valute

Figura 6. Stochastis dagli indici delle valute

Conclusione

Durante l'implementazione dell'indicatore MultiCurrencyIndex, ho utilizzato un numero illimitato di buffer di indicatori in MQL5, il che ha notevolmente semplificato il codice. Questo articolo è un esempio di tale approccio. Per dati affidabili di un indicatore, ho dimostrato un algoritmo di sincronizzazione di diversi strumenti rispetto alla barra zero. Ho anche dimostrato uno dei possibili algoritmi di accesso ai dati di altri strumenti, relativo al simbolo a cui l'indicatore è allegato.

Poiché lo scopo dell'articolo era dimostrare la possibilità di lavorare con un'enorme quantità di buffer di indicatori; la suddetta funzione di calcolo degli indicatori da parte degli array dei dati degli utenti, non era il modo ottimale per evitare di sovraccaricare il lettore. Ma era sufficiente per eseguire i calcoli necessari.

Ci sono molti pro e contro dell'analisi cluster del mercato Forex. I sistemi di trading, basati su questo approccio, sono disponibili gratuitamente e se ne discute su vari forum, incluso su MQL4.Community. Pertanto, i principi di negoziazione di questo indicatore non sono considerati in questo articolo.

Tradotto dal russo da MetaQuotes Ltd.
Articolo originale: https://www.mql5.com/ru/articles/83

File allegati |
Un Gestore degli Ordini Virtuale per tenere traccia degli ordini all'interno dell'ambiente MetaTrader 5 incentrato sulla posizione Un Gestore degli Ordini Virtuale per tenere traccia degli ordini all'interno dell'ambiente MetaTrader 5 incentrato sulla posizione
Questa libreria di classi può essere aggiunta a un MetaTrader 5 Expert Advisor per consentirne la scrittura con un approccio incentrato sull'ordine sostanzialmente simile a MetaTrader 4, rispetto all'approccio basato sulla posizione di MetaTrader 5. Lo fa tenendo traccia degli ordini virtuali sul client terminal MetaTrader 5, mantenendo un broker protettivo per ogni posizione per la protezione dai disastri.
Migrazione da MQL4 a MQL5 Migrazione da MQL4 a MQL5
Questo articolo è una guida rapida alle funzioni del linguaggio MQL4, ti aiuterà a migrare i tuoi programmi da MQL4 a MQL5. Per ogni funzione MQL4 (ad eccezione delle funzioni di trading) vengono presentate la descrizione e l'implementazione MQL5, che consente di ridurre significativamente il tempo di conversione. Per comodità, le funzioni MQL4 sono suddivise in gruppi, in modo simile a MQL4 Reference.
Un Esempio di un Sistema di Trading Basato su un Indicatore Heiken-Ashi Un Esempio di un Sistema di Trading Basato su un Indicatore Heiken-Ashi
In questo articolo esaminiamo la questione dell'utilizzo di un indicatore Heiken-Ashi nel trading. Sulla base di questo indicatore, viene considerato un semplice sistema di trading e viene scritto un Expert Advisor MQL5. Le operazioni di trading sono implementate sulla base delle classi della libreria di classi Standard. I risultati dello Strategy Tester di trading recensito, si basano sulla cronologia e sono ottenuti utilizzando lo Strategy Tester MetaTrader 5 integrato, sono forniti nell'articolo.
MetaTrader 5: Pubblicazione di previsioni di trading e dichiarazioni di trading in tempo reale via e-mail su blog, social network e siti web dedicati MetaTrader 5: Pubblicazione di previsioni di trading e dichiarazioni di trading in tempo reale via e-mail su blog, social network e siti web dedicati
Questo articolo mira a presentare soluzioni pronte per la pubblicazione di previsioni utilizzando MetaTrader 5. Copre una vasta gamma di idee: dall'utilizzo di siti web dedicati per la pubblicazione di dichiarazioni MetaTrader, attraverso la creazione del proprio sito Web senza praticamente alcuna esperienza di programmazione web necessaria e infine l'integrazione con un servizio di microblogging di social network che consente a molti lettori di aderire e seguire le previsioni. Tutte le soluzioni presentate qui sono gratuite al 100% e possono essere configurate da chiunque abbia una conoscenza di base dei servizi di posta elettronica e ftp. Non ci sono ostacoli all'utilizzo delle stesse tecniche per l'hosting professionale e per i servizi di previsione del trading commerciale.