Creazione di un Indicatore Multivaluta, Utilizzando un Numero di Buffer di Indicatori Intermedi
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.
,
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.
- Sincronizzare i grafici delle coppie di valute interessate di questo timeframe.
- 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.
- Sulla base dei dati ottenuti al punto (2), calcola per la barra correntel'indice del dollaro.
- Conoscendo l'indice del dollaro per la barra corrente, calcola gli indici di valuta rimanenti.
- Eseguire i calcoli dei dati (voci 3 e 4) il numero di volte richiesto per la durata della cronologia selezionata.
- 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
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
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
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 dagli indici
Figura 5. MACD 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
- 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