MT5 und Geschwindigkeit in Aktion - Seite 62

 
Rorschach:
Würde ein Echtzeit-Kernel in irgendeiner Weise helfen?

Bauen Sie mehr Kerne in das System ein und belasten Sie es nicht zu 100 % mit einem Kern.

Glauben Sie nicht an Märchen, Prozessoren und Thread Scheduler funktionieren nicht so, wie Sie es sich vorstellen.

 
Anton:

In den neuesten Builds hat der Tick-Stream-Empfang auch theoretisch keine Auswirkungen. Praktisch funktioniert SymbolInfoTick bereits mit Cache, aber einzelne Bürger suchen weiter nach einer schwarzen Katze.

Und es sind nicht einmal 80 % im Test. Es hat 6 Agenten, die auf 4 Kernen laufen, d.h. 100% garantiert.

Die einzige Frage ist, wie der Taskplaner seines Systems mit dieser Situation umgeht. Gleichzeitig wird behauptet, dass es an der Umsetzung der Terminals liegt, die dafür verantwortlich ist.

Das heißt, es wird künstlich eine Situation geschaffen, in der ein Computer überlastet ist, in der buchstäblich alles auf ihm langsamer wird, und dann werden Behauptungen aufgestellt in der Form "Oh, sieh mal, warum ist der Terminal manchmal lags".

Verschließen wir die Augen vor der Tatsache, dass es selbst unter solchen Bedingungen "etwa 0,01 %" sind - zum Teufel mit den Details! Es genügt zu sagen, dass "sich niemand für die durchschnittliche Temperatur im Krankenhaus interessiert", "Verzögerungen beim Handel Probleme verursachen" und "wir wollen HFT".

Außerdem wollen wir natürlich HFT in 20 Experten auf einem alten Büro-Desktop oder einer toten virtuellen Maschine.

PS PositionSelectByTicket() hat in seiner Implementierung sicherlich Zugriff auf eine gemeinsame Ressource mit Zugriffssynchronisierung. Und wenn Sie nicht bei jedem Anruf die Position auswählen, lesen Sie den alten Kurs. Es war einfacher, einen "Schnappschuss" über SymbolInfoDouble zu machen.

danke

Ich habe meine Frage gestellt, weil ich vor sechs Monaten meinen Code optimierte und die Geschwindigkeit von Systemfunktionen testete, und vor sechs Monaten war SymbolInfoDouble langsamer als SymbolInfoTick

Vielleicht stimmt es ja, was Sie sagen. Ich habe heute ein paar Artikel über Multi-Core-Cache gegoogelt (ich habe mich schon lange nicht mehr für diese Informationen interessiert),

Hier ist ein kurzer Artikelhttps://i2hard.ru/publications/25666/

der Punkt ist, dass die Daten in der ALU nur aus dem L1-Cache laufen, der sehr klein ist, und wenn Sie den Prozessor mit voller Geschwindigkeit belasten, dann wirklich - der Test wird zu einem Test des Betriebssystems + Test der Prozessor-Cache-Geschwindigkeit (Laden, Vorhersage von L1+L3-Daten), aber nicht beim Testen von Code (Anwendung) Leistung

 

fxsaber, was, wenn Sie eine niedrige Priorität für Agenten in Task-Manager und eine hohe für MT5?

Ich kann kein Dienstprogramm finden, das alle Programme/OS-Threads daran hindert, einen bestimmten CPU-Thread zugewiesen zu bekommen. Andernfalls wäre es möglich, dass MT5 einen Thread reserviert und automatisch blockiert, dass er von anderen Programmen verwendet wird, was theoretisch Verzögerungen reduzieren könnte.

 
Anton:

In den neuesten Builds hat der Tick-Stream-Empfang auch theoretisch keine Auswirkungen. Praktisch gesehen arbeitet SymbolInfoTick bereits mit einem Cache, aber einige Bürger suchen immer noch nach einer schwarzen Katze.

Ein bestimmter Bürger hat den MQL-Code aus seiner breiten Hosedupliziertbekommen, der zeigte, dass die Krücke unter den gleichen Bedingungen schneller arbeitet als die reguläre Funktion.

Aber Sie argumentieren, dass Ihre Funktion gut ist, sie hat nur Einschränkungen in Bezug auf die Einsatzbedingungen.

Und es sind nicht einmal 80 % im Test. Es laufen 6 Agenten auf 4 Kernen, d.h. 100% garantiert.

Die einzige Frage ist, wie der Taskplaner seines Systems mit dieser Situation umgeht. Gleichzeitig wird behauptet, dass es an der Umsetzung der Terminals liegt, die dafür verantwortlich ist.

