Ich verstehe nicht ganz, warum es unmöglich ist, diese CPU-Last-Lags zu umgehen. Wahrscheinlich ist er dazu nicht in der Lage.
Im Folgenden finden Sie jedoch einen sauberen Test, der das Problem der Relevanz von Preisdaten im MT5 zeigt. Ich habe den Code mit Kommentaren versehen. Kurz gesagt, die Ticks werden über SymbolInfoTick/stack entnommen und gegeneinander geprüft. Insbesondere, um Lücken und große Verzögerungen zwischen identischen Ticks aus verschiedenen Quellen zu vermeiden.
// Демонстрация лагов 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); // Вывод всех записей.
}
Ergebnis (nur ein MT5-b2656 läuft auf dem Rechner, CPU-Last um Null, ein Chart, Tester nicht verwendet).
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.
Wenn die CPU überlastet ist (z.B. Optimize nicht einmal auf allen Kernen), kann SymbolInfoTick bis zu zehn Millisekunden brauchen, um fertig zu werden. Es gibt keine Antwort darauf, warum diese beliebteste Funktion des Terminals nicht regelmäßig einen Snapshot macht. Wenn möglich, machen Sie Schnappschüsse davon. Und vergessen Sie nicht, dass die OnTick-Funktion selbst bei Null-CPU-Last einige Dutzend Millisekunden später arbeiten kann als ein Tick, der am Terminal ankommt.
Alles in allem ziemlich traurig, aber das kann diejenigen nicht beunruhigen, die primitiv handeln.
Die SymbolInfoTick-Bremsen sind geschlossen. Das Ergebnis ist folgendes.
Wenn die CPU überlastet ist (z.B. Optimize nicht einmal auf allen Kernen), kann SymbolInfoTick bis zu zehn Millisekunden brauchen, um fertig zu werden. Es gibt keine Antwort darauf, warum diese beliebteste Funktion des Terminals nicht regelmäßig einen Snapshot macht. Wenn möglich, machen Sie Schnappschüsse davon. Und vergessen Sie nicht, dass die OnTick-Funktion selbst bei Null-CPU-Last einige Dutzend Millisekunden später arbeiten kann als ein Tick, der am Terminal ankommt.
Alles in allem recht bedauerlich, aber das kann diejenigen, die primitiv handeln, nicht stören.
Für diejenigen, die "nicht primitiv" handeln: Die Hardware muss der Aufgabe gewachsen sein.
"nicht einmal auf allen Kernen" - sprechen Sie von "6/8"? d.h. 6 Prozesse, und jeder von ihnen belastet einen CPU-Kern für die Dauer des Tests zu 100%? Und es gibt nur 4 physische Kerne? Und sind Sie wirklich überrascht, dass der Test vor einem solchen Hintergrund "hinkt"?
Wenn dies tatsächlich Ihr Verständnis ist, dann: "Lernen, lernen und nochmals lernen".
Wenn Sie eine CPU mit 16-20 Threads vergewaltigen wollen, sollten Sie eine CPU mit mindestens 20 physischen Kernen kaufen.
Für diejenigen, die "nicht primitiv" handeln: Die Hardware muss der Aufgabe gewachsen sein.
"nicht einmal auf allen Kernen" - sprechen Sie von "6/8"? Ich meine 6 Prozesse, und jeder von ihnen belastet einen CPU-Kern während der gesamten Testzeit zu 100%? Und es gibt nur 4 physische Kerne? Und sind Sie wirklich überrascht, dass der Test auf einem solchen Hintergrund "hinkt"?
Wenn dies tatsächlich Ihr Verständnis ist, dann: "Lernen, lernen und nochmals lernen".
Wenn Sie eine CPU mit 16-20 Threads vergewaltigen wollen, kaufen Sie eine CPU mit mindestens 20 physischen Kernen.
Ich bin sicher, dass ich beweisen kann, dass Ihre aktuellen Preise sehr langsam umgesetzt werden. Die CPU-Belastung verursacht eine solche Trägheit nur wegen der falschen Implementierung der wichtigsten Funktion in MQL5.
Ich bin sicher, dass ich beweisen kann, dass Ihre Umsetzung der aktuellen Preise sehr langsam ist. Die CPU-Belastung erzeugt nur solche Verlangsamungen, die durch die fehlerhafte Implementierung der Hauptfunktion in MQL5 entstehen.
Test-Code:
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");
}
Wie macht man das?
Die Bremsen wurden nur dann reproduziert, wenn 6/8 Agenten im Einsatz waren.
Die Bremsen wurden nur dann reproduziert, wenn 6/8 Agenten im Einsatz waren.
D.h. Problem, wenn die CPU belastet wird.
MQ-Demo, 20 Karten, b2656. Auf dem Rechner läuft nur das Terminal, der Tester ist nicht aktiv.
Die Bremsen wurden nur dann reproduziert, wenn 6/8 Agenten im Einsatz waren.
Das heißt, das Problem tritt auf, wenn die CPU belastet wird.
Ist diese Information für Sie neu?
Ist diese Information für Sie neu?
Ich verstehe nicht ganz, warum es unmöglich ist, diese CPU-Last-Lags zu umgehen. Wahrscheinlich ist er dazu nicht in der Lage.
Im Folgenden finden Sie jedoch einen sauberen Test, der das Problem der Relevanz von Preisdaten im MT5 zeigt. Ich habe den Code mit Kommentaren versehen. Kurz gesagt, die Ticks werden über SymbolInfoTick/stack entnommen und gegeneinander geprüft. Insbesondere, um Lücken und große Verzögerungen zwischen identischen Ticks aus verschiedenen Quellen zu vermeiden.
Ergebnis (nur ein MT5-b2656 läuft auf dem Rechner, CPU-Last um Null, ein Chart, Tester nicht verwendet).
Bitte bestätigen Sie die Wiedergabe.
Zwischensumme für eine schnell entladene Maschine.
Frage an die Entwickler.
Angenommen, SymbolInfoTick wurde 5 ms lang ausgeführt. Entspricht der Tick der aktuellen Zeit oder der 5 ms davor?
Die SymbolInfoTick-Bremsen sind geschlossen. Das Ergebnis ist folgendes.
Wenn die CPU überlastet ist (z.B. Optimize nicht einmal auf allen Kernen), kann SymbolInfoTick bis zu zehn Millisekunden brauchen, um fertig zu werden. Es gibt keine Antwort darauf, warum diese beliebteste Funktion des Terminals nicht regelmäßig einen Snapshot macht. Wenn möglich, machen Sie Schnappschüsse davon. Und vergessen Sie nicht, dass die OnTick-Funktion selbst bei Null-CPU-Last einige Dutzend Millisekunden später arbeiten kann als ein Tick, der am Terminal ankommt.
Alles in allem ziemlich traurig, aber das kann diejenigen nicht beunruhigen, die primitiv handeln.
Die SymbolInfoTick-Bremsen sind geschlossen. Das Ergebnis ist folgendes.
Wenn die CPU überlastet ist (z.B. Optimize nicht einmal auf allen Kernen), kann SymbolInfoTick bis zu zehn Millisekunden brauchen, um fertig zu werden. Es gibt keine Antwort darauf, warum diese beliebteste Funktion des Terminals nicht regelmäßig einen Snapshot macht. Wenn möglich, machen Sie Schnappschüsse davon. Und vergessen Sie nicht, dass die OnTick-Funktion selbst bei Null-CPU-Last einige Dutzend Millisekunden später arbeiten kann als ein Tick, der am Terminal ankommt.
Alles in allem recht bedauerlich, aber das kann diejenigen, die primitiv handeln, nicht stören.
Für diejenigen, die "nicht primitiv" handeln: Die Hardware muss der Aufgabe gewachsen sein.
"nicht einmal auf allen Kernen" - sprechen Sie von "6/8"? d.h. 6 Prozesse, und jeder von ihnen belastet einen CPU-Kern für die Dauer des Tests zu 100%? Und es gibt nur 4 physische Kerne? Und sind Sie wirklich überrascht, dass der Test vor einem solchen Hintergrund "hinkt"?
Wenn dies tatsächlich Ihr Verständnis ist, dann: "Lernen, lernen und nochmals lernen".
Wenn Sie eine CPU mit 16-20 Threads vergewaltigen wollen, sollten Sie eine CPU mit mindestens 20 physischen Kernen kaufen.
Für diejenigen, die "nicht primitiv" handeln: Die Hardware muss der Aufgabe gewachsen sein.
"nicht einmal auf allen Kernen" - sprechen Sie von "6/8"? Ich meine 6 Prozesse, und jeder von ihnen belastet einen CPU-Kern während der gesamten Testzeit zu 100%? Und es gibt nur 4 physische Kerne? Und sind Sie wirklich überrascht, dass der Test auf einem solchen Hintergrund "hinkt"?
Wenn dies tatsächlich Ihr Verständnis ist, dann: "Lernen, lernen und nochmals lernen".
Wenn Sie eine CPU mit 16-20 Threads vergewaltigen wollen, kaufen Sie eine CPU mit mindestens 20 physischen Kernen.
Ich bin sicher, dass ich beweisen kann, dass Ihre aktuellen Preise sehr langsam umgesetzt werden. Die CPU-Belastung verursacht eine solche Trägheit nur wegen der falschen Implementierung der wichtigsten Funktion in MQL5.
Ich bin sicher, dass ich beweisen kann, dass Ihre Umsetzung der aktuellen Preise sehr langsam ist. Die CPU-Belastung erzeugt nur solche Verlangsamungen, die durch die fehlerhafte Implementierung der Hauptfunktion in MQL5 entstehen.
Test-Code:
Beweisen Sie es.