MT5 e la velocità in azione - pagina 62

 
Rorschach:
Un kernel in tempo reale aiuterebbe in qualche modo?

Mettete più core nel sistema e non rendete la situazione al 100% un carico single core.

Non credete alle favole, i processori e il thread scheduler non funzionano come immaginate.

 
Anton:

Nelle ultime build la ricezione del flusso di tick non ha alcun effetto, anche teoricamente. Praticamente SymbolInfoTick funziona già con la cache, ma i singoli cittadini continuano a cercare un gatto nero.

E non è nemmeno l'80% nel test. Ha 6 agenti in esecuzione su 4 core, cioè il 100% garantito.

L'unica domanda è come il task scheduler del suo sistema sta gestendo la situazione. Allo stesso tempo, gli autori affermano che la colpa è dell'implementazione del terminale.

Cioè, si crea artificialmente una situazione in cui un computer è sovraccarico, quando letteralmente tutto su di esso rallenta, e poi si fanno delle affermazioni sotto forma di "Oh, guarda, perché il terminale a volte lagga".

Chiudiamo gli occhi sul fatto che anche in queste condizioni è "circa lo 0,01%" - al diavolo i dettagli! Basta dire che "a nessuno interessa la temperatura media dell'ospedale", "i ritardi causano problemi nel trading" e "vogliamo l'HFT".

Inoltre, ovviamente vogliamo HFT in 20 esperti su un vecchio desktop da ufficio o una macchina virtuale morta.

PS PositionSelectByTicket() nella sua implementazione ha certamente accesso a una risorsa condivisa con sincronizzazione degli accessi. E se non selezioni la posizione su ogni chiamata, stai leggendo il vecchio prezzo. Era più facile fare una "istantanea" tramite SymbolInfoDouble.

grazie

Ho la mia domanda perché sei mesi fa, stavo ottimizzando il mio codice e testando la velocità delle funzioni di sistema, e sei mesi fa, SymbolInfoDouble era più lento di SymbolInfoTick

Forse è vero quello che dici però. Oggi stavo cercando su Google alcuni articoli sulla cache multi-core (non mi sono interessato a queste informazioni per molto tempo),

Ecco un breve articolohttps://i2hard.ru/publications/25666/

il punto è che i dati arrivano a correre in ALU solo da L1-cache che è molto piccola e se si carica il processore a piena velocità, allora davvero - il test si trasformerà in un test del sistema operativo + test della velocità della cache del processore (caricamento, previsione dei dati L1+L3) ma non nel test delle prestazioni del codice (applicazione)

 

fxsaber, cosa succede se si imposta una priorità bassa per gli agenti nel task manager e una alta per MT5?

Non riesco a trovare un'utility che blocchi tutti i programmi/ thread dell'OS dall'essere assegnati a un thread specifico della CPU, altrimenti sarebbe possibile riservare un thread per MT5 e bloccarlo automaticamente dall'essere usato da altri programmi, il che potrebbe in teoria ridurre i lag.

 
Anton:

Nelle ultime build la ricezione del flusso di tick non ha alcun effetto, anche teoricamente. In pratica, SymbolInfoTick funziona già con la cache, ma certi cittadini continuano a cercare un gatto nero.

Un cittadino particolare ha fattoduplicare il codice MQL dai suoi pantaloni larghi che ha mostrato che la stampella funziona più velocemente della funzione regolare nelle stesse condizioni.

Ma voi sostenete che la vostra funzione è buona, ha solo delle limitazioni nelle condizioni d'uso.

E non è nemmeno l'80% nel test. Ci sono 6 agenti in esecuzione su 4 core, cioè garantiti al 100%.

L'unica domanda è come il task scheduler del suo sistema sta gestendo la situazione. Allo stesso tempo, alcuni sostengono che la colpa è dell'implementazione del terminale.

Cioè, si crea artificialmente una situazione in cui un computer è sovraccaricato fino ai suoi limiti e tutto rallenta su di esso, e poi si fanno delle affermazioni sotto forma di "Oh, guarda, perché il terminale a volte lagga laggiù".

