MT5 e la velocità in azione

 

La MT5 è una piattaforma agile. Ma ci sono dei colli di bottiglia che annullano tutti gli sforzi per un trading veloce.

Mi piacerebbe raccogliere i problemi qui, discuterli e risolverli da qualche parte con i miei sforzi, da qualche parte con l'aiuto degli sviluppatori.

 

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.

void OnTick()
{
  MqlTick Tick;

  if (SymbolInfo(_Symbol, Tick) && HistorySelect(Tick.time, INT_MAX)) // Взяли история торгов со времени текущего тика.
    // Проверяем актуальность тика через сравнение Tick.time_msc и DEAL_TIME_MSC.
}


Sfortunatamente, 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 (in senso buono, 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.


Si prega di pensare all'introduzione di tali funzioni per lavorare con la storia.

HistoryDealsSelect( const int Index, const int Count = WHOLE_ARRAY );  // Из внутренней таблицы сделок взять сделки, начиная с заданного индекса в таблице.
HistoryOrdersSelect( const int Index, const int Count = WHOLE_ARRAY ); // Из внутренней таблицы ордеров взять ордера, начиная с заданного индекса в таблице.

Chiuderebbero completamente i freni di HistorySelect. Perché risolverebbe il problema di ottenere le ultime offerte a basso costo. In questo momento, è un tormento in esecuzione di combattimento.


Non è sempre possibile controllare le ultime transazioni tramite OnTradeTransaction, quindi è urgente un lavoro rapido con la cronologia.

 

Accesso agli eventi ChartEvent e TradeTransaction.


È stata suggerita un'idea e una delle possibili implementazioni. Quindi lo sto solo copiando qui.

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

Errori, bug, domande

Sergey Dzyublik, 2020.05.20 00:47

Suggerimento agli sviluppatori.
Si prega di considerare l'aggiunta in MQL di una funzione che permetta agli utenti di chiamare indipendentemente l'elaborazione dei "messaggi" accumulati in OnChartEvent dal codice personalizzato.
1) Questo permetterebbe di chiamare la gestione di OnChartEvent tra le iterazioni di un calcolo che richiede tempo, rendendo la GUI dell'utente almeno un po' reattiva senza costruire un orto di: task pool, trasferimento di dati, sincronizzazione di stato, salvataggio e ripristino del contesto...
2) Questo permetterebbe di usare OnChartEvent negli script.

Grazie.

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

Bug, bug, domande

Ilyas, 2020.05.20 09:09

Stai suggerendo di aggiungere la funzione GetNextEvent?

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

Bug, bug, domande

Sergey Dzyublik, 2020.05.20 13:39

Non proprio, preferirei chiamare questa funzione come HandleNextEvent, una firma possibile:

bool HandleNextEvent (ENUM_EVENT_TYPE);


Quando viene chiamato, simile a GetNextEvent, controlla se l'ENUM_EVENT_TYPE specificato è presente nella coda,
e se questo evento è presente, passa automaticamente il controllo al codice utente del gestore corrispondente (OnChartEvent, OnTrade, OnTradeTransaction, ... (graziea fxsaber per l'aggiunta)).
Restituisce true se c'era un evento nella coda, altrimenti restituisce false.


Possibile caso d'uso:

//....
for(int i = 0; i < 10^6; ++i){
   // .... Data Calculations

   if((i % 10^3) == 0){
       while(HandleNextEvent(EVENT_TYPE_ALL));
   }
}
//....

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

Errori, bug, domande

Sergey Dzyublik, 2020.05.20 14:38

2) Proprio così. Se sono interessato all'elaborazione di un evento particolare, e non di tutti gli eventi del sistema, sarebbe bello poter elaborare solo questo tipo di eventi, lasciando l'elaborazione degli altri eventi nel solito modo.
3) Se HandleNextEvent viene chiamato di nuovo durante l'elaborazione - chiama e processa. L'unica cosa che può succedere è lo stack overflow, ma questo è un problema dell'utente e del codice, non dello sviluppatore.
4) Gli eventi che non rientrano nel filtro rimangono nella stessa sequenza e saranno chiamati quando l'utente restituisce il controllo al sistema, come al solito.


Ora dobbiamo fare delle stampelle per arrivare agli stessi eventi TradeTransaction all'interno del codice in esecuzione.

