MT5 e la velocità in azione - pagina 4

 
Capisco che tutto dipende dall'attrezzatura
 
Alexsandr San:
Capisco che dipende dall'attrezzatura

Niente affatto!

2020.05.29 15:08:44.938 Terminal        Windows 7 Service Pack 1 build 7601, Intel Core i7-6850 K  @ 3.60 GHz, 23 / 31 Gb memory, 43 / 226 Gb disk, IE 11, UAC, Admin, GMT+3
 
Alexsandr San:
Credo che dipenda dall'hardware.

Non credo ))))

E nemmeno da un computer occupato...

 
prostotrader:

Niente affatto!

Sì, la tua macchina e quella precedente hanno risultati diversi - quindi mi sbaglio, non sono i mezzi di alimentazione

 
Aleksey Mavrin:

Come può esserci più di un evento in coda in onMain se ogni evento chiama onMain per gestire la coda?

OnMain è una funzione. Non è codice vero e proprio, ma un caso speciale - una risposta all'affermazione "Non c'è modo di conoscere lo stato della coda reale correntementre si esegue la funzione OnMain".È un approccio diverso ai calcoli stessi

 
A100:

OnMain è una funzione. Non è il codice attuale, ma un caso speciale - una risposta all'affermazione "Non c'è modo di conoscere lo stato della coda reale correntedurante l'esecuzione della funzione OnMain".Questo è un approccio diverso ai calcoli stessi

Quindi, per sicurezza, OnMain...

:) ;)
 
fxsaber:


In Combat Advisors, ho avvolto funzioni ovunque in posti sospetti a _B(FuncName(...), AlertTime). Ecco un breve estratto del registro dalle voci più recenti.

La colonna del tempo mostra quanto spesso si verificano i blocchi.

Lei sta sostituendo dei concetti.

Ecco la sua dichiarazione originale:

Sfortunatamente, tale chiamata HistorySelect dura 5-30 millisecondi (l'ho misurata io stesso in Release-EX5). Quando l'Expert Advisor fa diversi aggiornamenti di questo tipo in OnTick (in un buon modo, dovrebbe essere fatto dopo qualsiasi pausa. Per esempio, dopo ogni OrderSend.), allora tutto diventa follemente costoso/lungo. HistorySelect può aggiungere fino a diversi secondi in un singolo OnTick.

Anche nel vostro terminale, il tempo medio di 0,2ms per chiamata è nettamente inferiore ai valori specificati nella dichiarazione originale.

Ora stai dicendo che a volte il tempo di esecuzione di una funzione può essere notevolmente più lungo della media. Questa è una domanda diversa.

Qualsiasi richiesta di HistorySelect() è una chiamata a pieno titolo alle basi del terminale sotto sincronizzatori. Questo è inevitabile. Sì, tenendo conto della presenza della sincronizzazione degli accessi, non possiamo garantire un tempo molto breve di esecuzione di questa funzione.

La soluzione proposta aggiungendo le funzioni HistoryDealsSelect() e HistoryOrdersSelect() non cambia assolutamente nulla in questo senso.

Lo script per controllare il tempo massimo e medio:

void OnStart()
  {
   MqlTick Tick;
   SymbolInfoTick(_Symbol, Tick);
//---
   ulong start,end,max_time=0,avr_time=0;
   int   count=100000;
   for(int i=0; i<count; i++)
     {
      start=GetMicrosecondCount();
      HistorySelect(Tick.time, INT_MAX);
      end=GetMicrosecondCount()-start;
      //--- >1 ms
      if(end>1000)
         Print(" > 1 ms for one HistorySelect: ",DoubleToString(end/1000.0,2)," ms");
      //---
      if(end>max_time)
         max_time=end;
      avr_time+=end;
     }
   Print("Last tick time. Selected orders: ",HistoryOrdersTotal(),"; max time: ",DoubleToString(max_time/1000.0,3)," ms; avr time: ",DoubleToString(avr_time/1000.0/count,3)," ms; ",count," iterations");
//---
   Tick.time=(Tick.time/86400)*86400;
   max_time=0;
   for(int i=0; i<count; i++)
     {
      start=GetMicrosecondCount();
      HistorySelect(Tick.time, INT_MAX);
      end=GetMicrosecondCount()-start;
      //--- >1 ms
      if(end>1000)
         Print(" > 1 ms for one last day HistorySelect: ",DoubleToString(end/1000.0,2)," ms");
      //---
      if(end>max_time)
         max_time=end;
      avr_time+=end;
     }
   Print("Last day. Selected orders: ",HistoryOrdersTotal(),"; max time: ",DoubleToString(max_time/1000.0,3)," ms; avr time: ",DoubleToString(avr_time/1000.0/count,3)," ms; ",count," iterations");
//---
   HistorySelect(0, INT_MAX);
   Print("Orders total: ",HistoryOrdersTotal());
  }
2020.05.29 17:22:04.195 TestHistorySelect (EURJPY,H1)   Last tick time. Selected orders: 0; max time: 0.034 ms; avr time: 0.001 ms; 100000 iterations
2020.05.29 17:22:06.771 TestHistorySelect (EURJPY,H1)   Last day. Selected orders: 141; max time: 0.101 ms; avr time: 0.027 ms; 100000 iterations
2020.05.29 17:22:08.039 TestHistorySelect (EURJPY,H1)   Orders total: 31448
 
Anton:

Uno script per controllare i tempi massimi e medi:

Non commenterò la sua opinione prima di averla citata. Ecco il risultato dell'esecuzione del tuo script.

Più precisamente, non potevo aspettare che finisse, così ho cambiato il numero di iterazioni da 100K a 1K.

        Last tick time. Selected orders: 0; max time: 3.880 ms; avr time: 1.315 ms; 1000 iterations
        Last day. Selected orders: 2061; max time: 7.131 ms; avr time: 4.309 ms; 1000 iterations
        Orders total: 50113

Questo merita almeno un voto soddisfacente?

Guardate l'assurdità della situazione. Per scoprire stupidamente il numero di accordi dobbiamo chiamare HistorySelect! Questo, per dirla tutta, non è razionale.


Spendo al massimo decine di millisecondi per ogni tick solo a causa di HistorySelect.

 
A100:

Nella sua forma più semplice:

Dovete solo cambiare il vostro approccio ai calcoli stessi (fare dei ritorni intermedi con la frequenza richiesta dal compito). Ma se è complicato, considera al 1° stadio che OnMain è assente per te (metti il codice principale non in OnMain ma in OnTrade2XX), quindi non devi imparare nulla in OnMain

Grazie, è esattamente come l'ho capito dall'inizio ed è per questo che ho detto che non l'ho capito completamente. Ecco un esempio di uno scenario semplice.


Si fa un OrderSend. Se una certa posizione non ha chiuso sul segno subito dopo l'OrderSend, si fa un altro OrderSend. Questa è tutta logica, che deve essere programmata. Async non è usato.


Ora la situazione che si è verificata per il nostro robot. Hai inviato un OrderSend e mentre viene eseguito il Limiter è scattato e il TP della posizione di cui sopra è stato eseguito.


Qual è l'implementazione del robot schematicamente? Non so come implementarlo senza frenare HistorySelect o OnTradeTransaction-spia che dà accesso all'intera storia delle transazioni in qualsiasi punto del codice. Se fosse implementato un meccanismo di accesso alla coda degli eventi, l'esempio precedente sarebbe risolto in modo elementare.


Tutti coloro che sono forti in MT5, compresi gli sviluppatori, per favore mostratemi come implementare questa (due righein grassetto sopra) logica di trading non complicata (ho paura di menzionare anche complessa).

 
A100:

OnMain è una funzione. Questo non è il codice attuale, ma un caso speciale - una risposta all'affermazione " Non c'è modo di conoscere lo stato della coda reale corrente durante l'esecuzione della funzione OnMain".Questo è un approccio diverso ai calcoli stessi

Beh, è così, no? Ed è di questo che parlavano i ragazzi. Per implementarlo, è necessario cambiare la struttura di esecuzione dei programmi MQL, o a) almeno in una a due thread o b) aggiungere un meccanismo di accesso e gestione delle code.

Con la struttura attuale, lo schema da lei proposto è impossibile da attuare.