Das heißt, es wird künstlich eine Situation geschaffen, in der ein Computer bis an seine Grenzen überlastet ist und alles langsamer wird, und dann werden Behauptungen aufgestellt in der Form: "Oh, sieh mal, warum ist das Terminal manchmal lags".

6/8 - nichts ist im Rückstand. Browser, Kompilierung, Debugging usw. laufen parallel, ohne dass es zu Verzögerungen kommt.

Aber jetzt habe ich absichtlich alles ausgeschaltet, so dass nur noch 4/8 Agenten übrig sind. Die Situation hat sich durch Ihre Funktionsbremsung nicht geändert.

Darüberhinaus wollen wir natürlich, dass HFT in 20 Experten auf einem alten Büro-Desktop oder einer toten virtuellen Maschine läuft.

Es wurde eine schnelle Maschine verwendet. Und nur 6 Charts gaben bereits die Bremse.

PS PositionSelectByTicket() hat in seiner Implementierung sicherlich Zugriff auf eine gemeinsame Ressource mit Zugriffssynchronisierung. Und wenn Sie die Position nicht bei jedem Anruf auswählen, lesen Sie den alten Preis. Es war einfacher, einen "Schnappschuss" über SymbolInfoDouble zu machen.

Ich benutze das auch.

// Снепшот SymbolInfoTick для текущего символа.
bool SymbolInfoTick( MqlTick &Tick )
{
  static MqlTick PrevTick = {0};
  static ulong PrevTime = 0;
  
  const ulong NewTime = GetMicrosecondCount();
  const bool Res = (NewTime - PrevTime < 1000) || (::SymbolInfoTick(_Symbol, PrevTick) && (bool)(PrevTime = NewTime));
  
  Tick = PrevTick;
  
  return(Res);
}
 

Über welche Art von Geschwindigkeit in der Kampfleistung können wir sprechen, wenn es Probleme im Terminal gibt.

Der Expert Advisor scannt alle Finanzinstrumente und sucht nach einem bestimmten Muster.

Er stolpert über ein Symbol und hält sich fest!!!

Code von Hilfe, ich habe nur Schritte, Finanzinstrument mit Problem und Timer:

//+------------------------------------------------------------------+ 
//|                                              TestLoadHistory.mq5 | 
//|                        Copyright 2009, MetaQuotes Software Corp. | 
//|                                              https://www.mql5.com | 
//+------------------------------------------------------------------+ 
#property copyright "2009, MetaQuotes Software Corp." 
#property link      "https://www.mql5.com" 
#property version   "1.02" 
#property script_show_inputs 
//--- input parameters 
input string          InpLoadedSymbol="RTSCHH1";   // Symbol to be load 
input ENUM_TIMEFRAMES InpLoadedPeriod=PERIOD_H1;  // Period to be load 
input datetime        InpStartDate=D'2006.01.01'; // Start date 
//+------------------------------------------------------------------+ 
//| Script program start function                                    | 
//+------------------------------------------------------------------+ 
void OnStart() 
  { 
   Print("Start load",InpLoadedSymbol+","+GetPeriodName(InpLoadedPeriod),"from",InpStartDate); 
//--- 
   int res=CheckLoadHistory(InpLoadedSymbol,InpLoadedPeriod,InpStartDate); 
   switch(res) 
     { 
      case -1 : Print("Unknown symbol ",InpLoadedSymbol);             break; 
      case -2 : Print("Requested bars more than max bars in chart "); break; 
      case -3 : Print("Program was stopped ");                        break; 
      case -4 : Print("Indicator shouldn't load its own data ");      break; 
      case -5 : Print("Load failed ");                                break; 
      case  0 : Print("Loaded OK ");                                  break; 
      case  1 : Print("Loaded previously ");                          break; 
      case  2 : Print("Loaded previously and built ");                break; 
      default : Print("Unknown result "); 
     } 
//--- 
   datetime first_date; 
   SeriesInfoInteger(InpLoadedSymbol,InpLoadedPeriod,SERIES_FIRSTDATE,first_date); 
   int bars=Bars(InpLoadedSymbol,InpLoadedPeriod); 
   Print("First date ",first_date," - ",bars," bars"); 
//--- 
  } 