Gli Expert Advisors hanno davvero bisogno di questa caratteristica per l'applicazione di combattimento.

 
fxsaber:

Non è sempre possibile monitorare le transazioni recenti tramite OnTradeTransaction, quindi un rapido lavoro con lo storico è rilevante.

Per favore, fate un esempio quando non è possibile controllare?

 
prostotrader:

Per favore, mi faccia un esempio quando non c'è controllo?

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

Peculiarità di mql5, consigli e trucchi

fxsaber, 2020.04.23 19:51

Le frecce di apertura/chiusura che MT5 piazza automaticamente in tempo reale sono basate su eventi TradeTransaction.


Ho appena visto che questi eventi (apertura e chiusura di circa una dozzina di posizioni) non hanno raggiunto il terminale a causa di una momentanea interruzione della connessione - è stato così casuale, ero seduto al mio PC e li ho guardati in prima persona. Di conseguenza non ci sono frecce corrispondenti.


E, come è stato detto a volte qui, non si può fare affidamento su OnTradeTransaction negli EA da combattimento. Peccato che non ci sia un meccanismo pubblico affidabile per gestire OrderSendAsync.


E anche quando diversi OrderSend sono inseriti nel codice. Quando un OrderSend dipende dal precedente.

 
fxsaber:

Anche quando si inseriscono più OrderSend all'interno del codice. Quando un OrderSend dipende dal precedente OrderSend.

Se c'è un'interruzione della comunicazione, non verrà aggiunto nulla neanche alla storia!

Ho usatoOrderSendAsync per oltre 5 anni(allora c'erano problemi con OrderSend) + OnTradeTransaction() solo in modalità combattimento - nessun problema!

Se c'è un'interruzione nella connessione, allora viene scoperto dalla procedura guidata che viene assegnata ad ogni ordine (nel FOREX è difficile da fare perché i nomi dei simboli non sono standardizzati).

Документация по MQL5: Основы языка / Функции / Функции обработки событий
Документация по MQL5: Основы языка / Функции / Функции обработки событий
  • www.mql5.com
В языке MQL5 предусмотрена обработка некоторых предопределенных событий. Функции для обработки этих событий должны быть определены в программе MQL5: имя функции, тип возвращаемого значения, состав параметров (если они есть) и их типы должны строго соответствовать описанию функции-обработчика события. Именно по типу возвращаемого значения и по...
 
prostotrader:

Se c'è un'interruzione della comunicazione, non verrà aggiunto nulla neanche alla storia!

Ho usatoOrderSendAsync per oltre 5 anni(allora c'erano problemi con OrderSend) + OnTradeTransaction() solo in modalità combattimento - nessun problema!

Non si può fare a meno di notare come per anni avete affondato i denti in Async+OnTrade. Se fai l'attualizzazione dei dati attraverso questo meccanismo e tutto il resto, non ci sono problemi.

Per favore, non dire "non sai proprio cucinare", almeno qui.

 
fxsaber:

Non si può fare a meno di notare come per anni avete spinto per Async+OnTrade. Si fa anche l'aggiornamento dei dati attraverso questo meccanismo e tutto il resto, perché non c'è nessun problema.

Per favore, non dichiarate almeno qui "non sapete cucinare".

State "combattendo" per microsecondi e allo stesso tempo state scrivendo tonnellate di codice, che consuma anche tempo,

e il 99% delle volte non ne hai bisogno.

 
Vi incoraggio a parlare solo in modo costruttivo.
 
fxsaber:

Accesso agli eventi ChartEvent e TradeTransaction.

È stata suggerita un'idea e una delle possibili implementazioni. Quindi lo sto copiando qui.

Ora, per avere accesso a questi eventi TradeTransaction all'interno del codice in esecuzione, dobbiamo usare le stampelle.

State facendo delle stampelle in una direzione sbagliata:

Lasciare nelle funzioni OnXXX solo la copia degli eventi (parametri) in coda e chiamare la funzione principale OnMain. Spostate tutto il loro codice nelle funzioni duplicate di 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?

 
A100:

Lasciare le funzioni OnXXX solo per copiare gli eventi (parametri) nella coda e chiamare la funzione principale OnMain. Spostare tutto il 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 della coda come parametri.

Per favore, datemi uno schema-codice rudimentale di questa idea. A prima vista sembra un completo malinteso.

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

Motivazione: