MT5 e la velocità in azione - pagina 2

 
fxsaber:

Per favore, date un diagramma-codice rudimentale per questa idea. A prima vista sembra un completo malinteso.

Durante l'esecuzione della funzione OnMain non c'è modo di conoscere lo stato della coda reale corrente. L'unico workaround per farlo è un programma spyware, come indicato nel link.

Nella sua forma più semplice:

OnXXX( параметры )
{
        запомнить параметры (поместить в очередь)
        OnMain();
}
On2XX( параметры )
{
/*вычисления*/
        поменять приоритет обработки событий (если нужно)
/*вычисления*/
        промежуточный return (если нужно) 
/*вычисления*/
}
void OnMain()
{
        прочитать приоритет обработки событий
        для каждой группы событий
                извлечь параметры из очереди
                OnTradeXXX( параметры )
                удалить событие из очереди
}

Dovete solo cambiare l'approccio ai calcoli stessi (fare il ritorno intermedio tutte le volte che il compito lo richiede). Ma se è difficile, considerate al 1º passo che OnMain non esiste per voi (spostate il codice principale non in OnMain, ma in On2XX), rispettivamente, in OnMain non dovete imparare nulla

 
A100:

Le stampelle vengono fatte nella direzione sbagliata:

Lasciate le funzioni OnXXX solo copiando gli eventi (parametri) nella coda e chiamando la funzione principale OnMain. Spostare tutto il loro codice per duplicare le funzioni On2XX. E chiamate queste funzioni On2XX duplicate dall'OnMain nella sequenza in cui avete bisogno, passando loro a turno i dati delle code come parametri.

Poi eseguire le misurazioni e mostrare il guadagno di velocità, e poi si può suggerire di integrare MQL con funzionalità appropriate. Ma perché aggiungere, se hai già fatto tutto da solo qui e ora?

Non è di questo che stai scrivendo.
Il problema è che la funzionalità di riempimento dei campi nelle variabili di input della funzione "OntaredeTransaction" non corrisponde alla descrizione data nella Guida, in peggio:
cioè molti campi non sono riempiti nelle chiamate e anche nella chiamata finale di TRADE_TRANSACTION_HISTORY_ADD.
Di conseguenza, tutti i commercianti sono agonizzanti qui per determinare in qualche modo questi parametri mancanti al momento dell'arrivo.
Ci sono state molte discussioni qui, basta fare una ricerca sul forum - la scarsa funzionalità "OntaredeTransaction" causa spese aggiuntive sia in tempo che "carica" i commercianti con tempo extra speso per lo sviluppo di codice adeguatamente funzionante (cioè enormi perdite di tempo e colossale inefficacia a livello di comunità).
Le risposte attuali degli sviluppatori come "Se hai un simbolo di esecuzione di mercato, avrà valore di prezzo zero; dovrebbe essere così" (Link).(Link) - questo è UNNORMAL, ancora una volta -
mancanza di valori esaustivi nell'ultima chiamata di funzione porta ad un sacco di lavoro extra.

Новая версия платформы MetaTrader 5 build 2450: Сервис "Подписки", улучшения в интерфейсе и удобные функции в MetaEditor
Новая версия платформы MetaTrader 5 build 2450: Сервис "Подписки", улучшения в интерфейсе и удобные функции в MetaEditor
  • 2020.05.18
  • www.mql5.com
В пятницу 22 мая 2020 года будет выпущена обновленная версия платформы MetaTrader 5...
 
fxsaber:

HistorySelect.


Questa è una caratteristica follemente costosa. E purtroppo, nessuna quantità di cache può rendere la sua velocità accettabile ora.


Per esempio, negli EA sul campo di battaglia è importante lavorare con dati reali. In particolare, che i tick di Market Watch e CopyTicks non siano obsoleti, se possibile.

Per fare questo, ci sono meccanismi non molto buoni, ma forzati per controllare la pertinenza dei dati sui prezzi attuali. Una parte di questo meccanismo consiste nel rilevare situazioni in cui un trade su un simbolo è passato dopo l'ultimo tick. Questo non accade raramente, quindi è importante sapere se la zecca attuale è ancora aggiornata o no.


Per questo rilevamento, è necessario essere in grado di accedere alla storia degli affari recenti. Si fa usando la HistorySelect nel seguente modo schematico.