//+------------------------------------------------------------------+ 
//|                                                                  | 
//+------------------------------------------------------------------+ 
int CheckLoadHistory(string symbol,ENUM_TIMEFRAMES period,datetime start_date) 
  { 
  Print(" === 1 === ");
   datetime first_date=0; 
   datetime times[100]; 
//--- check symbol & period 
   if(symbol==NULL || symbol=="") symbol=Symbol(); 
   if(period==PERIOD_CURRENT)     period=Period(); 
//--- check if symbol is selected in the MarketWatch 
   if(!SymbolInfoInteger(symbol,SYMBOL_SELECT)) 
     { 
      if(GetLastError()==ERR_MARKET_UNKNOWN_SYMBOL) return(-1); 
      SymbolSelect(symbol,true); 
     } 
     
     ulong time = GetMicrosecondCount();
     Print(" === 2 === ",first_date);
//--- check if data is present 
  bool date = SeriesInfoInteger(symbol,period,SERIES_FIRSTDATE,first_date); 
   
   Print(" === 2.1 === ",(time - GetMicrosecondCount()));
   
   if(first_date>0 && first_date<=start_date) return(1); 
//--- don't ask for load of its own data if it is an indicator 

Print(" === 2.2 === ");
   if(MQL5InfoInteger(MQL5_PROGRAM_TYPE)==PROGRAM_INDICATOR && Period()==period && Symbol()==symbol) 
      return(-4); 
//--- second attempt 
Print(" === 2.3 === ");
   if(SeriesInfoInteger(symbol,PERIOD_M1,SERIES_TERMINAL_FIRSTDATE,first_date)) 
     { 
      //--- there is loaded data to build timeseries 
      Print(" === 2.4 === ");
      if(first_date>0) 
        { 
         //--- force timeseries build 
         CopyTime(symbol,period,first_date+PeriodSeconds(period),1,times); 
         //--- check date 
         Print(" === 2.5 === ");
         if(SeriesInfoInteger(symbol,period,SERIES_FIRSTDATE,first_date)) 
            if(first_date>0 && first_date<=start_date) return(2); 
        } 
     } 
     
     Print(" === 3 === ");
     
//--- max bars in chart from terminal options 
   int max_bars=TerminalInfoInteger(TERMINAL_MAXBARS); 
//--- load symbol history info 
   datetime first_server_date=0; 
   while(!SeriesInfoInteger(symbol,PERIOD_M1,SERIES_SERVER_FIRSTDATE,first_server_date) && !IsStopped()) 
      Sleep(5); 
//--- fix start date for loading 

Print(" === 4 === ");


   if(first_server_date>start_date) start_date=first_server_date; 
   if(first_date>0 && first_date<first_server_date) 
      Print("Warning: first server date ",first_server_date," for ",symbol, 
            " does not match to first series date ",first_date); 
//--- load data step by step 

Print(" === 5 === ");

   int fail_cnt=0; 
   while(!IsStopped()) 
     { 
      //--- wait for timeseries build 
      while(!SeriesInfoInteger(symbol,period,SERIES_SYNCHRONIZED) && !IsStopped()) 
         Sleep(5); 
      //--- ask for built bars 
      int bars=Bars(symbol,period); 
      if(bars>0) 
        { 
         if(bars>=max_bars) return(-2); 
         //--- ask for first date 
         if(SeriesInfoInteger(symbol,period,SERIES_FIRSTDATE,first_date)) 
            if(first_date>0 && first_date<=start_date) return(0); 
        } 
      //--- copying of next part forces data loading 
      int copied=CopyTime(symbol,period,bars,100,times); 
      if(copied>0) 
        { 
         //--- check for data 
         if(times[0]<=start_date)  return(0); 
         if(bars+copied>=max_bars) return(-2); 
         fail_cnt=0; 
        } 
      else 
        { 
         //--- no more than 100 failed attempts 
         fail_cnt++; 
         if(fail_cnt>=100) return(-5); 
         Sleep(10); 
        } 
     } 
     
     Print(" === 6 === ");
//--- stopped 
   return(-3); 
  } 
//+------------------------------------------------------------------+ 
//| Возвращает строкое значение периода                              | 
//+------------------------------------------------------------------+ 
string GetPeriodName(ENUM_TIMEFRAMES period) 
  { 
   if(period==PERIOD_CURRENT) period=Period(); 
//--- 
   switch(period) 
     { 
      case PERIOD_M1:  return("M1"); 
      case PERIOD_M2:  return("M2"); 
      case PERIOD_M3:  return("M3"); 
      case PERIOD_M4:  return("M4"); 
      case PERIOD_M5:  return("M5"); 
      case PERIOD_M6:  return("M6"); 
      case PERIOD_M10: return("M10"); 
      case PERIOD_M12: return("M12"); 
      case PERIOD_M15: return("M15"); 
      case PERIOD_M20: return("M20"); 
      case PERIOD_M30: return("M30"); 
      case PERIOD_H1:  return("H1"); 
      case PERIOD_H2:  return("H2"); 
      case PERIOD_H3:  return("H3"); 
      case PERIOD_H4:  return("H4"); 
      case PERIOD_H6:  return("H6"); 
      case PERIOD_H8:  return("H8"); 
      case PERIOD_H12: return("H12"); 
      case PERIOD_D1:  return("Daily"); 
      case PERIOD_W1:  return("Weekly"); 
      case PERIOD_MN1: return("Monthly"); 
     } 
//--- 
   return("unknown period"); 
  }

