Unisciti alla nostra fan page
- Pubblicati da::
- MetaQuotes
- Visualizzazioni:
- 1268
- Valutazioni:
- Pubblicato:
- 2021.11.01 12:41
-
Hai bisogno di un robot o indicatore basato su questo codice? Ordinalo su Freelance Vai a Freelance
L'esempio di Expert Advisor MACD è incluso nel pacchetto standard del terminale MetaTrader 5 ed è un esempio di Ea che trada utilizzando l'indicatore MACD.
Il file dell' Expert Advisor MACD Sample.mq5 è situato in terminal_data_folder\MQL5\Experts\Examples\MACD\". Questo Expert Advisor è un esempio di approccio orietato agli oggetti nello sviluppo di un EA.
Andiamo a considerare la struttura dell' Expert Advisor e come lavora.
1 Proprietà dell'EA
1.1. Proprietà dell'EA
//+------------------------------------------------------------------+ //| MACD Sample.mq5 | //| Copyright 2009-2013, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2009-2013, MetaQuotes Software Corp." #property link "https://www.mql5.com" #property version "5.20" #property description "It is important to make sure that the expert works with a normal" #property description "chart and the user did not make any mistakes setting input" #property description "variables (Lots, TakeProfit, TrailingStop) in our case," #property description "we check TakeProfit on a chart of more than 2*trend_period bars"
Le prime 5 righe contengono un commento, le sette linee succesive impostano le proprietà del programma MQL5 (copyright, link, version, description) utilizzando le direttive del preprocessore #property.
Quando esegui gli Expert Advisor sono mostrati nella scheda "Comune":
Figura 1 parametri comuni dell'Esempio dell' EA MACD
1.2. File dell' Include
Dopo, la direttiva dell' #include dice al compilatore di includere i file che contengono le classi di trade della Libreria Standard.
- Trade.mqh (CTrade - una classe per le operazioni di trade);
- SymbolInfo.mqh (CSymbolInfo - una classe per lavorare con le proprietà di uno strumento di trading);
- PositionInfo.mqh (CPositionInfo - una classe per lavorare con le proprietà di una posizione aperta);
- AccountInfo.mqh (CAccountInfo - una classe per lavorare con le proprietà di un account di trading).
//--- include files #include <Trade\Trade.mqh> #include <Trade\SymbolInfo.mqh> #include <Trade\PositionInfo.mqh> #include <Trade\AccountInfo.mqh>
Le istanze delle classi appropriate vengono quindi utilizzate come variabili membro della classe CExpert (Sezione 3).
1.3. Inputs
Poi troviamo il tipo,nome,valori predefiniti e un commento. Il loro ruolo è mostrato in fig. 2.
//--- Expert Advisor input parameters input double InpLots =0.1; // Lots input int InpTakeProfit =50; // Take Profit (in pips) input int InpTrailingStop =30; // Trailing Stop Level (in pips) input int InpMACDOpenLevel =3; // MACD open level (in pips) input int InpMACDCloseLevel=2; // MACD close level (in pips) input int InpMATrendPeriod =26; // MA trend period
Notare che i nomi dei parametri di input hanno il prefisso "Inp". Notare anche che le variabili globali sono prefissate con "Ext". Questo tipo di approccio alla denominazione delle variabili semplifica l'utilizzo di molte variabili diverse.
InpLots - volume di trade, InpTakeProfit e InpTrailingStop determinano il Take Profit e i livelli di Trailing Stop.
Il testo nel commento nella linea dei parametri di input, affianco ai valori predefiniti, sono visualizzati nella scheda "Opzioni" anzichè il nome del parametro di input.
Figure 2. Parametri di input dell'Esempio dell' EA MACD
1.4. Variabili Globali
Poi è dichiarata la variabile globale ExtTimeOut. Sarà utilizzata per controllare il tempo di esecuzione delle operazioni di trade.
int ExtTimeOut=10; // tempo (in secondi) tra le operazioni di trade
Dopo la dichiarazione della classe CSampleExpert class, nella liea 76 un'altra variabile globale è dichiarata: ExtExpert - istanza della classe CSampleExpert:
//--- the ExtExpert global variable
CSampleExpert ExtExpert;
L'oggetto ExtExpert (classe di esempio CSampleExpert) contiene le basi logiche delle strategie dii trading (Sezione 3).
2. Funzioni di Gestione degli Eventi
Funzioni di Gestione degli Eventi
2.1. La funzione di inizializzazione OnInit()
La funzione OnInit()è chiamata una sola volta durante il primo avvio dell'Expert Advisor. Normalmente nelle gestione dll'evento OnInit() l'EA è pronto ad operare: vengono verificati i parametri di input, indicatori e i parametri sono inizializzati, etc. In caso di errori critici, quando ulteriore lavoro non ha senso, la funzione viene chiusa con il codice di ritorno INIT_FAILED.
//+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit(void) { //--- initialization and creation of all the required objects if(!ExtExpert.Init()) return(INIT_FAILED); //--- successful initialization return(INIT_SUCCEEDED); }
In questo caso, il metodo Init() dell'oggetto ExtExpert è chiamato, il quale ritorna true o false a seconda della preparazione di tutti gli oggetti richiesti per operare (vedere Sezione 3.4). In caso di errore, si esce da OnInit() con il codice di ritorno INIT_FAILED - è il modo corretto per completare l'operazione EA/indicatore in caso di inizializzazione non riuscita.
2.2. Funzione OnTick()
La funzione OnTick() è chiamata ogni volta che si riceve una nuova quotazione per il simbolo sul grafico, o sulla quale l'EA è eseguito.
//+------------------------------------------------------------------+ //| Expert new tick handling function | //+------------------------------------------------------------------+ void OnTick(void) { static datetime limit_time=0; // stores the last call time + timeout //--- do not operate if the required time has not elapsed if(TimeCurrent()>=limit_time) { //--- checking data if(Bars(Symbol(),Period())>2*InpMATrendPeriod) { //--- after the call of the Processing() method increase the value of limit_time by ExtTimeOut if(ExtExpert.Processing()) limit_time=TimeCurrent()+ExtTimeOut; } } }
Nel gestore dell'evento OnTick() è incluso un meccanismo per periodiche chiamate al metodo ExtExpert.Processing(), il quale è utilizzato per l'analisi del mercato e per le operazioni di trading quando le condizioni di trading sono soddisfatte.
L'intervallo di tempo tra le chiamate è impostato con il valore del parametro di input ExtTimeOut .
2.3. La funzione di deinizializzazione OnDeint()
OnDeInit() è chiamata quando un EA è rimosso dal garfico. Se un programma piazza oggetti grafici durante la sua operatività, possono essere rimossi dal grafico.
In questo esempio nessuna funzione di deinizializzazione è utilizzata, non sono eseguite azioni.
3. La classe CSampleExpert
3.1. La classe CSampleExpert
//+------------------------------------------------------------------+ //| The MACD Sample EA class sample | //+------------------------------------------------------------------+ class CSampleExpert { protected: //--- protected variables - class members are available only inside the class methods double m_adjusted_point; // a multiplier for 3/5-digit quotes CTrade m_trade; // CTrade class sample CSymbolInfo m_symbol; // CSymbolInfo class sample CPositionInfo m_position; // CPositionInfo class sample CAccountInfo m_account; // CAccountInfo class sample //--- indicator handles int m_handle_macd; // the MACD indicator handle int m_handle_ema; // the Moving Average indicator handle //--- indicator buffers double m_buff_MACD_main[]; // the buffer of the main line of the MACD indicator double m_buff_MACD_signal[]; // the buffer of the signal line of the MACD indicator double m_buff_EMA[]; // EMA indicator buffers //--- current indicator values double m_macd_current; double m_macd_previous; double m_signal_current; double m_signal_previous; double m_ema_current; double m_ema_previous; //--- levels (in standard points) double m_macd_open_level; double m_macd_close_level; double m_traling_stop; double m_take_profit; public: //--- constructor CSampleExpert(void); //--- destructor ~CSampleExpert(void); //--- public-methods can be called from outside the class //--- initialization method bool Init(void); //--- deinitialization method void Deinit(void); //--- method of processing bool Processing(void); protected: //--- protected-methods can be accessed only inside the class methods bool InitCheckParameters(const int digits_adjust); bool InitIndicators(void); bool LongClosed(void); bool ShortClosed(void); bool LongModified(void); bool ShortModified(void); bool LongOpened(void); bool ShortOpened(void); };
La classe EA contiene la dichiarazione di variabili (membri di classe) e funzioni (metodi di classe).
Per un lavoro più conveniente con le variabili, tutte le variabili dei membri della classe contengono il prefisso "m_" (membro), che indica che una variabile è un membro della classe. Prima della dichiarazione di una variabile o di un metodo, ne viene specificato il tipo (o il valore restituito per le funzioni).
La visibilità delle variabili e dei metodi dei membri della classe è definita utilizzando modificatori di accesso. Nella classe CSampleExpert vengono utilizzati i modificatori protected e public. Tutte le variabili e i metodi definiti nella sezione public, sono pubblici e accessibili dall'esterno. La classe CSampleExpert ha cinque di questi metodi:
- CSampleExpert(void) - un costruttore (chiamato automaticamente durante la creazione di un'istanza di classe);
- ~CSampleExpert(void) - un distruttore (chiamato automaticamente quando si elimina un'istanza di classe);
- bool Init(void) - metodo di inizializzazione, in cui vengono preparati tutti i dati necessari per il funzionamento;
- void Deinit(void) - metodo di deinizializzazione;
- bool Processing(void) - metodo di elaborazione.
Le variabili membro della classe CSampleExpert dichiarate con il modificatore di accesso protected saranno disponibili solo all'interno dei metodi della classe CSampleExpert (e delle classi figlio).
- double m_adjusted_point - variabile moltiplicatrice per una corretta operazione con virgola a 3/5 cifre;
- CTrade m_trade - СTrade classe d'esempio;
- CSymbolInfo m_symbol - CSymbolInfo classe d'esempio;
- CPositionInfo m_position - СPositionInfo classe d'esempio;
- CAccountInfo m_account - CAccountInfo classe d'esempio;
- int m_handle_macd - una variabile per memorizzare il valore dell'handle dell' indicatore MACD.
- int m_handle_ema - una variabile per memorizzare il valore dell'handle dell' indicatore EMA.
- double m_buff_MACD_main[] - un array dinamico di tipo double, che serve per richiedere i valori della linea main dell' MACD;
- double m_buff_MACD_signal[] - un array dinamico di tipo double, che serve per richiedere i valori della linea signal dell' MACD;
- double m_buff_EMA[] - un array dinamico di tipo double, che serve per richiedere i valori dell'indicatore EMA;
- double m_macd_current - è utilizzata per memorizzare il valore corrente della linea main dell'MACD;
- double m_macd_previous - è utilizzata per memorizzare il valore precedente della linea main dell'MACD;
- double m_signal_current - è utilizzata per memorizzare il valore corrente della linea signal dell'MACD;
- double m_signal_previous - è utilizzata per memorizzare il valore precedente della linea signal dell'MACD;
- double m_ema_current - è utilizzata per memorizzare il valore corrente dell'indicatore EMA;
- double m_ema_previous - è utilizzata per memorizzare il valore precedente dell'indicatore EMA
- double m_macd_open_level,
- double m_macd_close_level,
- double m_traling_stop,
- double m_take_profit - sono utilizzati per memorizzare i valori dei livelli di prezzo (impostati nei parametri di input) tenendo conto del moltiplicatore m_adjusted_point.
Metodi della classe CSampleExpert dichiarati con il modificatore di accesso protected:
- bool InitCheckParameters(const int digits_adjust) - verifica della correttezza dei parametri di input e inizializzazione dei parametri dell'EA;
- bool InitIndicators(void) - inizializzazione (creazione ) degli indicatori MACD e Moving Average;
- bool LongClosed(void) - restituisce true (e chiude una posizione lunga aperta) se sono soddisfatte le condizioni per chiudere una posizione lunga;
- bool ShortClosed(void) - restituisce true (e chiude una posizione corta aperta) se sono soddisfatte le condizioni per chiudere una posizione corta;
- bool LongModified(void) - restituisce true (e modifica il prezzo di Stop Loss) se sono soddisfatte le condizioni per modificare il livello di Stop Loss di una posizione lunga aperta;
- bool ShortModified(void) - restituisce true (e modifica il prezzo di Stop Loss) se sono soddisfatte le condizioni per modificare il livello di Stop Loss di una posizione corta aperta;
- bool LongOpened(void) - restituisce true (e apre una posizione long) se sono soddisfatte le condizioni per l'apertura di una posizione long;
- bool ShortOpened(void) - restituisce true (e apre una posizione corta) se le condizioni per l'apertura di una posizione corta sono soddisfatte.
3.2. Costruttore della Classe CSampleExpert
//+------------------------------------------------------------------+ //| CSampleExpert Class Constructor | //+------------------------------------------------------------------+ CSampleExpert::CSampleExpert(void) : m_adjusted_point(0), m_handle_macd(INVALID_HANDLE), m_handle_ema(INVALID_HANDLE), m_macd_current(0), m_macd_previous(0), m_signal_current(0), m_signal_previous(0), m_ema_current(0), m_ema_previous(0), m_macd_open_level(0), m_macd_close_level(0), m_traling_stop(0), m_take_profit(0) { ArraySetAsSeries(m_buff_MACD_main,true); ArraySetAsSeries(m_buff_MACD_signal,true); ArraySetAsSeries(m_buff_EMA,true); }
Il costruttore della Classe Costruttore di classe viene chiamato automaticamente quando viene creato un oggetto di esempio della classe. Quando viene chiamato, vengono impostati i valori predefiniti (tra parentesi) per le variabili membro della classe e le serie temporali direzione di indicizzazione per m_buff_MACD_main[], m_buff_MACD_signal[], m_buff_EMA[].
3.3. Distruttore della Classe CSampleExpert
//+------------------------------------------------------------------+ //| CSampleExpert class destructor | //+------------------------------------------------------------------+ CSampleExpert::~CSampleExpert(void) { }
Il distruttore della classe CSampleExpert non contiene alcun codice.
3.4. Il metodo Init della classe CSampleExpert
//+------------------------------------------------------------------+ //| Initialization and verification of input parameters | //+------------------------------------------------------------------+ bool CSampleExpert::Init(void) { //--- setting common properties m_symbol.Name(Symbol()); // symbol m_trade.SetExpertMagicNumber(12345); // magic //--- taking into account 3/5-digit quotes int digits_adjust=1; if(m_symbol.Digits()==3 || m_symbol.Digits()==5) digits_adjust=10; m_adjusted_point=m_symbol.Point()*digits_adjust; //--- setting the values of the levels taking into account the m_adjusted_point modifier m_macd_open_level =InpMACDOpenLevel*m_adjusted_point; m_macd_close_level=InpMACDCloseLevel*m_adjusted_point; m_traling_stop =InpTrailingStop*m_adjusted_point; m_take_profit =InpTakeProfit*m_adjusted_point; //--- setting the slippage of 3 points m_trade.SetDeviationInPoints(3*digits_adjust); //--- if(!InitCheckParameters(digits_adjust)) return(false); if(!InitIndicators()) return(false); //--- successful completion return(true); }
Nel metodo Init(), le variabili della classe membro sono inizializzate e i parametri di input verificati.
una chiamata del metodo Name() per l'oggetto m_symbol (istanza della classe CSymbolInfo) imposta il nome del simbolo, sulla quale l'Expert Advisor è avviato,in seguito è chiamato il metodo SetExpertMagicNumber(); Imposta il valore del magic number dell'EA per l'oggetto m_trade (verrà utilizzato per le operazioni di trading). Successivamente viene utilizzato il metodo Digits() per richiedere il numero di cifre del simbolo dopo la virgola e, se necessario, vengono corretti i valori dei livelli.
In seguito viene chiamato il metodo SetDeviationInPoints() dell'oggetto m_trade, in cui viene impostato il valore dello slippage consentito nelle operazioni di trade.
3.5. Il metodo della InitCheckParameters della classe CSampleExpert
//+------------------------------------------------------------------+ //| Checking for input parameters | //+------------------------------------------------------------------+ bool CSampleExpert::InitCheckParameters(const int digits_adjust) { //--- checking correctness of the Take Profit level if(InpTakeProfit*digits_adjust<m_symbol.StopsLevel()) { printf("Take Profit must be greater than %d",m_symbol.StopsLevel()); return(false); } //--- checking correctness of the Trailing Stop level if(InpTrailingStop*digits_adjust<m_symbol.StopsLevel()) { printf("Trailing Stop must be greater than %d",m_symbol.StopsLevel()); return(false); } //--- checking correctness of the trade volume if(InpLots<m_symbol.LotsMin() || InpLots>m_symbol.LotsMax()) { printf("Lots amount must be in the range from %f to %f",m_symbol.LotsMin(),m_symbol.LotsMax()); return(false); } if(MathAbs(InpLots/m_symbol.LotsStep()-MathRound(InpLots/m_symbol.LotsStep()))>1.0E-10) { printf("Lots amount is not corresponding with lot step %f",m_symbol.LotsStep()); return(false); } //--- show warning if Take Profit<=Trailing Stop if(InpTakeProfit<=InpTrailingStop) printf("Warning: Trailing Stop must be less than Take Profit"); //--- successful completion return(true); }
La correttezza dei parametri di input dell'EA viene verificata nel metodo InitCheckParameters(). Se uno dei parametri non è valido, viene visualizzato un messaggio appropriato e la funzione restituisce false.
3.6. Il metodo InitIndicators() della classe CSampleExpert
//+------------------------------------------------------------------+ //| Indicators initialization method | //+------------------------------------------------------------------+ bool CSampleExpert::InitIndicators(void) { //--- creating the MACD indicator if(m_handle_macd==INVALID_HANDLE) if((m_handle_macd=iMACD(NULL,0,12,26,9,PRICE_CLOSE))==INVALID_HANDLE) { printf("Error creating MACD indicator"); return(false); } //--- creating the EMA indicator if(m_handle_ema==INVALID_HANDLE) if((m_handle_ema=iMA(NULL,0,InpMATrendPeriod,0,MODE_EMA,PRICE_CLOSE))==INVALID_HANDLE) { printf("Error creating EMA indicator"); return(false); } //--- successful completion return(true); }
Nel metodo InitIndicators() viene verificata la correttezza dei valori iniziali delle variabili m_handle_macd e m_handle_ema (devono essere uguali a INVALID_HANDLE, poiché sono stati inizializzati nel costruttore), e gli indicatori tecnici MACD e Moving Average vengono creati (utilizzando le funzioni iMACD e iMA). In caso di successo, la funzione restituisce true e gli handle dell'indicatore vengono salvati nei membri della classe m_handle_macd e m_handle_ema.
Gli handle degli indicatori creati verranno quindi utilizzati per verificare la quantità di dati calcolati (BarsCalculated) e ottenere i valori numerici (CopyBuffer) degli indicatori nel metodo Processing ().
3.7. Il metodo LongClosed() della classe CSampleExpert
//+------------------------------------------------------------------+ //| Checking conditions for closing a long position | //+------------------------------------------------------------------+ bool CSampleExpert::LongClosed(void) { bool res=false; //--- Should the position be closed? if(m_macd_current>0) if(m_macd_current<m_signal_current && m_macd_previous>m_signal_previous) if(m_macd_current>m_macd_close_level) { //--- closing the position if(m_trade.PositionClose(Symbol())) printf("Long position by %s to be closed",Symbol()); else printf("Error closing position by %s : '%s'",Symbol(),m_trade.ResultComment()); res=true; } //--- returning the result return(res); }
Il metodo LongClosed() restituisce true (e chiude la posizione long aperta) se vengono soddisfatte le condizioni per la chiusura della posizione:
- m_macd_current>0 - il valore corrente della linea main dell'indicatore MACD è positivo (l'istogramma dell'MACD è sopra la linea dello zero);
- m_macd_current<m_signal_current && m_macd_previous>m_signal_previous - la linea main dell'indicatore MACD ha attraversato verso il basso la linea del signal.
- m_macd_current>m_macd_close_level - il valore corrente della linea main dell'indicatore MACD è maggiore di m_macd_close_level.
3.8. Il metodo shortClosed() della classe CSampleExpert
//+------------------------------------------------------------------+ //| Checking conditions for closing a short position | //+------------------------------------------------------------------+ bool CSampleExpert::ShortClosed(void) { bool res=false; //--- Should the position be closed? if(m_macd_current<0) if(m_macd_current>m_signal_current && m_macd_previous<m_signal_previous) if(MathAbs(m_macd_current)>m_macd_close_level) { //--- closing the position if(m_trade.PositionClose(Symbol())) printf("Short position by %s to be closed",Symbol()); else printf("Error closing position by %s : '%s'",Symbol(),m_trade.ResultComment()); res=true; } //--- returning the result return(res); }
Il metodo ShortClosed() restituisce true (e chiude la posizione short aperta) se vengono soddisfatte le condizioni per la chiusura della posizione short:
- m_macd_current<0 - il valore corrente della linea main dell'indicatore MACD è negativo (l'istogramma dell'MACD è sotto la linea dello zero);
- m_macd_current>m_signal_current && m_macd_previous<m_signal_previous - la linea main dell'indicatore MACD ha attraversato verso l'alto la linea del signal.
- MathAbs(m_macd_current)>m_macd_close_level - il valore corrente della linea main dell'indicatore MACD è maggiore di m_macd_close_level.
3.9. Il metodo LongModified() della classe CSampleExpert
//+------------------------------------------------------------------+ //| Checking conditions for long position modification | //+------------------------------------------------------------------+ bool CSampleExpert::LongModified(void) { bool res=false; //--- checking if Trailing Stop is required if(InpTrailingStop>0) { if(m_symbol.Bid()-m_position.PriceOpen()>m_adjusted_point*InpTrailingStop) { double sl=NormalizeDouble(m_symbol.Bid()-m_traling_stop,m_symbol.Digits()); double tp=m_position.TakeProfit(); if(m_position.StopLoss()<sl || m_position.StopLoss()==0.0) { //--- modifying Stop Loss and Take Profit of the position if(m_trade.PositionModify(Symbol(),sl,tp)) printf("Long position by %s to be modified",Symbol()); else { printf("Error modifying position by %s : '%s'",Symbol(),m_trade.ResultComment()); printf("Modify parameters : SL=%f,TP=%f",sl,tp); } res=true; } } } //--- returning the result return(res); }
Il metodo LongModified() ritorna true (e modifica il valore dello Stop Loss) se le condizioni per la modifica della posizione long sono soddisfatte: se il valore dell'input InpTrailingStop>0, se le condizioni per la modifica della posizione long sono soddisfatte: Se il valore dell'input InpTrailingStop>0, viene verificato il fatto che il prezzo passato InpTrailingStop punti dal prezzo aperto nella direzione della posizione. Successivamente si calcola il valore del nuovo livello di Stop Loss e si modifica il parametro Stop Loss della posizione aperta.
3.10. Il metodo ShortModified() della classe CSampleExpert
//+------------------------------------------------------------------+ //| Checking conditions for long position modification | //+------------------------------------------------------------------+ bool CSampleExpert::ShortModified(void) { bool res=false; //--- checking if Trailing Stop is required if(InpTrailingStop>0) { if((m_position.PriceOpen()-m_symbol.Ask())>(m_adjusted_point*InpTrailingStop)) { double sl=NormalizeDouble(m_symbol.Ask()+m_traling_stop,m_symbol.Digits()); double tp=m_position.TakeProfit(); if(m_position.StopLoss()>sl || m_position.StopLoss()==0.0) { //--- modifying Stop Loss and Take Profit of the position if(m_trade.PositionModify(Symbol(),sl,tp)) printf("Short position by %s to be modified",Symbol()); else { printf("Error modifying position by %s : '%s'",Symbol(),m_trade.ResultComment()); printf("Modify parameters : SL=%f,TP=%f",sl,tp); } res=true; } } } //--- returning the result return(res); }
Il metodo ShortModified() ritorna true (e modifica il valore dello Stop Loss) se le condizioni per la modifica della posizione short sono soddisfatte: se il valore dell'input InpTrailingStop>0, viene verificato il fatto che il prezzo passato InpTrailingStop punti dal prezzo aperto nella direzione della posizione. Successivamente si calcola il valore del nuovo livello di Stop Loss e si modifica il parametro Stop Loss della posizione aperta.
3.11. Il metodo LongOpened() della classe CSampleExpert
//+------------------------------------------------------------------+ //| Check for long position opening | //+------------------------------------------------------------------+ bool CSampleExpert::LongOpened(void) { bool res=false; //--- checking conditions for opening a long position if(m_macd_current<0) if(m_macd_current>m_signal_current && m_macd_previous<m_signal_previous) if(MathAbs(m_macd_current)>(m_macd_open_level) && m_ema_current>m_ema_previous) { double price=m_symbol.Ask(); double tp =m_symbol.Bid()+m_take_profit; //--- checking free margin if(m_account.FreeMarginCheck(Symbol(),ORDER_TYPE_BUY,InpLots,price)<0.0) printf("We have no money. Free Margin = %f",m_account.FreeMargin()); else { //--- opening a long position if(m_trade.PositionOpen(Symbol(),ORDER_TYPE_BUY,InpLots,price,0.0,tp)) printf("Position by %s to be opened",Symbol()); else { printf("Error opening BUY position by %s : '%s'",Symbol(),m_trade.ResultComment()); printf("Open parameters : price=%f,TP=%f",price,tp); } } res=true; } //--- returning the result return(res); }
Il metodo LongOpened() ritorna true (e apre una posizione long) se le condizioni per aprire una posizione buy sono soddisfatte:
- m_macd_current<0 - il valore corrente della linea main dell'indicatore MACD è negativo (l'istogramma dell'MACD è sotto la linea dello zero);
- m_macd_current>m_signal_current && m_macd_previous<m_signal_previous - la linea main dell'indicatore MACD ha attraversato verso l'alto la linea del signal.
- MathAbs(m_macd_current)>m_macd_open_level - il valore corrente della linea main dell'indicatore MACD è maggiore di m_macd_open_level;
- m_ema_current>m_ema_previous - l'ema cresce.
Quando tutte le condizioni sono soddisfatte, viene controllato il margine libero (il metodo FreeMarginCheck() della classe della libreria standard CAccountInfo) e viene aperta una posizione long utilizzando la PositionOpen () metodo della classe CTrade.
3.12. Il metodo ShortOpened() della classe CSampleExpert
//+------------------------------------------------------------------+ //| Check for short position opening | //+------------------------------------------------------------------+ bool CSampleExpert::ShortOpened(void) { bool res=false; //--- checking conditions for opening a short position if(m_macd_current>0) if(m_macd_current<m_signal_current && m_macd_previous>m_signal_previous) if(m_macd_current>(m_macd_open_level) && m_ema_current<m_ema_previous) { double price=m_symbol.Bid(); double tp =m_symbol.Ask()-m_take_profit; //--- checking free margin if(m_account.FreeMarginCheck(Symbol(),ORDER_TYPE_SELL,InpLots,price)<0.0) printf("We have no money. Free Margin = %f",m_account.FreeMargin()); else { //--- opening a short position if(m_trade.PositionOpen(Symbol(),ORDER_TYPE_SELL,InpLots,price,0.0,tp)) printf("Position by %s to be opened",Symbol()); else { printf("Error opening SELL position by %s : '%s'",Symbol(),m_trade.ResultComment()); printf("Open parameters : price=%f,TP=%f",price,tp); } } res=true; } //--- returning the result return(res); }
Il metodo ShortOpened() ritorna true (e apre una posizione short) se le condizioni per aprire una posizione sell sono soddisfatte:
- m_macd_current>0 - il valore corrente della linea main dell'indicatore MACD è positivo (l'istogramma dell'MACD è sopra la linea dello zero);
- m_macd_current<m_signal_current && m_macd_previous>m_signal_previous - la linea main dell'indicatore MACD ha attraversato verso il basso la linea del signal.
- m_macd_current>m_macd_open_level - il valore corrente della linea main dell'indicatore MACD è maggiore di m_macd_open_level;
- m_ema_current<m_ema_previous - l'ema scende.
Quando tutte le condizioni sono soddisfatte, viene controllato il margine libero (il metodo FreeMarginCheck() della classe della libreria standard CAccountInfo) e viene aperta una posizione short utilizzando la PositionOpen () metodo della classe CTrade.
3.13 Il metodo Processing() della classe CSampleExpert
//+------------------------------------------------------------------+ //| main function returns true if any position processed | //+------------------------------------------------------------------+ bool CSampleExpert::Processing(void) { //--- updating quotes if(!m_symbol.RefreshRates()) return(false); //--- updating indicator values if(BarsCalculated(m_handle_macd)<2 || BarsCalculated(m_handle_ema)<2) return(false); if(CopyBuffer(m_handle_macd,0,0,2,m_buff_MACD_main) !=2 || CopyBuffer(m_handle_macd,1,0,2,m_buff_MACD_signal)!=2 || CopyBuffer(m_handle_ema,0,0,2,m_buff_EMA) !=2) return(false); //--- to simplify work with indicators and for faster access //--- the current values of the indicators are saved in internal variables (class members) m_macd_current =m_buff_MACD_main[0]; m_macd_previous =m_buff_MACD_main[1]; m_signal_current =m_buff_MACD_signal[0]; m_signal_previous=m_buff_MACD_signal[1]; m_ema_current =m_buff_EMA[0]; m_ema_previous =m_buff_EMA[1]; //--- correct market entry is important, but a correct exit is even more important //--- first check if there is an open position if(m_position.Select(Symbol())) { if(m_position.PositionType()==POSITION_TYPE_BUY) { //--- if necessary, we try to close or modify a long position if(LongClosed()) return(true); if(LongModified()) return(true); } else { //--- if necessary, we try to close or modify a short position if(ShortClosed()) return(true); if(ShortModified()) return(true); } } //--- no open positions else { //--- check conditions and open a long position if necessary if(LongOpened()) return(true); //--- check conditions and open a short position if necessary if(ShortOpened()) return(true); } //--- exit without position processing return(false); }
Il metodo Processing() della classe CSampleExpert è il metodo dell'Expert Advisor. Il metodo Processing() viene chiamato nel gestore dell'evento OnTick() e viene monitorato l'intervallo di tempo tra le chiamate successive di questo metodo (non meno di ExtTimeOut secondi) (sezione 2.2).
Chiamando il metodo RefreshRates() della classe CSymbolInfo le quotazioni vengono aggiornate. La funzione BarsCalculated() viene utilizzata per richiedere il numero di barre, per le quali vengono calcolati gli indicatori MACD e Moving Average (sezione 3.6.); se il numero di barre è inferiore a 2, esce dalla funzione e restituisci false.
Successivamente, la chiamata alla funzione CopyBuffer richiede gli ultimi due valori degli indicatori tecnici (le linee MACD main e signal e i valori della Moving Average ); e se la quantità di dati copiati è inferiore a due, esce dalla funzione. Successivamente i valori degli indicatori dagli array m_buff_MACD_main[], m_buff_MACD_signal[] e m_buff_EMA[] vengono copiati nelle variabili m_macd_current, m_macd_previous, m_signal_current, m_signal_previous, m_ema_current e m_ema_previous.
Il passo successivo è lavorare con una posizione tramite la classe CPositionInfo della Libreria Standard. Se la chiamata al metodo Select() ha restituito true, significa che attualmente esiste una posizione aperta, il suo tipo viene determinato utilizzando il metodo PositionType(). Ulteriori lavori vengono eseguiti in base al tipo di posizione aperta.
4. Backtesting
I migliori valori dei parametri si possono trovare utilizzando lo Strategy Tester del terminale MetaTrader 5.
La Figura 3 mostra i risultati dei test dell' Expert Advisor per il 2013 con le impostazioni predefinite.
Figure 3. Risultato del Backtest dell' Esempio di Expert Advisor MACD
Conclusioni
Il MACD Sample Expert Advisor, incluso nel pacchetto standard rilasciato col terminale MetaTrader 5, è un esempio di approccio orientato agli oggetti nello sviluppo di EA.
Tradotto dal russo da MetaQuotes Ltd.
Codice originale https://www.mql5.com/ru/code/2154

L'Expert Advisor Moving Average (Media Mobile) trada quando il prezzo attraversa la MA

ALGLIB libreria di funzioni matematiche (v. 3.19) portata a MQL5.

L'indicatore Bollinger Bands ® (BB) è simile a Envelopes. L'unica differenza è che le bande Envelopes sono tracciate ad una distanza fissa (%) dalla media mobile, mentre le Bande di Bollinger sono tracciate ad un certo numero di deviazioni standard da essa.

The Acceleration/Deceleration Indicator (AC) measures acceleration and deceleration of the current driving force.