MT5 und Geschwindigkeit in Aktion - Seite 57

 
Renat Fatkhullin:

Beschleunigung um das Zehnfache bei massivem parallelem Zugriff.

In anderen Fällen werden nur Prozessor, Speicher und Betriebssystem aufgerüstet.

In PM, vergleichende Protokolle vom selben Rechner.

 
fxsaber:

Dies ist ein einmaliger Aufruf von CopyTicks. Dies geschieht, um einen virtuellen Backtest für diese Ticks in OnInit durchzuführen und ihn dann in Echtzeit fortzusetzen, wobei nur frische Ticks eingespeist werden.

Als Kompromiss schlage ich vor, den Speicher im Terminal unmittelbar nach dem Aufruf von CopyTicks in OnInit freizugeben. Dann müssen wir keine Zwangsabkühlungsfunktion für CopyTicks einführen.

Momentan ist die Sleep-Version der Kühlung sehr hinderlich. Aber ich habe oben gezeigt, wie diese Krücke Speicherplatz spart.


Jetzt stellt sich heraus, dass 20 Expert Advisors auch auf langsamen VPS schnell laufen. Aber sie zu starten ist ein ernsthaftes Problem.

Es ist noch gar nicht so lange her, da haben Sie selbst Stresstests durchgeführt und die sofortige Ausgabe von tiefen Ticks bei jedem Tick gefordert.

Das heißt, sowohl Sie als auch 100 % der anderen Entwickler haben Strategien für anstehende vollständige Cache-Anfragen angewandt und werden dies auch weiterhin tun. Es werden immer mehr und immer kostspieligere und frontalere Gutachten erstellt.

Deshalb werden wir die Caches keineswegs abschaffen, sondern empfehlen, 16-32gb Speicher einzusetzen und Probleme und Verzögerungen zu vergessen.

Verhalten und Wirtschaft auf VPS (halten Sie auf 512 mb-1 gb) wir überhaupt nicht kümmern.

 
Renat Fatkhullin:

Sie selbst haben vor nicht allzu langer Zeit Stresstests durchgeführt, und Sie verlangten sofortige tiefe Ticks bei jedem Tick.

Das heißt, sowohl Sie als auch 100 % der anderen Entwickler haben Strategien für anstehende vollständige Cache-Anfragen angewandt und werden dies auch weiterhin tun. Es werden immer mehr und immer kostspieligere und frontalere Gutachten erstellt.

Deshalb werden wir die Caches keineswegs abschaffen, sondern empfehlen, 16-32gb Speicher einzusetzen und Probleme und Verzögerungen zu vergessen.

Verhalten und Wirtschaft auf VPS (um in 512 mb-1gb passen) wir überhaupt nicht kümmern.

Oben habe ich meinen Beitrag mit Code ergänzt. Es geht um OnInit, nicht um etwas anderes. Hot CopyTicks wird dringend benötigt, aber nicht in OnInit.

 
fxsaber:

Als Kompromiss schlage ich vor, dass nach dem Aufruf von CopyTicks in OnInit der Speicher sofort im Terminal freigegeben werden sollte.

Auf jeden Fall nicht!
Und was, wenn ich im Gegenteil erhöhen Cache in OnInit, um mit ihm zu arbeiten, ohne Verzögerungen?

Es ist besser, die Funktion zum Entladen des Terminal-Caches einzuführen.
Dies ist nicht nur für Ticks, sondern auch für Zeitreihen und Indikatoren erforderlich (versuchen Sie, einen 5K für 5 Instrumente und 5 TFs zu schreiben).

@Renat?

 
Andrey Khatimlianskii:

Niemals!
Was, wenn ich den Cache in OnInit anhebe, so dass ich dann ohne Verzögerung damit arbeiten kann?

Der Zeckenzwischenspeicher hat nur eine Lebensdauer von 10 Sekunden.

 

Der Tick History Script Screener (die einzige Software, die im Terminal läuft) frisst bis zu 6 GB, wenn man die Notierungen von fünf Monaten nimmt.

