
MQL5 Wizard: Come insegnare a un EA ad aprire ordini pendenti a qualsiasi prezzo
Introduzione
Un Expert Advisor generato utilizzando la procedura guidata MQL5 può aprire gli ordini pendenti solo ad una distanza fissa dal prezzo corrente. Ciò significa che se la situazione del mercato cambia (ad esempio un cambiamento nella volatilità del mercato), l'Expert Advisor dovrà essere nuovamente eseguito con nuovi parametri.
Questo non sarebbe adatto per molti sistemi di trading. Nella maggior parte dei casi, il livello di prezzo per gli ordini pendenti è determinato dinamicamente da un sistema di trading. E la distanza dal prezzo corrente è in continua evoluzione. In questo articolo, discuteremo come modificare un Expert Advisor generato utilizzando la procedura guidata MQL5 in modo che possa aprire ordini pendenti a distanze variabili dal prezzo corrente.
1. Meccanismo di apertura degli ordini pendenti nell'Expert Advisor generato utilizzando la procedura guidata MQL5
Un Expert Advisor generato avrebbe approssimativamente lo stesso codice nella sua intestazione come fornito di seguito:
//+------------------------------------------------------------------+ //| Inputs | //+------------------------------------------------------------------+ //--- inputs for expert input string Expert_Title="ExpertMySignalEnvelopes.mq5"; // Document name ulong Expert_MagicNumber =3915; // bool Expert_EveryTick =false; // //--- inputs for main signal input int Signal_ThresholdOpen =10; // Signal threshold value to open [0...100] input int Signal_ThresholdClose =10; // Signal threshold value to close [0...100] input double Signal_PriceLevel =0.0; // Price level to execute a deal input double Signal_StopLevel =85.0; // Stop Loss level (in points) input double Signal_TakeLevel =195.0; // Take Profit level (in points) input int Signal_Expiration =0; // Expiration of pending orders (in bars) input int Signal_Envelopes_PeriodMA =13; // Envelopes(13,0,MODE_SMA,...) Period of averaging input int Signal_Envelopes_Shift =0; // Envelopes(13,0,MODE_SMA,...) Time shift input ENUM_MA_METHOD Signal_Envelopes_Method =MODE_SMA; // Envelopes(13,0,MODE_SMA,...) Method of averaging input ENUM_APPLIED_PRICE Signal_Envelopes_Applied =PRICE_CLOSE; // Envelopes(13,0,MODE_SMA,...) Prices series input double Signal_Envelopes_Deviation=0.2; // Envelopes(13,0,MODE_SMA,...) Deviation input double Signal_Envelopes_Weight =1.0; // Envelopes(13,0,MODE_SMA,...) Weight [0...1.0] //--- inputs for money input double Money_FixLot_Percent =10.0; // Percent input double Money_FixLot_Lots =0.1; // Fixed volume //+------------------------------------------------------------------+
Si prega di notare il parametro Signal_PriceLevel. Per impostazione predefinita, Expert Advisor viene generato con Signal_PriceLevel=0. Questo parametro definisce la distanza dal prezzo corrente. Se è uguale a zero, verrà aperto un ordine al prezzo corrente di mercato. Per aprire un ordine pendente, è necessario impostare un valore diverso da zero per il parametro Signal_PriceLevel, ovvero Signal_PriceLevel può essere sia negativo che positivo.
Il valore di Signal_PriceLevel è di solito un numero abbastanza grande. La differenza tra valori negativi e positivi è mostrata di seguito:
Signal_PriceLevel=-50:
Fig. 1. Signal_PriceLevel=-50
Signal_PriceLevel=50:
Fig. 2. Signal_PriceLevel=50
Pertanto, se Signal_PriceLevel = -50, un ordine pendente verrà aperto al prezzo meno favorevole del prezzo corrente, mentre se Signal_PriceLevel = 50, un ordine pendente verrà aperto al prezzo migliore del prezzo corrente.
Questa versione di Expert Advisor apre gli ordini Sell Stop e Buy Stop.
2. Dove memorizziamo i dati sulla distanza dal prezzo per l'apertura di un ordine pendente?
Diamo prima un'occhiata alla figura qui sotto e poi procediamo ai commenti:
Fig. 3. Memorizzazione dei dati sulla distanza dal prezzo corrente
Interpretazione della figura di cui sopra.
Expert Advisor è l'Expert Advisor generato utilizzando la procedura guidata MQL5.
- L'oggetto ExtExpert della classe CExpert viene dichiarato in Expert Advisor a livello globale.
- Quindi, nella funzione OnInit() di Expert Advisor, dichiariamo un puntatore all'oggetto segnale della classe CExpertSignal e l'oggetto segnaleviene immediatamente creato utilizzando il nuovo operatore.
- Pur essendo nella funzione OnInit(), chiamiamo la funzione InitSignal dell'oggetto ExtExpert e inizializziamo l'oggetto segnale.
- Pur essendo nella funzione OnInit(), chiamiamo la funzione PriceLevel dell'oggetto segnale che ottiene il parametro Signal_PriceLevel.
Pertanto, il parametro Signal_PriceLevel in cui viene memorizzata la distanza dal prezzo corrente e che è stato dichiarato nell'Expert Advisor viene passato all'oggetto segnale della classe CExpertSignal.
La classe CExpertSignal memorizza il valore della distanza dal prezzo corrente nella variabile m_price_level dichiarata con l'ambito della classe protetta:
class CExpertSignal : public CExpertBase { protected: //--- variables double m_base_price; // base price for detection of level of entering (and/or exit?) //--- variables for working with additional filters CArrayObj m_filters; // array of additional filters (maximum number of fileter is 64) //--- Adjusted parameters double m_weight; // "weight" of a signal in a combined filter int m_patterns_usage; // bit mask of using of the market models of signals int m_general; // index of the "main" signal (-1 - no) long m_ignore; // bit mask of "ignoring" the additional filter long m_invert; // bit mask of "inverting" the additional filter int m_threshold_open; // threshold value for opening int m_threshold_close;// threshold level for closing double m_price_level; // level of placing a pending orders relatively to the base price double m_stop_level; // level of placing of the "stop loss" order relatively to the open price double m_take_level; // level of placing of the "take profit" order relatively to the open price int m_expiration; // time of expiration of a pending order in bars
3. Struttura di Expert Advisor generata utilizzando la procedura guidata MQL5
L'Expert Advisor è composto da diversi blocchi con diverse funzionalità.
Fig. 4. Struttura dell'Expert Advisor
Interpretazione della figura di cui sopra:
- Expert Advisor è l'Expert Advisor generato utilizzando la procedura guidata MQL5.
- CExpert è la classe base per l'implementazione di strategie di trading.
- CExpertSignal è la classe base per la creazione di generatori di segnali di trading.
- filtro0 ... filtron sono generatori di segnali di trading, i discendenti della classe CExpertSignal. Va notato che il nostro sistema di trading si basa sul generatore di segnali di trading dell'indicatore Envelopes, ma i segnali all'interno del generatore sono stati modificati. Parleremo di questi cambiamenti nella sezione 7.
4. Blocchi di Expert Advisor consigliabili per la modifica
Come si può vedere dalla struttura di Expert Advisor generata utilizzando la procedura guidata MQL5, ci sono blocchi di classe base. Le classi base fanno parte della libreria standard.
Le classi di per sé sono discendenti di altre classi base e a loro volta sono costituite da una o più classi base. Di seguito puoi trovare le prime righe del codice di due classi - CExpert e CExpertSignal:
//+------------------------------------------------------------------+ //| Expert.mqh | //| Copyright 2009-2013, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #include "ExpertBase.mqh" #include "ExpertTrade.mqh" #include "ExpertSignal.mqh" #include "ExpertMoney.mqh" #include "ExpertTrailing.mqh" //+------------------------------------------------------------------+ . . . class CExpert : public CExpertBase
e
//+------------------------------------------------------------------+ //| ExpertSignal.mqh | //| Copyright 2009-2013, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #include "ExpertBase.mqh" . . . class CExpertSignal : public CExpertBase
Sono fortemente contrario a qualsiasi modifica delle classi base:
- Quando MetaEditor viene aggiornato, tutte le modifiche apportate alle classi base vengono ignorate e le classi base vengono ripristinate allo stato iniziale.
- L'eredità sarebbe più appropriata in questo caso. Ma poi dovrai modificare l'INTERA libreria standard.
Invece, sarebbe meglio modificare il blocco dei moduli Expert Advisor e generatore di segnali di trading, soprattutto perché il nostro sistema di trading avrà già un modulo modificato in uso - il generatore di segnali di trading dell'indicatore Envelopes.
Quindi, questo è risolto:apporteremo modifiche ai blocchi dell'Expert Advisor e al blocco del generatore di segnali di trading.
5. La logica di implementazione
Il puntatore verrà passato dall'Expert Advisor al generatore di segnali di trading.
A tale scopo, è inoltre necessario dichiarare una variabile con l'ambito protetto e scrivere un metodo che memorizza il puntatore di Expert Advisor nella variabile interna:
Fig. 5. La logica di implementazione
6. Sistema di trading
L'intervallo di tempo del grafico è D1. L'indicatore da utilizzare è Buste con il periodo medio di 13 e metodo di media esponenziale. I tipi di ordini che l'Expert Advisor può aprire sono Sell Stop e Buy Stop.
Se la barra precedente era rialzista, impostiamo un ordine Sell Stop. Se la barra precedente era ribassista, impostiamo un ordine Buy Stop. In altre parole, speriamo nel pullback:
Fig. 6. Sistema di trading
Per generare segnali di trading come richiesto dal sistema di trading, il modulo standard del generatore di segnali di trading SignalEnvelopes.mqh è stato modificato.
Si noti che qui è possibile utilizzare qualsiasi generatore di segnali di trading dalla libreria standard.
7. Modifica del generatore di segnali di trading. Ottenere il prezzo della barra
Quindi, iniziamo. Devo dire che preferisco salvare i miei programmi in MQL5 Storage.
La prima cosa che dovremmo fare per iniziare a modificare il generatore di segnali di trading è creare un file di include vuoto, eliminare tutto da esso e incollare l'intero contenuto del generatore di segnali di trading standard dell'indicatore Envelopes.
Per impostazione predefinita, il generatore di segnali di trading deve trovarsi sotto ...MQL5\Include\Expert\Signal. Per non sovraccaricare il ...\Cartella segnale della libreria standard con troppe informazioni, creiamo una nuova cartella sotto il ...\Expert cartella e chiamarlo \MySignals:
Fig. 7. Creazione della cartella MySignals
Successivamente, creeremo un file di inclusione utilizzando la procedura guidata MQL5.
In MetaEditor, seleziona "Nuovo" nel menu File, quindi seleziona "Includi file (*.mqh)".
Fig. 8. MQL5 Wizard. Creare un file include
Il nome della nostra classe di generatori di segnali sarà MySignalEnvelopes.
E si troverà sotto: Include\Expert\MySignals\MySignalEnvelopes. Specifichiamolo:
Fig. 9. MQL5 Wizard. Percorso del file di include
Dopo aver fatto clic su "Fine", la procedura guidata MQL5 genererà un modello vuoto.
Il file MySignalEnvelopes.mqh generato deve quindi essere aggiunto all'archiviazione MQL5:
Fig. 10. MQL5 Storage. Aggiunta del file
Una volta aggiunto il file, è necessario eseguire il commit delle modifiche a MQL5 Storage:
Fig. 11. MQL5 Storage. Impegnare le modifiche
Dopo aver completato i passaggi precedenti, possiamo procedere alla modifica del nostro generatore di segnali di trading.
Poiché il generatore è basato sul file \Include\Expert\Signal\SignalEnvelopes.mqh, copiamo l'intero contenuto del file e lo incolliamo nel file generatore, lasciando solo l'intestazione originale:
//+------------------------------------------------------------------+ //| MySignalEnvelopes.mqh | //| Copyright © 2013, Vladimir Karputov | //| http://wmua.ru/slesar/ | //+------------------------------------------------------------------+ #property copyright "Copyright © 2013, Vladimir Karputov" #property link "http://wmua.ru/slesar/" #include <Expert\ExpertSignal.mqh> // wizard description start //+------------------------------------------------------------------+ //| Description of the class | //| Title=Signals of indicator 'Envelopes' | //| Type=SignalAdvanced | //| Name=Envelopes | //| ShortName=Envelopes | //| Class=CSignalEnvelopes | //| Page=signal_envelopes | //| Parameter=PeriodMA,int,45,Period of averaging | //| Parameter=Shift,int,0,Time shift | //| Parameter=Method,ENUM_MA_METHOD,MODE_SMA,Method of averaging | //| Parameter=Applied,ENUM_APPLIED_PRICE,PRICE_CLOSE,Prices series | //| Parameter=Deviation,double,0.15,Deviation | //+------------------------------------------------------------------+ // wizard description end //+------------------------------------------------------------------+ //| Class CSignalEnvelopes. | //| Purpose: Class of generator of trade signals based on | //| the 'Envelopes' indicator. | //| Is derived from the CExpertSignal class. | //+------------------------------------------------------------------+ class CSignalEnvelopes : public CExpertSignal { protected: CiEnvelopes m_env; // object-indicator //--- adjusted parameters int m_ma_period; // the "period of averaging" parameter of the indicator int m_ma_shift; // the "time shift" parameter of the indicator ENUM_MA_METHOD m_ma_method; // the "method of averaging" parameter of the indicator ENUM_APPLIED_PRICE m_ma_applied; // the "object of averaging" parameter of the indicator double m_deviation; // the "deviation" parameter of the indicator double m_limit_in; // threshold sensitivity of the 'rollback zone' double m_limit_out; // threshold sensitivity of the 'break through zone' //--- "weights" of market models (0-100) int m_pattern_0; // model 0 "price is near the necessary border of the envelope" int m_pattern_1; // model 1 "price crossed a border of the envelope" public: CSignalEnvelopes(void); ~CSignalEnvelopes(void); //--- methods of setting adjustable parameters void PeriodMA(int value) { m_ma_period=value; } void Shift(int value) { m_ma_shift=value; } void Method(ENUM_MA_METHOD value) { m_ma_method=value; } void Applied(ENUM_APPLIED_PRICE value) { m_ma_applied=value; } void Deviation(double value) { m_deviation=value; } void LimitIn(double value) { m_limit_in=value; } void LimitOut(double value) { m_limit_out=value; } //--- methods of adjusting "weights" of market models void Pattern_0(int value) { m_pattern_0=value; } void Pattern_1(int value) { m_pattern_1=value; } //--- method of verification of settings virtual bool ValidationSettings(void); //--- method of creating the indicator and timeseries virtual bool InitIndicators(CIndicators *indicators); //--- methods of checking if the market models are formed virtual int LongCondition(void); virtual int ShortCondition(void); protected: //--- method of initialization of the indicator bool InitMA(CIndicators *indicators); //--- methods of getting data double Upper(int ind) { return(m_env.Upper(ind)); } double Lower(int ind) { return(m_env.Lower(ind)); } }; //+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ CSignalEnvelopes::CSignalEnvelopes(void) : m_ma_period(45), m_ma_shift(0), m_ma_method(MODE_SMA), m_ma_applied(PRICE_CLOSE), m_deviation(0.15), m_limit_in(0.2), m_limit_out(0.2), m_pattern_0(90), m_pattern_1(70) { //--- initialization of protected data m_used_series=USE_SERIES_OPEN+USE_SERIES_HIGH+USE_SERIES_LOW+USE_SERIES_CLOSE; } //+------------------------------------------------------------------+ //| Destructor | //+------------------------------------------------------------------+ CSignalEnvelopes::~CSignalEnvelopes(void) { } //+------------------------------------------------------------------+ //| Validation settings protected data. | //+------------------------------------------------------------------+ bool CSignalEnvelopes::ValidationSettings(void) { //--- validation settings of additional filters if(!CExpertSignal::ValidationSettings()) return(false); //--- initial data checks if(m_ma_period<=0) { printf(__FUNCTION__+": period MA must be greater than 0"); return(false); } //--- ok return(true); } //+------------------------------------------------------------------+ //| Create indicators. | //+------------------------------------------------------------------+ bool CSignalEnvelopes::InitIndicators(CIndicators *indicators) { //--- check pointer if(indicators==NULL) return(false); //--- initialization of indicators and timeseries of additional filters if(!CExpertSignal::InitIndicators(indicators)) return(false); //--- create and initialize MA indicator if(!InitMA(indicators)) return(false); //--- ok return(true); } //+------------------------------------------------------------------+ //| Initialize MA indicators. | //+------------------------------------------------------------------+ bool CSignalEnvelopes::InitMA(CIndicators *indicators) { //--- check pointer if(indicators==NULL) return(false); //--- add object to collection if(!indicators.Add(GetPointer(m_env))) { printf(__FUNCTION__+": error adding object"); return(false); } //--- initialize object if(!m_env.Create(m_symbol.Name(),m_period,m_ma_period,m_ma_shift,m_ma_method,m_ma_applied,m_deviation)) { printf(__FUNCTION__+": error initializing object"); return(false); } //--- ok return(true); } //+------------------------------------------------------------------+ //| "Voting" that price will grow. | //+------------------------------------------------------------------+ int CSignalEnvelopes::LongCondition(void) { int result=0; int idx =StartIndex(); double close=Close(idx); double upper=Upper(idx); double lower=Lower(idx); double width=upper-lower; //--- if the model 0 is used and price is in the rollback zone, then there is a condition for buying if(IS_PATTERN_USAGE(0) && close<lower+m_limit_in*width && close>lower-m_limit_out*width) result=m_pattern_0; //--- if the model 1 is used and price is above the rollback zone, then there is a condition for buying if(IS_PATTERN_USAGE(1) && close>upper+m_limit_out*width) result=m_pattern_1; //--- return the result return(result); } //+------------------------------------------------------------------+ //| "Voting" that price will fall. | //+------------------------------------------------------------------+ int CSignalEnvelopes::ShortCondition(void) { int result =0; int idx =StartIndex(); double close=Close(idx); double upper=Upper(idx); double lower=Lower(idx); double width=upper-lower; //--- if the model 0 is used and price is in the rollback zone, then there is a condition for selling if(IS_PATTERN_USAGE(0) && close>upper-m_limit_in*width && close<upper+m_limit_out*width) result=m_pattern_0; //--- if the model 1 is used and price is above the rollback zone, then there is a condition for selling if(IS_PATTERN_USAGE(1) && close<lower-m_limit_out*width) result=m_pattern_1; //--- return the result return(result); } //+------------------------------------------------------------------+
Ora, lavoreremo sulle modifiche di alcune parti del codice.
Per evitare confusione, il codice modificato verrà evidenziato:
//+------------------------------------------------------------------+
//| MySignal.mqh |
//| Copyright © 2013, Vladimir Karputov |
//| http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
Il codice modificato è il codice che deve essere copiato e incollato nel generatore di segnali di trading. Spero che tale evidenziazione ti aiuti a capire meglio il codice.
Poiché stiamo scrivendo la nostra classe del generatore di segnali di trading, il suo nome dovrebbe essere diverso dal nome della classe base. Sostituiamo quindi CSignalEnvelopes con CMySignalEnvelopes in tutto il codice:
Fig. 12. Ridenominazione della classe
Per assicurarsi che la classe del generatore di segnali di trading venga visualizzata nella procedura guidata MQL5 sotto il suo nome, modificare il nome della classe nel blocco di descrizione
//| Title=Signals of indicator 'Envelopes' |
a
//| Title=Signals of indicator 'MySignalEnvelopes' |
Modificare il valore del periodo MA
//| Parameter=PeriodMA,int,45,Period of averaging |
a 13 (questo è solo il mio suggerimento, puoi impostare qualsiasi valore tu preferisca)
//| Parameter=PeriodMA,int,13,Period of averaging |
Inoltre, modifichiamo anche il parametro Deviazione
//| Parameter=Deviation,double,0.15,Deviation |
impostando un valore maggiore
//| Parameter=Deviation,double,1.15,Deviation |
Secondo la nostra logica di implementazione, dobbiamo dichiarare una variabile interna che memorizzerà il puntatore al segnale principale.
Poiché questa deve essere una variabile interna (solo nell'ambito della classe del generatore di segnali di trading), verrà aggiunta al seguente blocco di codice:
protected: CiEnvelopes m_env; // object-indicator //--- adjusted parameters int m_ma_period; // the "period of averaging" parameter of the indicator int m_ma_shift; // the "time shift" parameter of the indicator ENUM_MA_METHOD m_ma_method; // the "method of averaging" parameter of the indicator ENUM_APPLIED_PRICE m_ma_applied; // the "object of averaging" parameter of the indicator double m_deviation; // the "deviation" parameter of the indicator //--- "weights" of market models (0-100) int m_pattern_0; // model 0 CExpertSignal *m_signal; // storing the pointer to the main signal
Si prega inoltre di notare che ho eliminato le variabili non necessarie dal codice.
Il metodo per memorizzare il puntatore al segnale principale verrà dichiarato in un altro blocco di codice - il "metodo di impostazione del puntatore sul segnale principale". Qui, ho anche eliminato alcuni metodi irrilevanti.
public: CMySignalEnvelopes(void); ~CMySignalEnvelopes(void); //--- methods of setting adjustable parameters void PeriodMA(int value) { m_ma_period=value; } void Shift(int value) { m_ma_shift=value; } void Method(ENUM_MA_METHOD value) { m_ma_method=value; } void Applied(ENUM_APPLIED_PRICE value) { m_ma_applied=value; } void Deviation(double value) { m_deviation=value; } //--- methods of adjusting "weights" of market models void Pattern_0(int value) { m_pattern_0=value; } //--- method of verification of settings virtual bool ValidationSettings(void); //--- method of creating the indicator and timeseries virtual bool InitIndicators(CIndicators *indicators); //--- methods of checking if the market models are formed virtual int LongCondition(void); virtual int ShortCondition(void); //--- method of setting the pointer to the main signal virtual bool InitSignal(CExpertSignal *signal=NULL);
Specifichiamo ora alcuni parametri modificati nel costruttore ed eliminiamo le variabili che non sono più necessarie:
//+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ CMySignalEnvelopes::CMySignalEnvelopes(void) : m_ma_period(13), m_ma_shift(0), m_ma_method(MODE_SMA), m_ma_applied(PRICE_CLOSE), m_deviation(1.15), m_pattern_0(50)
A questo punto, possiamo procedere a modificare la logica di generazione del segnale di trading in base al nostro sistema di trading.
Il blocco di codice responsabile di un segnale di acquisto:
int CMySignalEnvelopes::LongCondition(void) { int result=0; int idx =StartIndex(); double close=Close(idx); double upper=Upper(idx); double lower=Lower(idx); double width=upper-lower; //--- if the model 0 is used and price is in the rollback zone, then there is a condition for buying if(IS_PATTERN_USAGE(0) && close<lower+m_limit_in*width && close>lower-m_limit_out*width) result=m_pattern_0; //--- if the model 1 is used and price is above the rollback zone, then there is a condition for buying if(IS_PATTERN_USAGE(1) && close>upper+m_limit_out*width) result=m_pattern_1; //--- return the result return(result); }
sarà come mostrato di seguito, a seguito delle modifiche necessarie:
int CMySignalEnvelopes::LongCondition(void) //---buy
{
int result=0;
int idx =StartIndex();
double open=Open(idx);
double close=Close(idx);
double prlevel;
if(IS_PATTERN_USAGE(0) && close<open)
{
prlevel=GetPriceLevelStopp(open,Open(0));
m_signal.PriceLevel(prlevel);
result=m_pattern_0;
}
//--- return the result
return(result);
}
Il blocco di codice responsabile di un segnale di vendita:
int CMySignalEnvelopes::ShortCondition(void) { int result =0; int idx =StartIndex(); double close=Close(idx); double upper=Upper(idx); double lower=Lower(idx); double width=upper-lower; //--- if the model 0 is used and price is in the rollback zone, then there is a condition for selling if(IS_PATTERN_USAGE(0) && close>upper-m_limit_in*width && close<upper+m_limit_out*width) result=m_pattern_0; //--- if the model 1 is used and price is above the rollback zone, then there is a condition for selling if(IS_PATTERN_USAGE(1) && close<lower-m_limit_out*width) result=m_pattern_1; //--- return the result return(result); }
sarà come mostrato di seguito, a seguito delle modifiche necessarie:
int CMySignalEnvelopes::ShortCondition(void) //---sell
{
int result =0;
int idx =StartIndex();
double open=Open(idx);
double close=Close(idx);
double prlevel;
if(IS_PATTERN_USAGE(0) && close>open)
{
prlevel=GetPriceLevelStopp(Open(0),open);
m_signal.PriceLevel(prlevel);
result=m_pattern_0;
}
//--- return the result
return(result);
}
8. Alcuni commenti sul blocco del codice del segnale
Se viene soddisfatta la condizione richiesta per un determinato segnale, chiamiamo il metodo GetPriceLevelStopp che restituisce un numero come "20" o "15" - il valore della distanza dal prezzo corrente.
Questo è seguito dalla chiamata al metodo PriceLevel dell'oggetto m_signal (che imposta la distanza per determinare il prezzo a livello di ordine pendente). Va ricordato che m_signal è l'oggetto classe CExpertSignal che memorizza il puntatore al segnale principale.
Il codice del metodo GetPriceLevelStopp è fornito di seguito:
double CMySignalEnvelopes::GetPriceLevelStopp(double price_0,double min)
{
double level;
double temp;
temp-=(price_0-min)/PriceLevelUnit();
level=NormalizeDouble(temp,0);
return(level);
}
Dobbiamo dichiarare questo metodo nell'intestazione della classe:
protected: //--- method of initialization of the indicator bool InitMA(CIndicators *indicators); //--- methods of getting data double Upper(int ind) { return(m_env.Upper(ind)); } double Lower(int ind) { return(m_env.Lower(ind)); } double GetPriceLevelStopp(double price,double min); };
Un altro metodo di cui avremo bisogno è il metodo di passaggio del puntatore al segnale principale alla variabile interna:
bool CMySignalEnvelopes::InitSignal(CExpertSignal *signal)
{
m_signal=signal;
return(true);
}
Dopodiché dovremmo creare un Expert Advisor nella procedura guidata MQL5 e includere in esso il modulo di segnale 'MySignalEnvelopes'.
È inoltre necessario aggiungere la chiamata al metodo InitSignal al codice di Expert Advisor generato utilizzando la procedura guidata MQL5:
//--- Set filter parameters filter0.PeriodMA(Signal_Envelopes_PeriodMA); filter0.Shift(Signal_Envelopes_Shift); filter0.Method(Signal_Envelopes_Method); filter0.Applied(Signal_Envelopes_Applied); filter0.Deviation(Signal_Envelopes_Deviation); filter0.Weight(Signal_Envelopes_Weight); filter0.InitSignal(signal); //...
Per una migliore visualizzazione del funzionamento dell'Expert Advisor, ho fornito un breve video:
Il codice di Expert Advisor generato utilizzando la procedura guidata MQL5, così come il codice del modulo di segnale, è allegato all'articolo.
Di seguito puoi vedere i risultati dei test dell'Expert Advisor. È stato testato per EURUSD e USDJPY con i seguenti parametri: periodo di test 2013.01.01 - 2013.09.01, intervallo di tempo - D1, livello di Stop Loss = 85, livello di Take Profit = 195.
Fig. 13. Test per EURUSD su D1
Fig. 14. Test per USDJPY su D1
Conclusione
Abbiamo appena visto come possiamo modificare il codice del modulo del segnale di trading per l'implementazione della funzionalità che ci consente di impostare gli ordini pendenti a qualsiasi distanza dal prezzo corrente: può essere il prezzo di chiusura o apertura della barra precedente o il valore della media mobile. Ci sono molte opzioni. Importante è che è possibile impostare qualsiasi prezzo di apertura per un ordine pendente.
L'articolo ha dimostrato come possiamo accedere al puntatore al segnale principale, e quindi ai metodi della classe CExpertSignal. Credo che l'articolo si rivelerà utile per i trader che commerciano con ordini pendenti.
Tradotto dal russo da MetaQuotes Ltd.
Articolo originale: https://www.mql5.com/ru/articles/723





- 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