Non capisco bene perché sia impossibile aggirare questi ritardi di carico della CPU. Probabilmente è incompetente a farlo.
Tuttavia, di seguito è riportato un test pulito che mostra il problema della rilevanza dei dati di prezzo in MT5. Ho fornito il codice con i commenti. In breve, i tick sono presi tramite SymbolInfoTick/stack e controllati tra loro. In particolare, per evitare lacune e grandi ritardi tra tick identici provenienti da fonti diverse.
// Демонстрация лагов OnTick и OnBookEvent.inputuint inMinInterval = 1000; // Минимальное время (в мкс.) лага// Структура тика, которую удобно будет выводить в ArrayPrint.struct PRICE
{
double bid;
double ask;
bool onTick; // true - источник OnTick+SymbolInfoTick, false - источник OnBookEvent+MarketBookGetulong Interval; // Временной интервал между соседними записями.void Set( constdouble &dBid, constdouble &dAsk, constbool bTick )
{
staticulong PrevTime = ::GetMicrosecondCount();
constulong NewTime = ::GetMicrosecondCount();
this.bid = dBid;
this.ask = dAsk;
this.onTick = bTick;
this.Interval = NewTime - PrevTime;
PrevTime = NewTime;
}
// Записи одинаковые, если обе соответствующие цены совпадают.booloperator ==( const PRICE &Price ) const
{
return((this.bid == Price.bid) && (this.ask == Price.ask));
}
};
PRICE Prices[1000]; // Массив для записи тиков из разных источников.int Amount = 0; // Количество записанных тиков// Возвращает bid/ask-цены из стакана.bool GetCurrentPrices( double &bid, double &ask )
{
MqlBookInfo Bands[];
constbool Res = MarketBookGet(_Symbol, Bands);
if (Res)
for (int i = ArraySize(Bands) - 2; i >= 0; i--)
if (Bands[i].type == BOOK_TYPE_SELL)
{
ask = Bands[i].price;
bid = Bands[i + 1].price;
break;
}
return(Res);
}
// Если bid или ask стакана поменялся - записываем их.bool SaveNewTick_Book()
{
staticdouble PrevBid = 0;
staticdouble PrevAsk = 0;
double bid;
double ask;
constbool Res = !IsStopped() && GetCurrentPrices(bid, ask) && ((PrevBid != bid) || (PrevAsk != ask));
if (Res)
{
PrevBid = bid;
PrevAsk = ask;
Prices[Amount++].Set(bid, ask, false);
if (Amount == ArraySize(Prices)) // Если достигли конца массива - выходим.ExpertRemove();
}
return(Res);
}
// Записываем bid и askbool SaveNewTick_Tick()
{
MqlTick Tick;
constbool Res = !IsStopped() && SymbolInfoTick(_Symbol, Tick);
if (Res)
{
Prices[Amount++].Set(Tick.bid, Tick.ask, true);
if (Amount == ArraySize(Prices)) // Если достигли конца массива - выходим.ExpertRemove();
}
return(Res);
}
// Проверка на наличие багов и задержек.void Check()
{
if (Amount > 3)
{
if ((Prices[Amount - 1].onTick == Prices[Amount - 2].onTick) && // Три подряд записи из одного источника - баг.
(Prices[Amount - 2].onTick == Prices[Amount - 3].onTick))
Alert("BUG!");
elseif ((Prices[Amount - 1] == Prices[Amount - 2]) && // Если цены подряд идущих записей совпадают
(Prices[Amount - 1].Interval > inMinInterval)) // И временной интервал между ними большой - информируем.
{
Alert((Prices[Amount - 1].onTick ? "OnTick-lag! - " : "OnBook-lag! - ") + (string)Prices[Amount - 1].Interval + " mcs.");
ArrayPrint(Prices, _Digits, NULL, Amount - 4, 4); // Выводим подробно проблему.
}
}
}
intOnInit()
{
return(!MarketBookAdd(_Symbol)); // Подписались на стакан.
}
voidOnBookEvent( conststring &Symb )
{
if ((Symb == _Symbol) && SaveNewTick_Book()) // Если записали новые цены из стакана,
Check(); // проверяем.
}
voidOnTick()
{
if (SaveNewTick_Tick()) // Если записали цены тика,
Check(); // проверяем.
}
voidOnDeinit( constint )
{
MarketBookRelease(_Symbol); // Отписались от стакана.ArrayPrint(Prices, _Digits, NULL, 0, Amount); // Вывод всех записей.
}
Risultato (solo un MT5-b2656 in esecuzione sulla macchina, carico della CPU intorno a zero, un grafico, Tester non utilizzato).
2020.10.2012:26:19.680 Test9 (AUDCAD,H1) Alert: OnTick-lag! - 9573 mcs.
2020.10.2012:26:19.680 Test9 (AUDCAD,H1) [bid] [ask] [onTick] [Interval]
2020.10.2012:26:19.680 Test9 (AUDCAD,H1) [0] 0.927770.92780true764782020.10.2012:26:19.680 Test9 (AUDCAD,H1) [1] 0.927770.92780false642020.10.2012:26:19.680 Test9 (AUDCAD,H1) [2] 0.927770.92781false505522020.10.2012:26:19.680 Test9 (AUDCAD,H1) [3] 0.927770.92781true9573// В OnTick пришел тик на 9 мс позже, чем он был в стакане.
...
2020.10.2012:26:33.899 Test9 (AUDCAD,H1) Alert: OnBook-lag! - 22153 mcs.
2020.10.2012:26:33.899 Test9 (AUDCAD,H1) [bid] [ask] [onTick] [Interval]
2020.10.2012:26:33.899 Test9 (AUDCAD,H1) [0] 0.927760.92783true3584032020.10.2012:26:33.899 Test9 (AUDCAD,H1) [1] 0.927760.92783false23612020.10.2012:26:33.899 Test9 (AUDCAD,H1) [2] 0.927760.92784true22155062020.10.2012:26:33.899 Test9 (AUDCAD,H1) [3] 0.927760.92784false22153// В стакан пришел тик на 22 мс позже, чем он был в OnTick.
I freni di SymbolInfoTick sono chiusi. Il risultato è questo.
Se la CPU è sovraccarica (come Optimize non anche su tutti i core), SymbolInfoTick può richiedere fino a decine di millisecondi per essere completato. Non c'è una risposta al perché questa funzione più popolare del Terminale non scatti regolarmente. Se possibile, fate delle istantanee. E non dimenticate che anche a carico zero della CPU la funzione OnTick può funzionare decine di millisecondi dopo un tick che arriva al terminale.
Tutto sommato, abbastanza triste, ma non può preoccupare chi commercia in modo primitivo.
I freni di SymbolInfoTick sono chiusi. Il risultato è questo.
Se la CPU è sovraccarica (come Optimize non anche su tutti i core), SymbolInfoTick può richiedere fino a decine di millisecondi per essere completato. Non c'è una risposta al perché questa funzione più popolare del Terminale non scatti regolarmente. Se possibile, fate delle istantanee. E non dimenticate che anche a carico zero della CPU la funzione OnTick può funzionare decine di millisecondi dopo un tick che arriva al terminale.
Tutto sommato, abbastanza sfortunato, ma non può infastidire coloro che commerciano in modo primitivo.
Per chi commercia "non primitivo": l'hardware deve essere all'altezza del compito.
"non anche su tutti i core" - stai parlando di "6/8"? cioè 6 processi, e ognuno di loro carica al 100% un core della CPU per la durata del test? E ci sono solo 4 core fisici? E sinceramente sorpreso che su tale sfondo il test "ritardi"?
Se questo è davvero il suo livello di comprensione, allora: "Impara, impara e impara ancora".
Se volete violentare la CPU con 16-20 threads - comprate una CPU con 20 core fisici almeno.
Per chi commercia "non primitivo": l'hardware deve essere all'altezza del compito.
"non anche su tutti i core" - stai parlando di "6/8"? Voglio dire 6 processi, e ognuno di loro carica al 100% un core della CPU per tutto il tempo del test? E ci sono solo 4 core fisici? E sinceramente sorpreso che su tale sfondo il test "ritardi"?
Se questo è davvero il suo livello di comprensione, allora: "Impara, impara e impara ancora".
Se volete violentare la CPU con 16-20 threads - comprate una CPU con 20 core fisici almeno.
Sono sicuro di poter dimostrare che ottenere i vostri prezzi attuali viene attuato molto lentamente. Il carico della CPU crea tale lentezza solo a causa di una scorretta implementazione della funzione più importante in MQL5.
Sono sicuro di poter dimostrare che la tua implementazione per ottenere i prezzi attuali è molto lenta. Il carico della CPU crea solo tali rallentamenti a causa della scorretta implementazione della funzione principale in MQL5.
Codice di prova:
voidOnTick()
{
MqlTick Tick;
ulong gstart=GetMicrosecondCount();
int count=10000;
for(int i=0; i<count; i++)
{
SymbolInfoTick(_Symbol, Tick);
}
ulong gend=GetMicrosecondCount()-gstart;
Print(count," iterations, total time ", DoubleToString(gend/1000.0,3)," ms; avr time: ",DoubleToString(gend/1000.0/count,3)," ms");
}
Come si fa?
Ha solo riprodotto i freni quando 6/8 agenti erano in funzione.
Ha solo riprodotto i freni quando 6/8 agenti erano in funzione.
Cioè il problema quando la CPU viene caricata.
MQ-Demo, 20 grafici, b2656. Solo Terminal è in esecuzione sulla macchina, Tester non è in esecuzione.
Ha solo riprodotto i freni quando 6/8 agenti erano in funzione.
Cioè il problema è quando la CPU viene caricata.
È un'informazione nuova per te?
È un'informazione nuova per te?
Non capisco bene perché sia impossibile aggirare questi ritardi di carico della CPU. Probabilmente è incompetente a farlo.
Tuttavia, di seguito è riportato un test pulito che mostra il problema della rilevanza dei dati di prezzo in MT5. Ho fornito il codice con i commenti. In breve, i tick sono presi tramite SymbolInfoTick/stack e controllati tra loro. In particolare, per evitare lacune e grandi ritardi tra tick identici provenienti da fonti diverse.
Risultato (solo un MT5-b2656 in esecuzione sulla macchina, carico della CPU intorno a zero, un grafico, Tester non utilizzato).
Si prega di confermare la riproduzione.
Un totale intermedio per una macchina che si scarica velocemente.
Domanda agli sviluppatori.
Supponiamo che SymbolInfoTick sia stato eseguito per 5 ms. Il tick corrisponderà all'ora corrente o a 5 ms prima?
I freni di SymbolInfoTick sono chiusi. Il risultato è questo.
Se la CPU è sovraccarica (come Optimize non anche su tutti i core), SymbolInfoTick può richiedere fino a decine di millisecondi per essere completato. Non c'è una risposta al perché questa funzione più popolare del Terminale non scatti regolarmente. Se possibile, fate delle istantanee. E non dimenticate che anche a carico zero della CPU la funzione OnTick può funzionare decine di millisecondi dopo un tick che arriva al terminale.
Tutto sommato, abbastanza triste, ma non può preoccupare chi commercia in modo primitivo.
I freni di SymbolInfoTick sono chiusi. Il risultato è questo.
Se la CPU è sovraccarica (come Optimize non anche su tutti i core), SymbolInfoTick può richiedere fino a decine di millisecondi per essere completato. Non c'è una risposta al perché questa funzione più popolare del Terminale non scatti regolarmente. Se possibile, fate delle istantanee. E non dimenticate che anche a carico zero della CPU la funzione OnTick può funzionare decine di millisecondi dopo un tick che arriva al terminale.
Tutto sommato, abbastanza sfortunato, ma non può infastidire coloro che commerciano in modo primitivo.
Per chi commercia "non primitivo": l'hardware deve essere all'altezza del compito.
"non anche su tutti i core" - stai parlando di "6/8"? cioè 6 processi, e ognuno di loro carica al 100% un core della CPU per la durata del test? E ci sono solo 4 core fisici? E sinceramente sorpreso che su tale sfondo il test "ritardi"?
Se questo è davvero il suo livello di comprensione, allora: "Impara, impara e impara ancora".
Se volete violentare la CPU con 16-20 threads - comprate una CPU con 20 core fisici almeno.
Per chi commercia "non primitivo": l'hardware deve essere all'altezza del compito.
"non anche su tutti i core" - stai parlando di "6/8"? Voglio dire 6 processi, e ognuno di loro carica al 100% un core della CPU per tutto il tempo del test? E ci sono solo 4 core fisici? E sinceramente sorpreso che su tale sfondo il test "ritardi"?
Se questo è davvero il suo livello di comprensione, allora: "Impara, impara e impara ancora".
Se volete violentare la CPU con 16-20 threads - comprate una CPU con 20 core fisici almeno.
Sono sicuro di poter dimostrare che ottenere i vostri prezzi attuali viene attuato molto lentamente. Il carico della CPU crea tale lentezza solo a causa di una scorretta implementazione della funzione più importante in MQL5.
Sono sicuro di poter dimostrare che la tua implementazione per ottenere i prezzi attuali è molto lenta. Il carico della CPU crea solo tali rallentamenti a causa della scorretta implementazione della funzione principale in MQL5.
Codice di prova:
Provalo.