Je schneller der Rechner und das Internet sind, desto größer ist die Speicherbelastung. D.h. die internen Zwischenspeicher des Terminals sammeln sich innerhalb von 10 Sekunden auf einige Zeichen an.

 
Schnelle Maschine, neun Berater.
2020.10.19 22:32:06.965         Bench_Stack = 3, 100 <= Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 1229 mcs.
2020.10.19 22:33:23.727         Bench_Stack = 3, 100 <= Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 1250 mcs.
2020.10.19 22:34:29.802         Bench_Stack = 3, 100 <= Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 1281 mcs.
2020.10.19 22:35:58.747         Bench_Stack = 2, 100 <= Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 1164 mcs.
2020.10.19 22:37:20.196         Bench_Stack = 3, 100 <= Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 1045 mcs.
2020.10.19 22:38:24.920         Bench_Stack = 3, 100 <= Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 1907 mcs.
2020.10.19 22:39:48.359         Bench_Stack = 3, 100 <= Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 1387 mcs.
2020.10.19 22:40:03.623         Bench_Stack = 3, 100 <= Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 1302 mcs.
2020.10.19 22:40:44.569         Bench_Stack = 3, 100 <= Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 1271 mcs.
2020.10.19 22:41:09.393         Bench_Stack = 3, 100 <= Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 1482 mcs.
2020.10.19 22:41:19.831         Bench_Stack = 3, 100 <= Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 1024 mcs.
2020.10.19 22:41:19.975         Alert: Bench_Stack = 3, 100 <= Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 8026 mcs.
2020.10.19 22:41:50.137         Bench_Stack = 2, 100 <= Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 1040 mcs.
2020.10.19 22:42:05.876         Bench_Stack = 2, 100 <= Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 1346 mcs.
2020.10.19 22:43:21.478         Bench_Stack = 3, 100 <= Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 1523 mcs.
2020.10.19 22:43:21.557         Bench_Stack = 3, 100 <= Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 1245 mcs.
2020.10.19 22:43:21.843         Alert: Bench_Stack = 3, 100 <= Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 4675 mcs.
2020.10.19 22:43:21.854         Alert: Bench_Stack = 3, 100 <= Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 7567 mcs.
2020.10.19 22:44:01.181         Bench_Stack = 3, 100 <= Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 1052 mcs.
2020.10.19 22:44:33.124         Bench_Stack = 3, 100 <= Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 2714 mcs.
2020.10.19 22:44:54.967         Alert: Bench_Stack = 3, 100 <= Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 13626 mcs.
2020.10.19 22:45:07.561         Bench_Stack = 3, 100 <= Time[NewTicks.mqh 33 in NEWTICKS::GetMarketWatchTick: ::SymbolInfoTick(_Symbol,Tick)] = 2800 mcs.
Ich weiß nicht, wie man solche Verzögerungen überwinden kann. Mir fällt kein anderer Weg ein, um zu wissen, ob es einen neuen Tick gibt, während OnTick ausgeführt wird.
 
fxsaber:
Mir fällt kein anderer Weg ein, um zu wissen, dass es einen neuen Tick gibt, während OnTick ausgeführt wird.

Drei Optionen.

// Идентификация нового тика
bool IsNewTick_CopyRates()
{
  static MqlRates PrevRates = {0};
  MqlRates Rates[1];
    
  const bool Res = (::CopyRates(_Symbol, PERIOD_CURRENT, 0, 1, Rates) == 1) &&
//                   (_R(PrevRates) != Rates[0]); // TypeToBytes.mqh
                   ((Rates[0].time != PrevRates.time) ||
                    (Rates[0].tick_volume > PrevRates.tick_volume) ||
                    (Rates[0].close != PrevRates.close)); // Лишнее условие, но на всякий случай.
                   
  if (Res)
    PrevRates = Rates[0];
    
  return(Res);
}

// Идентификация нового тика
bool IsNewTick_SymbolInfoTick()
{
  static MqlTick PrevTick = {0};
  MqlTick Tick;
  
  const bool Res = ::SymbolInfoTick(_Symbol, Tick) &&
//                   (_R(PrevTick) != Tick); // TypeToBytes.mqh
                   ((PrevTick.time_msc != Tick.time_msc) ||
                    (PrevTick.bid != Tick.bid) ||
                    (PrevTick.ask != Tick.ask));
                   
  if (Res)
    PrevTick = Tick;
    
  return(Res);
}

// Идентификация нового тика
bool IsNewTick_CopyTicks()
{
  static MqlTick PrevTick = {0};
  MqlTick Tick[1];
  
  const bool Res = (::CopyTicks(_Symbol, Tick, COPY_TICKS_ALL, 0, 1) == 1) &&
//                   (_R(PrevTick) != Tick[0]); // TypeToBytes.mqh
                   ((PrevTick.time_msc != Tick[0].time_msc) ||
                    (PrevTick.bid != Tick[0].bid) ||
                    (PrevTick.ask != Tick[0].ask));
                   
  if (Res)
    PrevTick = Tick[0];
    
  return(Res);
}