Purtroppo, una tale chiamata di HistorySelect richiede 5-30 millisecondi (l'ho misurato io stesso in Release-EX5). Quando l'Expert Advisor fa diversi aggiornamenti di questo tipo in OnTick (dovrebbe essere fatto dopo ogni pausa, per esempio, dopo ogni OrderSend), allora tutto diventa follemente costoso/lungo. HistorySelect può consumare collettivamente diversi secondi in un singolo OnTick.


Cari sviluppatori, perché è così caro? Questa funzione può essere eseguita istantaneamente con una corretta implementazione.

Avete prove che "una tale chiamata a HistorySelect dura 5-30 millisecondi"?

Se ho capito bene la tua idea, allora il codice di test dovrebbe assomigliare a questo:

void OnStart()
  {
   MqlTick Tick;
   SymbolInfoTick(_Symbol, Tick);
   ulong start=GetMicrosecondCount();
   for(int i=0; i<100000; i++)
     {
      HistorySelect(Tick.time, INT_MAX);
     }
   ulong end=GetMicrosecondCount()-start;
   Print("100000 HistorySelect = ",DoubleToString(end/1000.0,2)," ms");
  }

Ecco come funzionano le 100000 query:

100000 HistorySelect = 141.63 ms
 
Anton:

Avete prove che "una tale chiamata a HistorySelect dura 5-30 millisecondi"?

Se ho capito bene il tuo punto, allora il codice di test dovrebbe assomigliare a questo:

Ecco come funzionano le 100.000 interrogazioni:

E una domanda? Non sarei sorpreso se il compilatore, quando ottimizza, facesse proprio questo)))
 
Anton:

Avete prove che "una tale chiamata a HistorySelect dura 5-30 millisecondi"?

Se ho capito bene il tuo punto, allora il codice di test dovrebbe assomigliare a questo:

Ecco come funzionano le 100.000 interrogazioni:

Eseguire lo script.

        100000 HistorySelect = 19493.96 ms


Lancia un altro script.

#define  PRINT(A) Print(#A + " = " + (string)(A))

void OnStart()
{
  if (HistorySelect(0, INT_MAX))
  {
    PRINT(HistoryDealsTotal());
    PRINT(HistoryOrdersTotal());
  }
}


HistoryDealsTotal() = 17828
HistoryOrdersTotal() = 22142


Conteggio delle battaglie normali. Non HFT.


A proposito, il tuo script ha mostrato che HistorySelect ricalcola tutto ogni volta. E i parametri di input non sono cambiati, la tabella della storia non è stata aggiornata, altre funzioni HistorySelect non sono state chiamate.

 
fxsaber:

Eseguire lo script.

Allora sono necessari dei dettagli.

Il mio test è stato eseguito su non il più veloce "Intel Xeon E5-2630 v4 @ 2.20GHz" con molti altri processi in background.

La storia del mio conto di prova mostra 31315 ordini più o meno uniformemente dal 2009, compresi 8 ordini per oggi.

Forse, avevi qualche script o Expert Advisor in esecuzione allo stesso tempo causando un carico drastico dei database del terminale. Provatelo su un terminale "pulito".

Test più informativo:

void OnStart()
  {
   MqlTick Tick;
   SymbolInfoTick(_Symbol, Tick);
//---   
   ulong start=GetMicrosecondCount();
   int count=100000;
   for(int i=0; i<count; i++)
     {
      HistorySelect(Tick.time, INT_MAX);
     }
   ulong end=GetMicrosecondCount()-start;

   Print(count," HistorySelect = ",DoubleToString(end/1000.0,2)," ms");
   Print("Selected = ",HistoryOrdersTotal());
//---   
   Tick.time=(Tick.time/86400)*86400;
   
   start=GetMicrosecondCount();
   count=1000;
   for(int i=0; i<count; i++)
     {
      HistorySelect(Tick.time, INT_MAX);
     }
   end=GetMicrosecondCount()-start;

   Print(count," HistorySelect = ",DoubleToString(end/1000.0,2)," ms");
   Print("Selected = ",HistoryOrdersTotal());
//---   
   HistorySelect(0, INT_MAX);
   Print("Selected = ",HistoryOrdersTotal());
  }

Tre corse:

2020.05.29 13:53:14.281 TestHistorySelect (EURUSD,H1)   100000 HistorySelect = 141.76 ms
2020.05.29 13:53:14.281 TestHistorySelect (EURUSD,H1)   Selected = 0
2020.05.29 13:53:14.284 TestHistorySelect (EURUSD,H1)   1000 HistorySelect = 2.82 ms
2020.05.29 13:53:14.284 TestHistorySelect (EURUSD,H1)   Selected = 8
2020.05.29 13:53:15.566 TestHistorySelect (EURUSD,H1)   Selected = 31315
2020.05.29 13:53:16.930 TestHistorySelect (EURUSD,H1)   100000 HistorySelect = 138.30 ms
2020.05.29 13:53:16.930 TestHistorySelect (EURUSD,H1)   Selected = 0
2020.05.29 13:53:16.933 TestHistorySelect (EURUSD,H1)   1000 HistorySelect = 2.61 ms
2020.05.29 13:53:16.933 TestHistorySelect (EURUSD,H1)   Selected = 8
2020.05.29 13:53:18.176 TestHistorySelect (EURUSD,H1)   Selected = 31315
2020.05.29 13:53:22.217 TestHistorySelect (EURUSD,H1)   100000 HistorySelect = 142.94 ms
2020.05.29 13:53:22.217 TestHistorySelect (EURUSD,H1)   Selected = 0
2020.05.29 13:53:22.220 TestHistorySelect (EURUSD,H1)   1000 HistorySelect = 2.57 ms
2020.05.29 13:53:22.220 TestHistorySelect (EURUSD,H1)   Selected = 8
2020.05.29 13:53:23.498 TestHistorySelect (EURUSD,H1)   Selected = 31315
 
