MT5 e la velocità in azione - pagina 46

 
Renat Fatkhullin:

Il timer al millisecondo esiste da molto tempo: EventSetMillisecondTimer()

Sei completamente fuori dal giro. Supponiamo che abbiate bisogno di aprire due posizioni in OnTick. Il primo OrderSend è di pochi millisecondi. Dopo di che è necessario fare un'istantanea. E poi dovrebbe essere chiamato il secondo OrderSend.

Solo OnTick può essere eseguito per centinaia di millisecondi. E voi suggerite di scattare qualche OnTimer.

 
Renat Fatkhullin:

Ci sono anche problemi con la libreria di misurazione stessa. C'è un sacco di roba inutile, comprese le spese generali.

Litigi in studio!

 
Renat Fatkhullin:

Ecco il mio codice e il tempo di esecuzione stabile: nessuna centinaia o migliaia di microsecondi su 20 grafici in parallelo

Quanti core hai e che tipo di processore? i7-2600?

8 core.

2020.10.06 02:27:59.464 Terminal        MetaTrader 5 x64 build 2630 started for MetaQuotes Software Corp.
2020.10.06 02:27:59.465 Terminal        Windows 10 build 19042, Intel Core i7-2700 K  @ 3.50 GHz, 7 / 15 Gb memory, 19 / 29 Gb disk, IE 11, Admin, GMT+3

Stress test nascosto di nuovo con milioni di richieste in parallelo?

