Estensione della MQL5 Standard Library e riutilizzo del codice
Introduzione
MQL5 Standard Library è un framework orientato agli oggetti composto da un insieme di classi pronte all'uso che semplificano la vita allo sviluppatore. Tuttavia, non implementa tutte le esigenze di tutti gli sviluppatori di tutto il mondo, quindi se ritieni di aver bisogno di altre personalizzazioni, puoi fare un ulteriore passo avanti ed espanderti. Questo articolo ti guida attraverso l'integrazione dell'indicatore tecnico Zig-Zag di MetaQuotes nella libreria standard. Ci ispireremo alla filosofia di design di MetaQuotes per raggiungere il nostro obiettivo.
In poche parole, con API MQL5 potrai riutilizzare il codice. In più esso offre affidabilità, flessibilità e facilità di manutenzione. Questo è cosa dice la teoria, ma al di là di tutto questo, se hai intenzione di continuare ad avanzare in MQL5 e sviluppare cose più sofisticate, come Expert Advisor multi-valuta, prima dovresti essere in grado di codificare in modalità libreria standard in modo che le tue app abbiano possano riuscire bene.
Man mano che i tuoi EA e indicatori diventano sempre più complessi, questo è sempre più necessario per padroneggiare i concetti coinvolti nello sviluppo di un framework. Come esempio di applicazione nel mondo reale, è il mio bisogno personale di sviluppare un EA complesso e multi-valuta che detta la necessità di rafforzare la base del mio progetto da zero.
Figura 1. I poliedri regolari sono oggetti perfetti. Descrivono bene l'approccio di creazione di app su concetti solidi
1. ZigZag Download
Iniziamo scaricando, l'indicatore ZigZag di MetaQuotes, disponibile in Code Base, dal nostro terminale MetaTrader 5. Questo creerà i file Indicators\zigzag.mq5 e Indicators\zigzag.ex5.Figura 2. Iniziamo a scaricare ZigZag di MetaQuotes dal nostro terminale MetaTrader 5
Allego qui quelle righe di Indicators\zigzag.mq5 contenenti i parametri di input dell'indicatore, le variabili globali e il gestore OnInit(). Ho messo solo questa parte perché l'intero file ha 298 righe di codice. Questo è semplicemente per comodità e la comprensione del quadro più ampio di cui stiamo parlando di seguito.
//+------------------------------------------------------------------+ //| ZigZag.mq5 | //| Copyright 2009, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "2009, MetaQuotes Software Corp." #property link "https://www.mql5.com" #property version "1.00" #property indicator_chart_window #property indicator_buffers 3 #property indicator_plots 1 //---- plot Zigzag #property indicator_label1 "Zigzag" #property indicator_type1 DRAW_SECTION #property indicator_color1 Red #property indicator_style1 STYLE_SOLID #property indicator_width1 1 //--- input parameters input int ExtDepth=12; input int ExtDeviation=5; input int ExtBackstep=3; //--- indicator buffers double ZigzagBuffer[]; // main buffer double HighMapBuffer[]; // highs double LowMapBuffer[]; // lows int level=3; // recounting depth double deviation; // deviation in points //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- indicator buffers mapping SetIndexBuffer(0,ZigzagBuffer,INDICATOR_DATA); SetIndexBuffer(1,HighMapBuffer,INDICATOR_CALCULATIONS); SetIndexBuffer(2,LowMapBuffer,INDICATOR_CALCULATIONS); //--- set short name and digits PlotIndexSetString(0,PLOT_LABEL,"ZigZag("+(string)ExtDepth+","+(string)ExtDeviation+","+(string)ExtBackstep+")"); IndicatorSetInteger(INDICATOR_DIGITS,_Digits); //--- set empty value PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0); //--- to use in cycle deviation=ExtDeviation*_Point; //--- return(INIT_SUCCEEDED); }
2. Panoramica rapida dall'alto verso il basso
Prendiamo ora un approccio top-down per pensare al nostro nuovo indicatore ZigZag orientato agli oggetti che vogliamo integrare nella MQL5 Standard Library. Ciò significa che prima dobbiamo guardare l'intero sistema e poi analizzare le parti più piccole di esso. Quindi, perché non codiniamo un paio di EA fittizi per vedere il quadro più ampio? Scriviamo un Expert Advisor in stile procedurale insieme alla sua versione orientata agli oggetti.
2.1. ZigZag fuori dagli schemi
Gli sviluppatori MQL5 intermedi probabilmente utilizzerebbero l'indicatore ZigZag nei loro EA in questo modo:
//+----------------------------------------------------------------------+ //| ExpertOriginalZigZag.mq5 | //| Copyright © 2013, Laplacianlab - Jordi Bassagañas | //+----------------------------------------------------------------------+ //--- EA properties #property copyright "Copyright © 2013, Laplacianlab - Jordi Bassagañas" #property link "https://www.mql5.com/it/articles" #property version "1.00" #property description "This dummy Expert Advisor is just for showing how to use the original MetaQuotes' ZigZag indicator." //--- EA inputs input ENUM_TIMEFRAMES EAPeriod=PERIOD_H1; input string CurrencyPair="EURUSD"; //--- global variables int zigZagHandle; double zigZagBuffer[]; double zigZagHigh[]; double zigZagLow[]; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { zigZagHandle=iCustom(CurrencyPair,EAPeriod,"zigzag",12,5,3); ArraySetAsSeries(zigZagBuffer,true); ArraySetAsSeries(zigZagHigh,true); ArraySetAsSeries(zigZagLow,true); return(0); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { IndicatorRelease(zigZagHandle); ArrayFree(zigZagBuffer); ArrayFree(zigZagHigh); ArrayFree(zigZagLow); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- refresh data if(CopyBuffer(zigZagHandle,0,0,2,zigZagBuffer)<0) { Print("Can't copy ZigZag buffer 0!"); return; } if(CopyBuffer(zigZagHandle,1,0,2,zigZagHigh)<0) { Print("Can't copy ZigZag buffer 1!"); return; } if(CopyBuffer(zigZagHandle,2,0,2,zigZagLow)<0) { Print("Can't copy ZigZag buffer 2!"); return; } //--- print values if(zigZagBuffer[0]!=0) Print("zigZagBuffer[0]: ", zigZagBuffer[0]); if(zigZagHigh[0]!=0) Print("zigZagHigh[0]: ", zigZagHigh[0]); if(zigZagLow[0]!=0) Print("zigZagLow[0]: ", zigZagLow[0]); } //+------------------------------------------------------------------+
2.2. ZigZag integrato nella libreria standard
D'altra parte, gli sviluppatori MQL5 avanzati vorranno lavorare con l'indicatore ZigZag proprio come già fanno con gli indicatori della libreria standard, in questo modo:
//+----------------------------------------------------------------------+ //| ExpertOOZigZag.mq5 | //| Copyright © 2013, Laplacianlab - Jordi Bassagañas | //+----------------------------------------------------------------------+ #include <..\Include\Indicators\Custom\Trend.mqh> //--- EA properties #property copyright "Copyright © 2013, Laplacianlab - Jordi Bassagañas" #property link "https://www.mql5.com/it/articles" #property version "1.00" #property description "This dummy Expert Advisor is just for showing how to use the object-oriented version of MetaQuotes' ZigZag indicator." //--- EA inputs input ENUM_TIMEFRAMES EAPeriod=PERIOD_H1; input string CurrencyPair="EURUSD"; //--- global variables CiZigZag *ciZigZag; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { ciZigZag=new CiZigZag; ciZigZag.Create(CurrencyPair,EAPeriod,12,5,3); return(0); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { delete(ciZigZag); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- refresh data ciZigZag.Refresh(); //--- print values if(ciZigZag.ZigZag(0)!=0) Print("OO ZigZag buffer: ", ciZigZag.ZigZag(0)); if(ciZigZag.High(0)!=0) Print("OO ZigZag high: ", ciZigZag.High(0)); if(ciZigZag.Low(0)!=0) Print("OO ZigZag low: ",ciZigZag.Low(0)); } //+------------------------------------------------------------------+
2.3. Conclusione
La seconda soluzione è migliore perché è orientata agli oggetti. Una volta che le classi OO sono state sviluppate, è intuitivo osservare che è molto più facile interagire con la funzionalità orientata agli oggetti di Zig-Zag che lavorare con la sua controparte procedurale. Ricordiamo brevemente, tuttavia, i vantaggi di cui beneficiamo quando lavoriamo con una libreria orientata agli oggetti:
- OOP semplifica la modellazione dei problemi.
- OOP semplifica il riutilizzo del codice, che a sua volta avvantaggia costi, affidabilità, flessibilità e manutenzione.
Questo paradigma consente la creazione di ADT (Abstract Data Types). Un ADT è un'astrazione del concetto tradizionale di tipo di dati, che è presente in tutti i linguaggi di programmazione.
Figura 3. Icosaedro regolare. Costruire le nostre app su concetti solidi è una garanzia di qualità che fa sì che i nostri progetti persistano nel tempo
3. Integrazione del nostro nuovo OO ZigZag nella MQL5 Standard Library
Come ho detto nell'introduzione di questo articolo, ci stiamo ispirando allo stile orientato agli oggetti di MetaQuotes per costruire il nostro nuovo set di classi destinate al wrapping dello ZigZag scaricato in precedenza. Questo è facile, non ci resta che dare un'occhiata ai file all'interno di Include\Indicators e studiare e capire alcune delle idee che stanno dietro MQL5 Standard Library. Quando guardi cosa c'è dentro Trend.mqh di MetaQuotes ti renderai presto conto che è pieno di classi che rappresentano alcuni indicatori tecnici: ADX, bande di Bollinger, SAR, medie mobili, ecc. Tutte queste classi ereditano da CIndicator. Quindi implementiamo questo schema. A proposito, estendere il nuovo indicatore OO dalla classe CiCustom di MQL5 sarebbe stata un'altra alternativa per implementare questo esercizio.
Iniziamo creando la nuova cartella Include\Indicators\Custom e, subito dopo, il nuovo file Include\Indicators\Custom\Trend.mqh in modo da poter codificare lì i nostri indicatori tecnici, proprio come fa MetaQuotes nel suo Include\Indicators\Trend.mqh. Ecco il nostro file di estensione Include\Indicators\Custom\Trend.mqh già implementato. Discuterò di seguito alcuni aspetti tecnici necessari per codificarlo.
//+------------------------------------------------------------------+ //| Include\Indicators\Custom\Trend.mqh | //| Copyright 2013, Laplacianlab - Jordi Bassagañas | //| https://www.mql5.com/en/users/laplacianlab | //+------------------------------------------------------------------+ #include <..\Include\Indicators\Indicator.mqh> //+------------------------------------------------------------------+ //| Class CiZigZag. | //| Purpose: Class of the "ZigZag" indicator. | //| Derives from class CIndicator. | //+------------------------------------------------------------------+ class CiZigZag : public CIndicator { protected: int m_depth; int m_deviation; int m_backstep; public: CiZigZag(void); ~CiZigZag(void); //--- methods of access to protected data int Depth(void) const { return(m_depth); } int Deviation(void) const { return(m_deviation); } int Backstep(void) const { return(m_backstep); } //--- method of creation bool Create(const string symbol,const ENUM_TIMEFRAMES period, const int depth,const int deviation_create,const int backstep); //--- methods of access to indicator data double ZigZag(const int index) const; double High(const int index) const; double Low(const int index) const; //--- method of identifying virtual int Type(void) const { return(IND_CUSTOM); } protected: //--- methods of tuning virtual bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]); bool Initialize(const string symbol,const ENUM_TIMEFRAMES period, const int depth,const int deviation_init,const int backstep); }; //+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ CiZigZag::CiZigZag(void) : m_depth(-1), m_deviation(-1), m_backstep(-1) { } //+------------------------------------------------------------------+ //| Destructor | //+------------------------------------------------------------------+ CiZigZag::~CiZigZag(void) { } //+------------------------------------------------------------------+ //| Create indicator "Zig Zag" | //+------------------------------------------------------------------+ bool CiZigZag::Create(const string symbol,const ENUM_TIMEFRAMES period, const int depth,const int deviation_create,const int backstep) { //--- check history if(!SetSymbolPeriod(symbol,period)) return(false); //--- create m_handle=iCustom(symbol,period,"zigzag",depth,deviation_create,backstep); //--- check result if(m_handle==INVALID_HANDLE) return(false); //--- indicator successfully created if(!Initialize(symbol,period,depth,deviation_create,backstep)) { //--- initialization failed IndicatorRelease(m_handle); m_handle=INVALID_HANDLE; return(false); } //--- ok return(true); } //+------------------------------------------------------------------+ //| Initialize the indicator with universal parameters | //+------------------------------------------------------------------+ bool CiZigZag::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]) { return(Initialize(symbol,period,(int)params[0].integer_value,(int)params[1].integer_value,(int)params[2].integer_value)); } //+------------------------------------------------------------------+ //| Initialize indicator with the special parameters | //+------------------------------------------------------------------+ bool CiZigZag::Initialize(const string symbol,const ENUM_TIMEFRAMES period, const int depth,const int deviation_init,const int backstep) { if(CreateBuffers(symbol,period,3)) { //--- string of status of drawing m_name ="ZigZag"; m_status="("+symbol+","+PeriodDescription()+","+ IntegerToString(depth)+","+IntegerToString(deviation_init)+","+ IntegerToString(backstep)+") H="+IntegerToString(m_handle); //--- save settings m_depth=depth; m_deviation=deviation_init; m_backstep=backstep; //--- create buffers ((CIndicatorBuffer*)At(0)).Name("ZIGZAG"); ((CIndicatorBuffer*)At(1)).Name("HIGH"); ((CIndicatorBuffer*)At(2)).Name("LOW"); //--- ok return(true); } //--- error return(false); } //+------------------------------------------------------------------+ //| Access to ZigZag buffer of "Zig Zag" | //+------------------------------------------------------------------+ double CiZigZag::ZigZag(const int index) const { CIndicatorBuffer *buffer=At(0); //--- check if(buffer==NULL) return(EMPTY_VALUE); //--- return(buffer.At(index)); } //+------------------------------------------------------------------+ //| Access to High buffer of "Zig Zag" | //+------------------------------------------------------------------+ double CiZigZag::High(const int index) const { CIndicatorBuffer *buffer=At(1); //--- check if(buffer==NULL) return(EMPTY_VALUE); //--- return(buffer.At(index)); } //+------------------------------------------------------------------+ //| Access to Low buffer of "Zig Zag" | //+------------------------------------------------------------------+ double CiZigZag::Low(const int index) const { CIndicatorBuffer *buffer=At(2); //--- check if(buffer==NULL) return(EMPTY_VALUE); //--- return(buffer.At(index)); } //+------------------------------------------------------------------+
3.1. Incapsulamento orientato agli oggetti
L'incapsulamento OO è una buona pratica di programmazione, il che significa che i membri dei dati degli oggetti possono essere modificati solo dalle operazioni definite per essi. Tutte le classi definite in Trend.mqh di MetaQuotes implementano questa idea, quindi stiamo facendo lo stesso.
Da un lato, ci sono le proprietà protette specifiche di CiZigZag:
protected: int m_depth; int m_deviation; int m_backstep;
Successivamente, esiste l'interfaccia pubblica di CiZigZagper accedere dall'esterno ad un determinato oggetto di tipo CiZigZag alle proprietà protette sopra definite:
public: //--- methods of access to protected data int Depth(void) const { return(m_depth); } int Deviation(void) const { return(m_deviation); } int Backstep(void) const { return(m_backstep); }
Si tratta di una misura di sicurezza per l'isolamento degli oggetti. Questo incapsulamento protegge dalle modifiche arbitrarie eseguite da qualcuno o qualcosa a cui non è consentito accedere ai dati degli oggetti.
3.2. Accesso ai dati di ZigZag
Come si vede nella prima sezione di questo articolo, il file di codice sorgente denominato zigzag.mq5 crea tre buffer:
//--- indicator buffers mapping SetIndexBuffer(0,ZigzagBuffer,INDICATOR_DATA); SetIndexBuffer(1,HighMapBuffer,INDICATOR_CALCULATIONS); SetIndexBuffer(2,LowMapBuffer,INDICATOR_CALCULATIONS);
Attraverso l'incapsulamento orientato agli oggetti, i metodi di CiZigZag ZigZag(const int index), High(const int index) e Low(const int index) restituiscono i buffer degli indicatori che sono stati precedentemente creati nel metodo di inizializzazione. È importante notare che il wrapper orientato agli oggetti CIndicatorBuffer è definito nella classe Include\Indicators\Indicator.mqhdi MQL5. CIndicatorBuffer è il pezzo centrale di questi tre metodi. Siamo già immersi nell'API MQL5!
Come esempio qui, è il codice per accedere al buffer alto di CiZigZag:
//+------------------------------------------------------------------+ //| Access to High buffer of "Zig Zag" | //+------------------------------------------------------------------+ double CiZigZag::High(const int index) const { CIndicatorBuffer *buffer=At(1); //--- check if(buffer==NULL) return(EMPTY_VALUE); //--- return(buffer.At(index)); }
3.3. Polimorfismo, sovraccarico di metodi e funzioni virtuali
Nella sezione precedente abbiamo brevemente discusso il tema dell'incapsulamento che è una delle caratteristiche più importanti della programmazione orientata agli oggetti. Bene, le classi contenute in Include\Indicators\Indicator.mqh e il file Include\Indicators\Custom\Trend.mqh trattano altri due aspetti del paradigma OOP, il polimorfismo e il sovraccarico del metodo.
Il polimorfismo ha la capacità di accedere a una vasta gamma di metodi attraverso la stessa interfaccia. In questo modo, un determinato identificatore può assumere diverse forme a seconda del contesto in cui si trova. Il polimorfismo richiede il meccanismo di ereditarietà in modo che possa essere implementato. D'altra parte, l'overload dei metodi è un'altra funzionalità OOP che consente di creare diversi metodi che condividono lo stesso nome ma con dichiarazioni di parametri diverse.
Questa è una brevissima introduzione. Non c'è abbastanza spazio in questo articolo per discutere di questi argomenti, quindi approfondirli è un esercizio lasciato per te. Per favore, leggi le sezioni MQL5 Polimorfismo e Sovraccarico. In ogni caso, vediamo la libreria standard implementare tutte le funzionalità OOP, di conseguenza, meglio le conosciamo, meglio possiamo estendere l'API per soddisfare le nostre esigenze.
Con tutto ciò che è stato detto, c'è solo un'altra cosa da notare. MQL5 implementa il polimorfismo con un meccanismo chiamato Virtual Functions. Ancora una volta, per favore, leggi la sezione MQL5 Funzioni virtuali per capire come funziona.
Questo è il motivo per cui codiniamo il metodo di inizializzazione di CiZigZagin questo modo:
//+------------------------------------------------------------------+ //| Initialize the indicator with universal parameters | //+------------------------------------------------------------------+ bool CiZigZag::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]) { return(Initialize(symbol,period,(int)params[0].integer_value,(int)params[1].integer_value,(int)params[2].integer_value)); } //+------------------------------------------------------------------+ //| Initialize indicator with the special parameters | //+------------------------------------------------------------------+ bool CiZigZag::Initialize(const string symbol,const ENUM_TIMEFRAMES period, const int depth,const int deviation_init,const int backstep) { if(CreateBuffers(symbol,period,3)) { //--- string of status of drawing m_name ="ZigZag"; m_status="("+symbol+","+PeriodDescription()+","+ IntegerToString(depth)+","+IntegerToString(deviation_init)+","+ IntegerToString(backstep)+") H="+IntegerToString(m_handle); //--- save settings m_depth=depth; m_deviation=deviation_init; m_backstep=backstep; //--- create buffers ((CIndicatorBuffer*)At(0)).Name("ZIGZAG"); ((CIndicatorBuffer*)At(1)).Name("HIGH"); ((CIndicatorBuffer*)At(2)).Name("LOW"); //--- ok return(true); } //--- error return(false); }
4. Test del nuovo OO ZigZag, già disponibile nella Libreria Standard
Naturalmente, prima di utilizzare le estensioni sviluppate da te nei tuoi sviluppi OO, dovresti prima assicurarti che funzionino come previsto. Si consiglia di eseguire un set completo di test sui nuovi componenti personalizzati. Per problemi di semplicità, tuttavia, eseguiremo ora un semplice test sui tre metodi principali di CiZigZag, vale a dire, ZigZag (indice const int), High(indice const int) e Low (indice const int).
Ci limiteremo a stampare i valori calcolati con questi tre metodi su ogni tick di EA e quindi confronteremo l'output generato da ExpertOriginalZigZag.ex5, il fittizio EA procedurale, con l'output generato da ExpertOOZigZag.ex5, il fittizio EA orientato agli oggetti. Ogni volta che entrambe le uscite ottenute sono le stesse, possiamo concludere che la nuova estensione è OK, possiamo prendere per sempre il nostro OO ZigZag integrato nell'API MQL5.
Figura 4. Stiamo confrontando l'output generato da ExpertOriginalZigZag.ex5 con l'output generato da ExpertOOZigZag.ex5
Pertanto eseguiamo sia ExpertOriginalZigZag.ex5 che ExpertOOZigZag.ex5, i due EA presentati all'inizio di questo articolo, nello Strategy Tester con i seguenti parametri impostati:
- Simbolo: EURUSD, H1
- Data: Periodo personalizzato, dal 2013.08.01 al 2013.08.15
- Esecuzione: Normale, 1 minuto OHLC
- Deposito: 10000 USD, 1:100 USD
- Ottimizzazione: Nessuno
Poiché entrambi i robot stampano gli stessi risultati, concludiamo che il nostro CiZigZag è ben implementato, quindi possiamo usarlo nei nostri sviluppi d'ora in poi.
Log generated by ExpertOriginalZigZag.ex5:
DE 0 18:45:39 ExpertOriginalZigZag (EURUSD,H1) 2013.08.01 08:50:40 zigZagBuffer[0]: 1.32657 ML 0 18:45:39 ExpertOriginalZigZag (EURUSD,H1) 2013.08.01 08:50:40 zigZagLow[0]: 1.32657 FL 0 18:45:39 ExpertOriginalZigZag (EURUSD,H1) 2013.08.01 08:50:59 zigZagBuffer[0]: 1.32657 GE 0 18:45:39 ExpertOriginalZigZag (EURUSD,H1) 2013.08.01 08:50:59 zigZagLow[0]: 1.32657 KS 0 18:45:39 ExpertOriginalZigZag (EURUSD,H1) 2013.08.01 08:51:00 zigZagBuffer[0]: 1.32657 FR 0 18:45:39 ExpertOriginalZigZag (EURUSD,H1) 2013.08.01 08:51:00 zigZagLow[0]: 1.32657 GK 0 18:45:39 ExpertOriginalZigZag (EURUSD,H1) 2013.08.01 08:51:20 zigZagBuffer[0]: 1.32653 RJ 0 18:45:39 ExpertOriginalZigZag (EURUSD,H1) 2013.08.01 08:51:20 zigZagLow[0]: 1.32653 OR 0 18:45:39 ExpertOriginalZigZag (EURUSD,H1) 2013.08.01 08:51:40 zigZagBuffer[0]: 1.32653 FS 0 18:45:39 ExpertOriginalZigZag (EURUSD,H1) 2013.08.01 08:51:40 zigZagLow[0]: 1.32653 QJ 0 18:45:39 ExpertOriginalZigZag (EURUSD,H1) 2013.08.01 08:51:59 zigZagBuffer[0]: 1.32653 PH 0 18:45:39 ExpertOriginalZigZag (EURUSD,H1) 2013.08.01 08:51:59 zigZagLow[0]: 1.32653 JQ 0 18:45:39 ExpertOriginalZigZag (EURUSD,H1) 2013.08.01 08:52:00 zigZagBuffer[0]: 1.32653 KP 0 18:45:39 ExpertOriginalZigZag (EURUSD,H1) 2013.08.01 08:52:00 zigZagLow[0]: 1.32653 RH 0 18:45:39 ExpertOriginalZigZag (EURUSD,H1) 2013.08.01 08:52:20 zigZagBuffer[0]: 1.32653 GI 0 18:45:39 ExpertOriginalZigZag (EURUSD,H1) 2013.08.01 08:52:20 zigZagLow[0]: 1.32653 GP 0 18:45:39 ExpertOriginalZigZag (EURUSD,H1) 2013.08.01 08:52:40 zigZagBuffer[0]: 1.32614 // More data here!..
Log generato da ExpertOOZigZag.ex5:
RP 0 18:48:02 ExpertOOZigZag (EURUSD,H1) 2013.08.01 08:50:40 OO ZigZag buffer(0): 1.32657 HQ 0 18:48:02 ExpertOOZigZag (EURUSD,H1) 2013.08.01 08:50:40 OO ZigZag low(0): 1.32657 DI 0 18:48:02 ExpertOOZigZag (EURUSD,H1) 2013.08.01 08:50:59 OO ZigZag buffer(0): 1.32657 RH 0 18:48:02 ExpertOOZigZag (EURUSD,H1) 2013.08.01 08:50:59 OO ZigZag low(0): 1.32657 QR 0 18:48:02 ExpertOOZigZag (EURUSD,H1) 2013.08.01 08:51:00 OO ZigZag buffer(0): 1.32657 GS 0 18:48:02 ExpertOOZigZag (EURUSD,H1) 2013.08.01 08:51:00 OO ZigZag low(0): 1.32657 IK 0 18:48:02 ExpertOOZigZag (EURUSD,H1) 2013.08.01 08:51:20 OO ZigZag buffer(0): 1.32653 GJ 0 18:48:02 ExpertOOZigZag (EURUSD,H1) 2013.08.01 08:51:20 OO ZigZag low(0): 1.32653 EL 0 18:48:02 ExpertOOZigZag (EURUSD,H1) 2013.08.01 08:51:40 OO ZigZag buffer(0): 1.32653 OD 0 18:48:02 ExpertOOZigZag (EURUSD,H1) 2013.08.01 08:51:40 OO ZigZag low(0): 1.32653 OE 0 18:48:02 ExpertOOZigZag (EURUSD,H1) 2013.08.01 08:51:59 OO ZigZag buffer(0): 1.32653 IO 0 18:48:02 ExpertOOZigZag (EURUSD,H1) 2013.08.01 08:51:59 OO ZigZag low(0): 1.32653 DN 0 18:48:02 ExpertOOZigZag (EURUSD,H1) 2013.08.01 08:52:00 OO ZigZag buffer(0): 1.32653 RF 0 18:48:02 ExpertOOZigZag (EURUSD,H1) 2013.08.01 08:52:00 OO ZigZag low(0): 1.32653 PP 0 18:48:02 ExpertOOZigZag (EURUSD,H1) 2013.08.01 08:52:20 OO ZigZag buffer(0): 1.32653 RQ 0 18:48:02 ExpertOOZigZag (EURUSD,H1) 2013.08.01 08:52:20 OO ZigZag low(0): 1.32653 MI 0 18:48:02 ExpertOOZigZag (EURUSD,H1) 2013.08.01 08:52:40 OO ZigZag buffer(0): 1.32614 // More data here!..
Conclusione
La libreria standard MQL5 semplifica la vita come sviluppatore. Tuttavia, non può implementare tutte le esigenze di tutti gli sviluppatori di tutto il mondo, quindi ci sarà sempre un punto in cui dovrai creare le tue cose personalizzate. Man mano che gli EA e gli indicatori diventano sempre più complessi, è più necessario padroneggiare i concetti coinvolti nello sviluppo di un framework. L'estensione della MQL5 Standard Library è una garanzia di qualità per le vostre applicazioni per avere una vita di successo.
Abbiamo approfittato del riutilizzo del codice scaricando prima l'indicatore ZigZag da Code Base. Una volta disponibile nel nostro terminale MetaTrader 5, abbiamo adottato un top-down per iniziare a pensare al nostro nuovo indicatore ZigZag orientato agli oggetti. Abbiamo dato un'occhiata generale all'intero sistema e poi abbiamo continuato ad analizzare. Nella prima fase dello sviluppo abbiamo confrontato un EA fittizio utilizzando l'indicatore ZigZag in stile procedurale con la sua controparte orientata agli oggetti.
Abbiamo avvolto l'indicatore ZigZag in una classe orientata agli oggetti che è stata progettata secondo la filosofia di progettazione di MetaQuotes, la stessa applicata per la costruzione della Libreria Standard. E infine eseguiamo alcuni semplici test concludendo che il nostro nuovo wrapper CiZigZag, già integrato nell'API MQL5, è ben implementato.
Tradotto dall’inglese da MetaQuotes Ltd.
Articolo originale: https://www.mql5.com/en/articles/741
- 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