#define  PRINT(A)            \
  if (!A)                   \
    Print(#A + " = false");


void OnTick()
{
  PRINT(IsNewTick_CopyTicks());      // true
  PRINT(IsNewTick_SymbolInfoTick()); // true
  PRINT(IsNewTick_CopyRates())       // false
}

Es ist besser, einen neuen Tick nicht durch die Balken zu erkennen.

 
Es wurde deutlich, wie lange CopyTicks hinter SymbolInfoTick zurückbleiben können.
// Замер длительности синхронизации CopyTicks и SymbolInfoTick.

#include <TypeToBytes.mqh> // https://www.mql5.com/ru/code/16280

bool IsSynch()
{
  MqlTick Tick;
  MqlTick Ticks[1];
  
  return(SymbolInfoTick(_Symbol, Tick) && (CopyTicks(_Symbol, Ticks, COPY_TICKS_ALL, 0, 1) == 1) && (_R(Tick) == Ticks[0]));
}

ulong WaitSynch( int &Count )
{
  while (!IsStopped() && IsSynch())
    Sleep(0);
    
  const ulong StartTime = GetMicrosecondCount();
  Count = 0;
  
  while (!IsStopped() && !IsSynch())
    Count++;
    
  return(GetMicrosecondCount() - StartTime);
}

void OnTick()
{
  int Count;
  const uint StartTime = GetTickCount();

  while (GetTickCount() - StartTime < 10000)
    Print("Cинхронизация CopyTicks и SymbolInfoTick длилась " + (string)(WaitSynch(Count) / 1000)  + " ms., число проверок = " + (string)Count);
}


Ergebnis(inAmount = 15).

2020.10.20 00:32:46.316 Test9 (GBPAUD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 163 ms., число попыток = 391432
2020.10.20 00:32:46.894 Test9 (GBPAUD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 221 ms., число попыток = 526533
2020.10.20 00:32:50.839 Test9 (GBPAUD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 69 ms., число попыток = 112339
2020.10.20 00:32:50.839 Test9 (EURAUD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 385 ms., число попыток = 837204
2020.10.20 00:32:51.958 Test9 (EURAUD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 74 ms., число попыток = 166407
2020.10.20 00:32:52.044 Test9 (EURAUD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 80 ms., число попыток = 180256
2020.10.20 00:32:52.797 Test9 (EURAUD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 737 ms., число попыток = 1469883
2020.10.20 00:33:04.229 Test9 (EURAUD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 8550 ms., число попыток = 14608891
2020.10.20 00:33:04.319 Test9 (GBPAUD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 159 ms., число попыток = 150630
2020.10.20 00:33:04.324 Test9 (AUDCHF,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 85 ms., число попыток = 78591
2020.10.20 00:33:07.340 Test9 (EURAUD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 2947 ms., число попыток = 4899320
2020.10.20 00:33:08.076 Test9 (EURAUD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 727 ms., число попыток = 1209371
2020.10.20 00:33:08.138 Test9 (EURAUD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 55 ms., число попыток = 73155
2020.10.20 00:33:14.233 Test9 (EURCAD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 107 ms., число попыток = 149697
2020.10.20 00:33:15.985 Test9 (EURCAD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 190 ms., число попыток = 230501
2020.10.20 00:33:16.114 Test9 (GBPJPY,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 208 ms., число попыток = 275639
2020.10.20 00:33:41.328 Test9 (GBPJPY,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 9457 ms., число попыток = 14426849
2020.10.20 00:33:46.000 Test9 (GBPCHF,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 53622 ms., число попыток = 109127013
2020.10.20 00:33:47.936 Test9 (GBPJPY,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 1302 ms., число попыток = 3104323
2020.10.20 00:33:55.715 Test9 (GBPAUD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 59 ms., число попыток = 87263
2020.10.20 00:33:55.776 Test9 (GBPJPY,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 88 ms., число попыток = 125641
2020.10.20 00:33:55.869 Test9 (GBPJPY,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 86 ms., число попыток = 140282
2020.10.20 00:33:55.974 Test9 (GBPJPY,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 95 ms., число попыток = 91802
2020.10.20 00:33:56.004 Test9 (GBPAUD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 125 ms., число попыток = 127590
2020.10.20 00:33:56.202 Test9 (GBPJPY,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 214 ms., число попыток = 311277
2020.10.20 00:34:40.522 Test9 (GBPAUD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 31 ms., число попыток = 48189
2020.10.20 00:34:40.672 Test9 (GBPAUD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 69 ms., число попыток = 99619
2020.10.20 00:34:41.094 Test9 (GBPAUD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 412 ms., число попыток = 613382
2020.10.20 00:34:41.864 Test9 (GBPAUD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 768 ms., число попыток = 1136798
2020.10.20 00:34:46.035 Test9 (GBPAUD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 2012 ms., число попыток = 2955715
2020.10.20 00:34:46.124 Test9 (GBPAUD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 79 ms., число попыток = 109796
2020.10.20 00:34:46.239 Test9 (GBPAUD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 98 ms., число попыток = 152433
2020.10.20 00:34:47.261 Test9 (GBPAUD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 1009 ms., число попыток = 1300923
2020.10.20 00:34:47.337 Test9 (GBPAUD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 73 ms., число попыток = 66414
2020.10.20 00:34:47.850 Test9 (AUDCHF,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 885 ms., число попыток = 832072
2020.10.20 00:34:48.383 Test9 (GBPAUD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 1040 ms., число попыток = 1239140
2020.10.20 00:34:49.093 Test9 (EURCAD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 46 ms., число попыток = 43232
2020.10.20 00:34:49.839 Test9 (GBPAUD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 1445 ms., число попыток = 2065046
2020.10.20 00:34:51.474 Test9 (GBPCHF,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 55801 ms., число попыток = 119517920
2020.10.20 00:34:51.755 Test9 (GBPAUD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 1498 ms., число попыток = 1625714
2020.10.20 00:34:52.269 Test9 (GBPJPY,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 403 ms., число попыток = 693015
2020.10.20 00:34:59.175 Test9 (AUDCAD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 9413 ms., число попыток = 16211601
2020.10.20 00:35:00.398 Test9 (EURAUD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 6302 ms., число попыток = 11626079
2020.10.20 00:35:05.587 Test9 (AUDCHF,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 3645 ms., число попыток = 8637511
2020.10.20 00:35:07.247 Test9 (EURAUD,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 133 ms., число попыток = 205326
2020.10.20 00:35:09.033 Test9 (AUDCHF,H1)       Cинхронизация CopyTicks и SymbolInfoTick длилась 3427 ms., число попыток = 8060967

Die Desynchronisation kann bis zu einer Minute dauern. Es gibt irgendwo einen Fehler.

 

Der Grund für das Abbremsen von SymbolInfoTick scheint die Parallelverarbeitung zu sein.

// Демонстрация тормозов SymbolInfoTick
#include <fxsaber\Benchmark\Benchmark.mqh> // https://www.mql5.com/ru/code/31279

void OnTick()
{
  const uint StartTime = GetTickCount();

  while (!IsStopped() && (GetTickCount() - StartTime < 10000))
  {
    _B(SymbolInfoInteger(_Symbol, SYMBOL_TIME_MSC), 100000);
    
//    Sleep(0); // Специально убрал.
  }
}


Ergebnis (inAmount = 15).

2020.10.20 01:01:30.517 Test9 (EURAUD,H1)       Alert: Bench_Stack = 0, 100000 <= Time[Test9.mq5 97 in OnTick: SymbolInfoInteger(_Symbol,SYMBOL_TIME_MSC)] = 105941 mcs.
2020.10.20 01:01:37.596 Test9 (USDCAD,H1)       Alert: Bench_Stack = 0, 100000 <= Time[Test9.mq5 97 in OnTick: SymbolInfoInteger(_Symbol,SYMBOL_TIME_MSC)] = 103045 mcs.
2020.10.20 01:01:38.968 Test9 (EURCHF,H1)       Alert: Bench_Stack = 0, 100000 <= Time[Test9.mq5 97 in OnTick: SymbolInfoInteger(_Symbol,SYMBOL_TIME_MSC)] = 103305 mcs.
2020.10.20 01:01:41.307 Test9 (EURUSD,H1)       Alert: Bench_Stack = 0, 100000 <= Time[Test9.mq5 97 in OnTick: SymbolInfoInteger(_Symbol,SYMBOL_TIME_MSC)] = 106121 mcs.
2020.10.20 01:01:42.573 Test9 (USDCAD,H1)       Alert: Bench_Stack = 0, 100000 <= Time[Test9.mq5 97 in OnTick: SymbolInfoInteger(_Symbol,SYMBOL_TIME_MSC)] = 128241 mcs.
2020.10.20 01:01:45.175 Test9 (GBPCHF,H1)       Alert: Bench_Stack = 0, 100000 <= Time[Test9.mq5 97 in OnTick: SymbolInfoInteger(_Symbol,SYMBOL_TIME_MSC)] = 120367 mcs.
2020.10.20 01:01:46.394 Test9 (EURCHF,H1)       Alert: Bench_Stack = 0, 100000 <= Time[Test9.mq5 97 in OnTick: SymbolInfoInteger(_Symbol,SYMBOL_TIME_MSC)] = 104458 mcs.
2020.10.20 01:01:57.832 Test9 (GBPCHF,H1)       Alert: Bench_Stack = 0, 100000 <= Time[Test9.mq5 97 in OnTick: SymbolInfoInteger(_Symbol,SYMBOL_TIME_MSC)] = 125348 mcs.

> 100 ms für die Ausführung von SymbolInfoTick. Es ist klar, dass der Code ein Selbstläufer ist. Aber es zeigt den Grund für die Verlangsamung bei den üblichen EAs.