Anton:

Allora sono necessari dei dettagli.

Il mio test è stato eseguito su non il più veloce "Intel Xeon E5-2630 v4 @ 2.20GHz" con molti altri processi in background.

Il conto di prova aveva 31315 ordini nella sua storia più o meno uniformemente dal 2009, compresi 8 ordini per oggi.

Forse, avevi qualche script o Expert Advisor in esecuzione allo stesso tempo che ha caricato drasticamente i database del terminale. Provatelo su un terminale "pulito".

Terminale vuoto sullo stesso account e sulla stessa macchina.

        100000 HistorySelect = 19367.01 ms


Su altri conti e terminali la stessa immagine. Configurazione.

2020.05.29 13:53:44.766 Terminal        ICMarkets - MetaTrader 5 x64 build 2453 started for International Capital Markets Pty Ltd.
2020.05.29 13:53:44.766 Terminal        Windows 7 Service Pack 1 build 7601, Intel Core i7-2700 K  @ 3.50 GHz, 6 / 15 Gb memory, 4 / 29 Gb disk, IE 11, Admin, GMT+2


Chiedo ai lettori di dare i loro risultati di questo script.

void OnStart()
{
  // https://www.mql5.com/ru/forum/342090/page2#comment_16607997
#define  PRINT(A) Print(#A + " = " + (string)(A))
  
  if (HistorySelect(0, INT_MAX))
  {
    PRINT(HistoryDealsTotal());
    PRINT(HistoryOrdersTotal());
  }

   // https://www.mql5.com/ru/forum/342090/page2#comment_16607922
   MqlTick Tick;
   SymbolInfoTick(_Symbol, Tick);
   ulong start=GetMicrosecondCount();
   for(int i=0; i<100000; i++)
     {
      HistorySelect(Tick.time, INT_MAX);
     }
   ulong end=GetMicrosecondCount()-start;
   Print("100000 HistorySelect = ",DoubleToString(end/1000.0,2)," ms");
}
 
Anton:

Un test più informativo:

Tre partenze:

        100000 HistorySelect = 18344.01 ms
        Selected = 0
        1000 HistorySelect = 602.77 ms
        Selected = 1169
        Selected = 22142
        100000 HistorySelect = 18331.15 ms
        Selected = 0
        1000 HistorySelect = 446.45 ms
        Selected = 1169
        Selected = 22142
        100000 HistorySelect = 18495.35 ms
        Selected = 0
        1000 HistorySelect = 549.40 ms
        Selected = 1169
        Selected = 22142

Terminale 2460 vuoto.


ZS Eseguire su un conto vuoto.

        100000 HistorySelect = 28.30 ms
        Selected = 0
        1000 HistorySelect = 0.28 ms
        Selected = 0
        Selected = 0


La velocità sembra essere fortemente influenzata dal numero di scambi, non dagli ordini.

 
fxsaber:

Terminale vuoto sullo stesso account e sulla stessa macchina.


Su altri conti e terminali lo stesso schema. Configurazione.


Chiedo ai lettori di citare i loro risultati di questo script.

Non prova nulla, ma il fatto che ad ogni nuova corsa (su un simbolo diverso), il tempo aumenta - è allarmante...

2020.05.29 13:59:36.625 test1 (USDJPY,H1)       HistoryDealsTotal() = 1
2020.05.29 13:59:36.626 test1 (USDJPY,H1)       HistoryOrdersTotal() = 0
2020.05.29 13:59:36.642 test1 (USDJPY,H1)       100000 HistorySelect = 16.00 ms
2020.05.29 13:59:53.522 test1 (EURUSD,H1)       HistoryDealsTotal() = 1
2020.05.29 13:59:53.522 test1 (EURUSD,H1)       HistoryOrdersTotal() = 0
2020.05.29 13:59:53.546 test1 (EURUSD,H1)       100000 HistorySelect = 24.36 ms
2020.05.29 14:00:03.640 test1 (USDCHF,H1)       HistoryDealsTotal() = 1
2020.05.29 14:00:03.640 test1 (USDCHF,H1)       HistoryOrdersTotal() = 0
2020.05.29 14:00:03.669 test1 (USDCHF,H1)       100000 HistorySelect = 29.25 ms
2020.05.29 14:00:14.994 test1 (GBPUSD,H1)       HistoryDealsTotal() = 1
2020.05.29 14:00:14.994 test1 (GBPUSD,H1)       HistoryOrdersTotal() = 0
2020.05.29 14:00:15.026 test1 (GBPUSD,H1)       100000 HistorySelect = 31.76 ms
 
Сергей Таболин:

Necessità di operare su un conto con una lunga storia di trading.