Ergebnis der Arbeit:

2020.10.28 11:18:08.067 Test (FUTBRNJAN21,M1)   Start loadRTSCHH1,H1from2006.01.01 00:00:00
2020.10.28 11:18:08.067 Test (FUTBRNJAN21,M1)    === 1 === 
2020.10.28 11:18:08.067 Test (FUTBRNJAN21,M1)    === 2 === 1970.01.01 00:00:00
2020.10.28 11:22:01.741 Test (FUTBRNJAN21,M1)    === 2.1 === 18446744073475877138    Время выполнения SeriesInfoInteger(symbol,period,SERIES_FIRSTDATE,first_date); 
2020.10.28 11:22:01.741 Test (FUTBRNJAN21,M1)    === 2.2 === 
2020.10.28 11:22:01.741 Test (FUTBRNJAN21,M1)    === 2.3 === 
2020.10.28 11:22:01.741 Test (FUTBRNJAN21,M1)    === 3 === 

Ich habe nie darauf gewartet, dass das Skript zu Ende läuft.

Solange das Terminal solche Fehler hat, ist an eine Kampfausführung nicht zu denken!!!

Es wurde erwartet, dass, wenn ein Wertpapier in die Marktübersicht aufgenommen wird, zumindest alle seine Eigenschaften und das Anfangsdatum der Historie für es abgerufen werden. Wenn es auf dem Server keinen Verlauf gibt, dann

SeriesInfoInteger(symbol,period,SERIES_FIRSTDATE,first_date)

Sollte sofort NULL zurückgeben, warum die Ausführungszeit 18446744073475877138 ?


Vielleicht weiß ich etwas nicht, die Funktion CopyXXX bleibt auch 16-29 Sekunden hängen!!!

Es ist nicht normal, dass ein Makler 3000-6000 Finanzinstrumente im Angebot hat.

 
Vladimir Pastushak:

Vielleicht weiß ich nicht was, die CopyXXX Funktionen hängen auch 16-29 Sekunden!!!

Es ist nicht normal, dass ein Broker 3000-6000 Finanzinstrumente im Angebot hat.

Bars sind böse. Also bitte in einem anderen Thread darüber schreiben.

 
fxsaber:

Bars sind böse. Also bitte in einem anderen Thread darüber schreiben.

Vielleicht wissen Sie, wie man programmgesteuert ein Finanzinstrument auswählt und nicht ewig hängenbleibt?

 
Vladimir Pastushak:

Vielleicht wissen Sie, wie man programmgesteuert ein Finanzinstrument auswählt und nicht ewig hängenbleibt?

Ich bin noch nicht auf eine solche Aufgabe gestoßen.

 
Aleksey Vyazmikin:

fxsaber, was, wenn Sie eine niedrige Priorität für Agenten in Task-Manager und eine hohe für MT5?

Ich kann kein Dienstprogramm finden, das die Zuweisung eines bestimmten CPU-Threads an alle Programme/OS-Threads blockiert. Andernfalls wäre es möglich, einen Thread für MT5 zu reservieren und seine Belegung durch andere Programme automatisch zu blockieren, was theoretisch Verzögerungen verringern könnte.

Setzen Sie alle Agenten auf die niedrigste Priorität.

Das funktioniert nicht.


ZZZ Die Anzahl der laufenden EAs beeinflusst das Ergebnis.

 

Liebe Entwickler, könnten Sie mir bitte mitteilen, wie MQL_MEMORY_USED berechnet wird?

Ich habe den Speicherplatz berechnet, den alle Variablen des EA belegen.

MQL_MEMORY_USED = 60 MB, Virtual = 3.40 MB ( 5.7%)

Sie beträgt weniger als 10 %. Wenn ich es richtig verstehe, umfasst MQL_MEMORY_USED den History-Cache und den CopyTicks-Cache. Aber es ist immer noch viel weniger.

Gleichzeitig verbraucht der parallele Expert Advisor ein Vielfaches weniger. Aber das Prinzip ist das gleiche.

Was ist im Allgemeinen in diesem Wert enthalten?


Ich habe eine Vorlage mit Expert Advisor gespeichert und sie auf dasselbe Diagramm angewendet, indem ich ein Neuladen veranlasste. Ich habe es so gesehen.

MQL_MEMORY_USED = 7 MB, Virtual = 3.40 MB ( 48.6%)

Die Speichernutzung hat sich um fast eine Größenordnung verändert. Es ist im Moment schwer zu erklären, was das bedeutet.