6/8 - niente è in ritardo. Browser, compilazione, debug ecc. girano in parallelo senza alcun accenno di ritardo.

Ma ora ho spento tutto di proposito, lasciando solo 4/8 di agente. La situazione non è cambiata con la tua funzione frenante.

Inoltre, ovviamente, vogliamo HFT in 20 esperti su un vecchio desktop da ufficio o una macchina virtuale morta.

È stata usata una macchina veloce. E solo 6 classifiche davano già i freni.

PS PositionSelectByTicket() nella sua implementazione ha certamente accesso a una risorsa condivisa con sincronizzazione degli accessi. E se non si seleziona la posizione su ogni chiamata, si legge il vecchio prezzo. Era più facile "fotografare" tramite SymbolInfoDouble.

Anche io uso questo.

// Снепшот 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);
}
 

Di che tipo di velocità nelle prestazioni di combattimento possiamo parlare quando ci sono problemi nel terminale.

L'Expert Advisor scansiona tutti gli strumenti finanziari e cerca un determinato modello.

Inciampa su un simbolo e si tiene stretto!!!

Codice da aiuto, ho messo solo passi, strumento finanziario con problema e 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"); 
  }

Risultato del lavoro:

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 === 

Non ho mai aspettato che lo script finisse di funzionare.

Finché il terminale ha questi bug, nessuna esecuzione di battaglia è fuori questione!!!

Ci si aspettava che quando un titolo entra nella revisione del mercato, almeno tutte le sue proprietà e la data di inizio della storia sono tirate fuori per esso. Se non c'è storia sul server, allora

SeriesInfoInteger(symbol,period,SERIES_FIRSTDATE,first_date)

Dovrebbe restituire NULL istantaneamente, perché il tempo di esecuzione 18446744073475877138 ?


Forse non so qualcosa, anche la funzione CopyXXX si blocca per 16-29 secondi!!!

Non è normale che un broker abbia 3000-6000 strumenti finanziari.

 
Vladimir Pastushak:

Forse non so cosa, anche le funzioni CopyXXX si bloccano per 16-29 secondi!!!

Non è normale che un broker abbia 3000-6000 strumenti finanziari.

I bar sono il male. Quindi, per favore, postate su di loro in un altro thread.

 
fxsaber:

I bar sono il male. Quindi, per favore, postate su di loro in un altro thread.

Forse sapete come selezionare programmaticamente uno strumento finanziario e non rimanere bloccati per anni?

 
Vladimir Pastushak:

Forse sapete come selezionare programmaticamente uno strumento finanziario e non rimanere bloccati per anni?

Non mi sono mai imbattuto in un compito simile.

 
Aleksey Vyazmikin:

fxsaber, cosa succede se si imposta una priorità bassa per gli agenti nel task manager e una alta per MT5?

Non riesco a trovare un'utility che blocchi l'assegnazione di un thread specifico della CPU a tutti i programmi/filetti dell'OS, altrimenti sarebbe possibile riservare un thread per MT5 e bloccare automaticamente la sua occupazione da parte di altri programmi, il che potrebbe in teoria ridurre i lag.

Imposta tutti gli agenti alla priorità più bassa.

Non funziona.


ZZZ Il numero di EA in esecuzione influenza il risultato.

 

Cari sviluppatori, potreste informarmi come viene calcolato MQL_MEMORY_USED?

Ho fatto un calcolo della memoria che tutte le variabili EA occupano.

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

È meno del 10%. Se ho capito bene, MQL_MEMORY_USED contiene la cache History e la cache CopyTicks. Ma è ancora molto meno.

Allo stesso tempo, l'Expert Advisor parallelo consuma diverse volte meno. Ma il principio è lo stesso.

In generale, cosa è incluso in questo valore?


Ho salvato un modello con Expert Advisor e l'ho applicato allo stesso grafico causando il ricaricamento. L'ho visto così.

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

L'uso della memoria è cambiato di quasi un ordine di grandezza. È difficile spiegare cosa significa questo al momento.