Dal registro sopra non sembra che ci sia un contatore?
Puoi vedere dal log qui sopra che un EA non cancella l'altro. Ma come viene attuato - attraverso il contatore o qualcos'altro - non è chiaro. Inoltre, il programmatore ha avuto un indicatore e un Expert Advisor. Ma l'indicatore ha la sgradevole caratteristica di confondere l'ordine di inizio di OnInit() e OnDeinit(). Anche se non dovrebbe confondere il contatore, se ne ha davvero uno.
Puoi vedere dal log qui sopra che un EA non cancella l'altro. Ma come viene attuato - attraverso il contatore o qualcos'altro - non è chiaro. Inoltre, il programmatore ha un indicatore e un Expert Advisor. Ma l'indicatore ha la fastidiosa caratteristica di confondere l'ordine di avvio di OnInit() e OnDeinit().
Pertanto, abbiamo implementato la variabile is_book per evitare confusione.
Gli sviluppatori hanno reso MarketBookAdd() una FUNZIONE per una ragione.
Il registro non è nulla quando si utilizza una situazione diversa da quella in cui si verifica il problema.
Prendete 2 dei vostri programmi (Expert Advisor e un indicatore, o 2 indulatori) - metteteli sullo stesso grafico e poi cancellatene uno. L'abbonamento dell'istanza rimanente cadrà.
Anche quando la sequenza di chiamate OnInit/OnDeinit è corretta (è sempre stata corretta in questi test), c'è un problema.
Non l'ho ancora eseguito nel terminale, ma ho una domanda - in che modo spostare il codice in un wrapper di oggetti aiuta contro il "taglio delle estremità" da parte del terminale stesso (come sta succedendo ora)? Bene, un oggetto sarà creato e l'abbonamento inizierà, e poi se qualcuno chiude un altro programma con abbonamento, l'oggetto non saprà mai che non c'è più l'abbonamento.
L'ho fatto in modo semplice: confronto i timeout su OnBookEvent e OnTick. Se il timeout sul primo supera il timeout sul secondo di più di N secondi - mi reiscrivo.
Non l'ho ancora eseguito nel terminale, ma è sorta la domanda: in che modo il trasferimento del codice in un wrapper di oggetti aiuterà a "tagliare le estremità" dal terminale stesso al suo interno (come sta accadendo ora)? Bene, verrà creato un oggetto e inizierà l'abbonamento, quindi se qualcuno chiude un altro programma con un abbonamento, l'oggetto non saprà mai che l'abbonamento non esiste più.
L'ho fatto in un modo semplice: confronto i timeout per OnBookEvent e OnTick. Se il primo timeout supera il secondo timeout di più di N secondi, mi abbono di nuovo.
Ebbene, come previsto, ti sbagli.
1° indicatore
//+------------------------------------------------------------------+//| Test_ind_1.mq5 |//| Copyright 2018 prostotrader |//| https://www.mql5.com |//+------------------------------------------------------------------+#property copyright"Copyright 2018 prostotrader"#property link"https://www.mql5.com"#property version"1.00"#define on_call - 111#property indicator_separate_windowbool is_book = false ;
double Buff[];
int event_cnt = 0 ;
#property indicator_buffers1#property indicator_plots1//--- plot Label1#property indicator_label1"Test_1"#property indicator_type1DRAW_LINE#property indicator_color1clrAqua#property indicator_style1STYLE_SOLID#property indicator_width11//+------------------------------------------------------------------+//| Custom indicator initialization function |//+------------------------------------------------------------------+intOnInit ()
{
//--- Set buffers IndicatorSetInteger ( INDICATOR_DIGITS , 0 );
IndicatorSetString ( INDICATOR_SHORTNAME , "Test_ind_1" );
//---Set buffersSetIndexBuffer ( 0 ,Buff, INDICATOR_DATA );
PlotIndexSetDouble ( 0 , PLOT_EMPTY_VALUE , EMPTY_VALUE );
ArraySetAsSeries (Buff, true );
is_book = MarketBookAdd ( Symbol ());
if (is_book == true )
{
Print ( __FUNCTION__ , ": Подписка на стакан добавлена. Символ " , Symbol ());
}
//---return ( INIT_SUCCEEDED );
}
//+------------------------------------------------------------------+//| Expert deinitialization function |//+------------------------------------------------------------------+voidOnDeinit ( constint reason)
{
if (is_book == true )
{
MarketBookRelease ( Symbol ());
Print ( __FUNCTION__ , ": Подписка на стакан удалена. Символ " , Symbol ());
}
}
//+------------------------------------------------------------------+//| Custom indicator iteration function |//+------------------------------------------------------------------+intOnCalculate ( constint rates_total,
constint prev_calculated,
constint begin,
constdouble &price[])
{
if (prev_calculated == 0 )
{
ArrayInitialize (Buff, EMPTY_VALUE );
}
Buff[ 0 ] = 2 ;
//--- return value of prev_calculated for next call
event_cnt = rates_total;
return (rates_total);
}
//+------------------------------------------------------------------+//| BookEvent function |//+------------------------------------------------------------------+voidOnBookEvent ( conststring &symbol)
{
if (symbol == Symbol ())
{
Print ( __FUNCTION__ , ": Подписка работает. Символ " , symbol);
double price[];
OnCalculate (event_cnt,event_cnt,on_call,price);
}
}
//+------------------------------------------------------------------+
Secondo indicatore
//+------------------------------------------------------------------+//| Test_ind_1.mq5 |//| Copyright 2018 prostotrader |//| https://www.mql5.com |//+------------------------------------------------------------------+#property copyright"Copyright 2018 prostotrader"#property link"https://www.mql5.com"#property version"1.00"#define on_call - 111#property indicator_separate_windowbool is_book = false ;
double Buff[];
int event_cnt = 0 ;
#property indicator_buffers1#property indicator_plots1//--- plot Label1#property indicator_label1"Test_2"#property indicator_type1DRAW_LINE#property indicator_color1clrLime#property indicator_style1STYLE_SOLID#property indicator_width11//+------------------------------------------------------------------+//| Custom indicator initialization function |//+------------------------------------------------------------------+intOnInit ()
{
//--- Set buffers IndicatorSetInteger ( INDICATOR_DIGITS , 0 );
IndicatorSetString ( INDICATOR_SHORTNAME , "Test_ind_2" );
//---Set buffersSetIndexBuffer ( 0 ,Buff, INDICATOR_DATA );
PlotIndexSetDouble ( 0 , PLOT_EMPTY_VALUE , EMPTY_VALUE );
ArraySetAsSeries (Buff, true );
is_book = MarketBookAdd ( Symbol ());
if (is_book == true )
{
Print ( __FUNCTION__ , ": Подписка 2 на стакан добавлена. Символ " , Symbol ());
}
//---return ( INIT_SUCCEEDED );
}
//+------------------------------------------------------------------+//| Expert deinitialization function |//+------------------------------------------------------------------+voidOnDeinit ( constint reason)
{
if (is_book == true )
{
MarketBookRelease ( Symbol ());
Print ( __FUNCTION__ , ": Подписка 2 на стакан удалена. Символ " , Symbol ());
}
}
//+------------------------------------------------------------------+//| Custom indicator iteration function |//+------------------------------------------------------------------+intOnCalculate ( constint rates_total,
constint prev_calculated,
constint begin,
constdouble &price[])
{
if (prev_calculated == 0 )
{
ArrayInitialize (Buff, EMPTY_VALUE );
}
Buff[ 0 ] = 2 ;
//--- return value of prev_calculated for next call
event_cnt = rates_total;
return (rates_total);
}
//+------------------------------------------------------------------+//| BookEvent function |//+------------------------------------------------------------------+voidOnBookEvent ( conststring &symbol)
{
if (symbol == Symbol ())
{
Print ( __FUNCTION__ , ": Подписка 2 работает. Символ " , symbol);
double price[];
OnCalculate (event_cnt,event_cnt,on_call,price);
}
}
//+------------------------------------------------------------------+
Non l'ho ancora eseguito nel terminale, ma ho una domanda - in che modo spostare il codice in un wrapper di oggetti aiuta contro il "taglio delle estremità" da parte del terminale stesso (come sta succedendo ora)?
Init e Deinit non partecipano alla sottoscrizione. Forse questa circostanza potrebbe aiutare.
Mi piacerebbe un commento da parte degli sviluppatori, perché non c'è nulla nella documentazione su questo.
Non vedi dal registro sopra che c'è un contatore?
Dal registro sopra non sembra che ci sia un contatore?
Puoi vedere dal log qui sopra che un EA non cancella l'altro. Ma come viene attuato - attraverso il contatore o qualcos'altro - non è chiaro. Inoltre, il programmatore ha avuto un indicatore e un Expert Advisor. Ma l'indicatore ha la sgradevole caratteristica di confondere l'ordine di inizio di OnInit() e OnDeinit(). Anche se non dovrebbe confondere il contatore, se ne ha davvero uno.
Puoi vedere dal log qui sopra che un EA non cancella l'altro. Ma come viene attuato - attraverso il contatore o qualcos'altro - non è chiaro. Inoltre, il programmatore ha un indicatore e un Expert Advisor. Ma l'indicatore ha la fastidiosa caratteristica di confondere l'ordine di avvio di OnInit() e OnDeinit().
Pertanto, abbiamo implementato la variabile is_book per evitare confusione.
Gli sviluppatori hanno reso MarketBookAdd() una FUNZIONE per una ragione.
Non vedi dal registro sopra che c'è un contatore?
Il registro non è nulla quando si utilizza una situazione diversa da quella in cui si verifica il problema.
Prendete 2 dei vostri programmi (Expert Advisor e un indicatore, o 2 indulatori) - metteteli sullo stesso grafico e poi cancellatene uno. L'abbonamento dell'istanza rimanente cadrà.
Anche quando la sequenza di chiamate OnInit/OnDeinit è corretta (è sempre stata corretta in questi test), c'è un problema.
Questo approccio non funziona?
Non l'ho ancora eseguito nel terminale, ma ho una domanda - in che modo spostare il codice in un wrapper di oggetti aiuta contro il "taglio delle estremità" da parte del terminale stesso (come sta succedendo ora)? Bene, un oggetto sarà creato e l'abbonamento inizierà, e poi se qualcuno chiude un altro programma con abbonamento, l'oggetto non saprà mai che non c'è più l'abbonamento.
L'ho fatto in modo semplice: confronto i timeout su OnBookEvent e OnTick. Se il timeout sul primo supera il timeout sul secondo di più di N secondi - mi reiscrivo.
Non l'ho ancora eseguito nel terminale, ma è sorta la domanda: in che modo il trasferimento del codice in un wrapper di oggetti aiuterà a "tagliare le estremità" dal terminale stesso al suo interno (come sta accadendo ora)? Bene, verrà creato un oggetto e inizierà l'abbonamento, quindi se qualcuno chiude un altro programma con un abbonamento, l'oggetto non saprà mai che l'abbonamento non esiste più.
L'ho fatto in un modo semplice: confronto i timeout per OnBookEvent e OnTick. Se il primo timeout supera il secondo timeout di più di N secondi, mi abbono di nuovo.
Ebbene, come previsto, ti sbagli.
1° indicatore
Secondo indicatore
Risultato
Non l'ho ancora eseguito nel terminale, ma ho una domanda - in che modo spostare il codice in un wrapper di oggetti aiuta contro il "taglio delle estremità" da parte del terminale stesso (come sta succedendo ora)?
Init e Deinit non partecipano alla sottoscrizione. Forse questa circostanza potrebbe aiutare.
Ho eseguito questi indicatori in diverse finestre dello stesso simbolo e funziona bene,
ma quando ho eseguito entrambi gli indicatori nella stessa finestra di simboli, è davvero
abbonamento "caduto" durante la rimozione di un indicatore.
Scrivere alla SD (forse avranno il tempo di fare una correzione nella nuova build)
Forum sul trading, sistemi di trading automatico e test di strategie di trading
La sottoscrizione di OnBookEvent a volte cade - esiste una cosa del genere?
prostotrader, 2018.07.24 21:25