Ti ho detto molte volte che consigliere di combattimento. Minimizzato il numero di chiamate il più possibile. In teoria (non l'ho misurato) fino a 10 chiamate per OnTick.


Essere più trasparente. Solo perché hai postato un paio di semplici chiamate _B non è una prova delle tue altre affermazioni. Lei dimentica bruscamente il codice e la descrizione reale delle condizioni non appena fa delle affermazioni stravaganti.

Non avete bisogno di immaginare nulla nella vostra mente - raccontate e mostrate ciò che effettivamente chiamate e testate. Non un risultato strappato di "eseguito uno stress test sconosciuto e in attesa di un avviso per mostrare il mondo", ma esattamente il codice completo del test.

Sto pubblicando i risultati dell'EA live. Ci sono 70 file mqh lì, incluso WinAPI. Se non vi limitate a parlarne, ma lo capite davvero, vi darò il codice sorgente. Riprodurrai i freni abbastanza rapidamente.

 
fxsaber:

Sei completamente fuori dal giro. Diciamo che avete bisogno di aprire due posizioni in OnTick. Il primo OrderSend è di pochi millisecondi. Dopo di che è necessario fare un'istantanea. E poi dovrebbe essere chiamato il secondo OrderSend.

Solo OnTick può essere eseguito per centinaia di millisecondi. E voi suggerite di scattare qualche OnTimer.

Non ho suggerito di scattare, ho risposto a una domanda diretta sul timer di millisecondi.

C'è, anche se nel tester attuale si attiva ancora a 1 secondo. Nel nuovo tester che stiamo scrivendo, cercheremo di cambiare questo.
 
fxsaber:

8 core.

Molte volte ha detto consigliere di combattimento. Minimizzato il numero di chiamate il più possibile. In teoria (non l'ho misurato) fino a 10 chiamate per OnTick.


Sto pubblicando i risultati dell'Expert Advisor. Ci sono 70 file mqh lì, incluso WinAPI. Se non vi limitate a parlarne, ma lo capite davvero, vi darò il codice sorgente. Giocherete i freni abbastanza rapidamente.

Lo scopriremo, dacci il codice sorgente.
 
fxsaber:

Argomenti sul tavolo!

Tutto il tuo benchmark è sovraccarico di spazzatura e infatti qui c'è una versione pulita e comprensibile (a differenza del tuo disordine di codice) di esso:


//--- benchmark macros
#define _B(_function,_alert_interval)               \
          {                                         \
           ulong _latency=GetMicrosecondCount();    \
           _function;                               \
           _latency=GetMicrosecondCount()-_latency; \
           if(_latency > _alert_interval)           \
              ::Alert("Time[" + __FILE__ + " " + (string)__LINE__ + " in " + __FUNCTION__+ ": " + #_function + "] = " + (string)_latency + " mсs"); \
          }



//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnTick()
  {
   MqlTick Tick;
   
   _B(SymbolInfoTick(_Symbol,Tick),0);
   _B(SymbolInfoTick(_Symbol,Tick),0);
  }

Quali sono i suoi problemi:

  1. codice illeggibile

  2. Legarsi a una classe con molto overhead

  3. il costo di memorizzare 50 risultati nello stack
      static bool Set( const string Str )
      {
        if (BENCHMARK::Amount == BENCHMARK::ReserveSize)
          BENCHMARK::ReserveSize = ::ArrayResize(BENCHMARK::Bench, BENCHMARK::ReserveSize + BENCHMARK_RESERVE);
    
        BENCHMARK::Bench[BENCHMARK::Amount++].Set(Str);
    
        return(true);
      }
    
  4. prendendo i risultati - un solido overhead e spazzatura nei binding degli oggetti
      static ulong Get( const uint AlertInterval = 0 )
      {
        const int Pos = BENCHMARK::Amount - 1;
        const ulong Res = (Pos < 0) ? 0 : BENCHMARK::Bench[Pos].Get();
    
        if (Pos >= 0)
        {
          if (AlertInterval && (Res > AlertInterval))
            ::Alert("Time[" + BENCHMARK::Bench[Pos].Str + "] = " + (string)Res + " mсs.");
    
          BENCHMARK::Amount = Pos;
        }
    
        return(Res);
      }
    


Spero che tu non abbia disabilitato l'ottimizzazione del codice per i test?

Intendo il parametro globale Optimize=0 in metaeditor.ini

 
Renat Fatkhullin:

Tutto il tuo benchmark è sovraccarico di spazzatura e infatti qui c'è una versione pulita e comprensibile (in contrasto con il tuo disordine di codice) di esso:

La tua versione è, purtroppo, allo stadio iniziale della comprensione della convenienza. Conveniente è quando si può fare così.

Forum sul trading, sistemi di trading automatico e test di strategia

Biblioteche: Benchmark

fxsaber, 2020.10.01 23:49

Ora cerchiamo di scoprire dove si trova l'intoppo nella variante standard. Aggiungiamo alcuni simboli al codice sorgente.

    for (long Chart = _B2(::ChartFirst()); (Chart != -1) && !Res; Chart = _B2(::ChartNext(Chart)))
      Res = (Chart != chartID) && _B2(::ChartGetInteger(Chart, CHART_IS_MAXIMIZED));

E vedere immediatamente la ragione.

2020.10.02 00:45:14.113 Alert: Time[Test9.mq5 36 in IsInvisible: ::ChartGetInteger(Chart,CHART_IS_MAXIMIZED)] = 878 mсs.
2020.10.02 00:45:14.114 Alert: Time[Test9.mq5 36 in IsInvisible: ::ChartGetInteger(Chart,CHART_IS_MAXIMIZED)] = 943 mсs.
2020.10.02 00:45:14.114 Alert: Time[Test9.mq5 36 in IsInvisible: ::ChartGetInteger(Chart,CHART_IS_MAXIMIZED)] = 297 mсs.
2020.10.02 00:45:14.116 Alert: Time[Test9.mq5 36 in IsInvisible: ::ChartGetInteger(Chart,CHART_IS_MAXIMIZED)] = 1787 mсs.
2020.10.02 00:45:14.116 Alert: Time[Test9.mq5 35 in IsInvisible: ::ChartNext(Chart)] = 2 mсs.
2020.10.02 00:45:14.117 Alert: Time[Test9.mq5 36 in IsInvisible: ::ChartGetInteger(Chart,CHART_IS_MAXIMIZED)] = 980 mсs.
2020.10.02 00:45:14.117 Alert: Time[Test9.mq5 35 in IsInvisible: ::ChartNext(Chart)] = 2 mсs.
2020.10.02 00:45:14.117 Alert: Time[Test9.mq5 36 in IsInvisible: ::ChartGetInteger(Chart,CHART_IS_MAXIMIZED)] = 59 mсs.
2020.10.02 00:45:14.118 Alert: Time[Test9.mq5 36 in IsInvisible: ::ChartGetInteger(Chart,CHART_IS_MAXIMIZED)] = 803 mсs.
2020.10.02 00:45:14.119 Alert: Time[Test9.mq5 36 in IsInvisible: ::ChartGetInteger(Chart,CHART_IS_MAXIMIZED)] = 1059 mсs.

CHART_IS_MAXIMIZED è troppo lento per i grafici di qualcun altro. Il rapporto sui bug è pronto! È stato molto facile con la biblioteca.


Qual è il problema:

  1. codice illeggibile

  2. entrare in una classe con molte spese generali

  3. costo di archiviazione dello stack di 50 risultati
  4. ottenendo risultati - un enorme overhead e spazzatura nei binding degli oggetti

L'usabilità prevale sull'esiguità delle spese generali. È miserabile se si guarda da vicino come viene implementato. Per esempio, ArrayResize è un overhead, quindi il suo uso è ridotto al minimo.

Spero che tu non abbia disabilitato l'ottimizzazione del codice per i test?

Intendo il parametro globale Optimize=0 in metaeditor.ini

Non mi interessano le modalità lente. Sto guardando le prestazioni dell'EA da combattimento, prestando attenzione all'ottimizzazione algoritmica e anche all'ottimizzazione del compilatore, naturalmente.

 
Renat Fatkhullin:

Tutto il tuo benchmark è sovraccarico di spazzatura e infatti qui c'è una versione pulita e comprensibile (a differenza del tuo disordine di codice) di esso:

Qual è il suo problema:

  1. codice illeggibile

  2. legarsi a una classe con un sacco di spese generali

  3. costo di archiviazione dello stack di 50 risultati
  4. recuperare i risultati - tutto l'overhead e la spazzatura nei binding degli oggetti


Spero che tu non abbia disabilitato l'ottimizzazione del codice per i test?

Intendo il parametro globale Optimize=0 in metaeditor.ini

Qui è in stile C, è semplice e davvero senza spazzatura. Grazie per l'esempio.

Uno degli insegnanti di linguaggio C ha raccomandato di non usare l'underscore _B nei nomi utente
Perché questo prefisso è usato dagli sviluppatori di librerie, programmi, ecc.
E per non incorrere in sovrapposizioni, ha raccomandato di non usarlo.

In mql5 è possibile sovrapporre i vostri nomi?
O i nomi personalizzati sono completamente schermati dai nomi MQ?

 
Roman:

Uno degli insegnanti di C raccomandava di non usare l'underscore _B nei nomi utente
, perché questo prefisso è usato dagli sviluppatori di librerie, software, ecc.
E per evitare sovrapposizioni, raccomandava di non usarlo.

In C, i nomi che iniziano con "_" sono usati come nomi di servizio, di sistema o speciali. In questo caso, penso che sia ammissibile. Poiché questa funzione è utilizzata per la manutenzione e l'esame del codice.

 
Edgar Akhmadeev:

I nomi che iniziano con "_" sono usati in C come nomi di servizio, di sistema o speciali. In questo caso - accettabile, credo. Poiché questa funzione è utilizzata per la manutenzione e l'esame del codice.

Questo è il punto, oltre a mql5, ci sono nomi di servizi MQ per sviluppatori.