MT5 et la vitesse en action - page 48

 
fxsaber:

L'impression et l'alerte ne sont pas asynchrones ?

Je voulais rendre ces fonctions asynchrones. J'ai essayé une implémentation via ChartEvent - cela fonctionne. Mais c'est très lent. J'avais déterré ça.

#include <fxsaber\Benchmark\Benchmark.mqh> // https://www.mql5.com/ru/code/31279

void OnTick()
{
  _B(EventChartCustom(ChartFirst(), 123, 0, 0, NULL), 1);
}


2020.10.07 12:38:04.579 Alert: Time[Test9.mq5 5 in OnTick: EventChartCustom(ChartFirst(),123,0,0,NULL)] = 100 mсs.
2020.10.07 12:38:06.842 Alert: Time[Test9.mq5 5 in OnTick: EventChartCustom(ChartFirst(),123,0,0,NULL)] = 170 mсs.
2020.10.07 12:38:07.924 Alert: Time[Test9.mq5 5 in OnTick: EventChartCustom(ChartFirst(),123,0,0,NULL)] = 765 mсs.
2020.10.07 12:38:08.359 Alert: Time[Test9.mq5 5 in OnTick: EventChartCustom(ChartFirst(),123,0,0,NULL)] = 377 mсs.
2020.10.07 12:38:09.246 Alert: Time[Test9.mq5 5 in OnTick: EventChartCustom(ChartFirst(),123,0,0,NULL)] = 66 mсs.
2020.10.07 12:38:14.645 Alert: Time[Test9.mq5 5 in OnTick: EventChartCustom(ChartFirst(),123,0,0,NULL)] = 692 mсs.
2020.10.07 12:38:14.729 Alert: Time[Test9.mq5 5 in OnTick: EventChartCustom(ChartFirst(),123,0,0,NULL)] = 6427 mсs.
2020.10.07 12:38:15.140 Alert: Time[Test9.mq5 5 in OnTick: EventChartCustom(ChartFirst(),123,0,0,NULL)] = 479 mсs.
2020.10.07 12:38:15.222 Alert: Time[Test9.mq5 5 in OnTick: EventChartCustom(ChartFirst(),123,0,0,NULL)] = 125 mсs.
2020.10.07 12:38:15.373 Alert: Time[Test9.mq5 5 in OnTick: EventChartCustom(ChartFirst(),123,0,0,NULL)] = 606 mсs.


On a renoncé à une fonction aussi coûteuse dans les endroits critiques.


Au sujet d'Alert.

Jusqu'à présent, nous pouvons dire avec certitude qu'Alert n'est pas possible aux endroits critiques. L'asynchronisme est nécessaire.

 

Reproduit les freins de SymbolInfoTick. Et pas de test de stress. La nécessité pratique vous pousse à l'écrire de cette façon.

#include <fxsaber\Benchmark\Benchmark.mqh> // https://www.mql5.com/ru/code/31279

// Возвращает время Обзора рынка в миллисекундах.
long TimeCurrentMsc()
{
  long Res = 0;
  
  MqlTick Tick;
  
  for (int i = SymbolsTotal(true); i >= 0; i--) 
  {
    const string Symb = SymbolName(i, true);
    
    if (_B(SymbolInfoTick(Symb, Tick), 10) && (Tick.time_msc > Res))
      Res = Tick.time_msc;
  }

  return(Res);
}

void OnTick()
{ 
  TimeCurrentMsc();
}


Suivez cette instruction pour une relecture rapide.

Forum sur le trading, les systèmes de trading automatisés et les tests de stratégies de trading

L'envoi synchrone d'ordres signale une exécution réussie plus rapidement qu'un ping au serveur commercial

fxsaber, 2020.09.30 20:36

  1. Ouvrez un compte de démonstration surle serveur RannForex.
  2. Ouvrez les symboles Forex dans l'aperçu du marché et autorisez le trading automatique.
  3. Sur un seul graphique, lancez cet EA.
  4. Lancez ce script sur le même graphique - il clonera l'EA sur d'autres symboles. Exécutez-le avec inAmount = 15.
  5. Attendez ces messages et observez le journal.


Sur une machine rapide, le résultat avec 30 caractères dans Market Watch.

2020.10.07 13:28:01.931 Test9 (NZDCHF,H1)       Alert: Bench_Stack = 0, Time[Test9.mq5 14 in TimeCurrentMsc: SymbolInfoTick(Symb,Tick)] = 65 mсs.
2020.10.07 13:28:02.344 Test9 (EURAUD,H1)       Alert: Bench_Stack = 0, Time[Test9.mq5 14 in TimeCurrentMsc: SymbolInfoTick(Symb,Tick)] = 11 mсs.
2020.10.07 13:28:02.730 Test9 (EURAUD,H1)       Alert: Bench_Stack = 0, Time[Test9.mq5 14 in TimeCurrentMsc: SymbolInfoTick(Symb,Tick)] = 15 mсs.
2020.10.07 13:28:02.800 Test9 (AUDCHF,H1)       Alert: Bench_Stack = 0, Time[Test9.mq5 14 in TimeCurrentMsc: SymbolInfoTick(Symb,Tick)] = 11 mсs.
2020.10.07 13:28:05.471 Test9 (GBPAUD,H1)       Alert: Bench_Stack = 0, Time[Test9.mq5 14 in TimeCurrentMsc: SymbolInfoTick(Symb,Tick)] = 30 mсs.
2020.10.07 13:28:08.675 Test9 (NZDCHF,H1)       Alert: Bench_Stack = 0, Time[Test9.mq5 14 in TimeCurrentMsc: SymbolInfoTick(Symb,Tick)] = 28 mсs.
2020.10.07 13:28:08.675 Test9 (GBPAUD,H1)       Alert: Bench_Stack = 0, Time[Test9.mq5 14 in TimeCurrentMsc: SymbolInfoTick(Symb,Tick)] = 120 mсs.
2020.10.07 13:28:09.697 Test9 (CADCHF,H1)       Alert: Bench_Stack = 0, Time[Test9.mq5 14 in TimeCurrentMsc: SymbolInfoTick(Symb,Tick)] = 13 mсs.
2020.10.07 13:28:10.063 Test9 (EURCAD,H1)       Alert: Bench_Stack = 0, Time[Test9.mq5 14 in TimeCurrentMsc: SymbolInfoTick(Symb,Tick)] = 29 mсs.
2020.10.07 13:28:11.741 Test9 (CADJPY,H1)       Alert: Bench_Stack = 0, Time[Test9.mq5 14 in TimeCurrentMsc: SymbolInfoTick(Symb,Tick)] = 32 mсs.
2020.10.07 13:28:12.597 Test9 (EURCAD,H1)       Alert: Bench_Stack = 0, Time[Test9.mq5 14 in TimeCurrentMsc: SymbolInfoTick(Symb,Tick)] = 33 mсs.


J'espère que je ne suis pas le seul à me reproduire. Bien sûr, le décalage n'est pas aussi important que ce qui a été montré précédemment. Mais il sera possible d'aller au fond des causes beaucoup plus rapidement ici.


ZZY TimeCurrentMsc n'est pas saisi dans MQL5 pour une raison quelconque, malgré des demandes répétées.

 
fxsaber:

On a renoncé à une fonction aussi coûteuse à des endroits critiques.

C'est un inconvénient important. Parce que le modèle d'événement MQL est incomplet - il n'y a pas d'événement zéro, c'est-à-dire l'événement qui est appelé lorsqu'il n'y a pas d'autres événements dans la file d'attente. Elle peut être émulée par un événement personnalisé. Mais compte tenu de cet inconvénient, le modèle événementiel n'a aucun sens pour ceux qui s'intéressent à la vitesse

 
fxsaber:

EventChartCustom est cher.

Qu'en est-il sansChartFirst()?

 
Andrey Khatimlianskii:

Et sans ChartFirst() ?

#include <fxsaber\Benchmark\Benchmark.mqh> // https://www.mql5.com/ru/code/31279

long GetAnotherChart()
{
  long Chart = ::ChartFirst();
  
  while (Chart == ChartID())
    Chart = ChartNext(Chart);
 
  return(Chart);     
}


void OnTick()
{  
  const long Chart = GetAnotherChart();
  
  if (Chart)
    _B(EventChartCustom(Chart, 123, 0, 0, NULL), 1);
  
  _B(EventChartCustom(0, 123, 0, 0, NULL), 1);
}


2020.10.07 14:49:09.786 Alert: Bench_Stack = 0, Time[Test9.mq5 19 in OnTick: EventChartCustom(Chart,123,0,0,NULL)] = 349 mсs.
2020.10.07 14:49:09.786 Alert: Bench_Stack = 0, Time[Test9.mq5 21 in OnTick: EventChartCustom(0,123,0,0,NULL)] = 81 mсs.
2020.10.07 14:49:09.866 Alert: Bench_Stack = 0, Time[Test9.mq5 19 in OnTick: EventChartCustom(Chart,123,0,0,NULL)] = 248 mсs.
2020.10.07 14:49:09.866 Alert: Bench_Stack = 0, Time[Test9.mq5 21 in OnTick: EventChartCustom(0,123,0,0,NULL)] = 24 mсs.
2020.10.07 14:49:10.095 Alert: Bench_Stack = 0, Time[Test9.mq5 19 in OnTick: EventChartCustom(Chart,123,0,0,NULL)] = 163 mсs.
2020.10.07 14:49:10.095 Alert: Bench_Stack = 0, Time[Test9.mq5 21 in OnTick: EventChartCustom(0,123,0,0,NULL)] = 116 mсs.
2020.10.07 14:49:10.810 Alert: Bench_Stack = 0, Time[Test9.mq5 19 in OnTick: EventChartCustom(Chart,123,0,0,NULL)] = 600 mсs.
2020.10.07 14:49:10.811 Alert: Bench_Stack = 0, Time[Test9.mq5 21 in OnTick: EventChartCustom(0,123,0,0,NULL)] = 53 mсs.
2020.10.07 14:49:10.870 Alert: Bench_Stack = 0, Time[Test9.mq5 19 in OnTick: EventChartCustom(Chart,123,0,0,NULL)] = 137 mсs.
2020.10.07 14:49:10.870 Alert: Bench_Stack = 0, Time[Test9.mq5 21 in OnTick: EventChartCustom(0,123,0,0,NULL)] = 54 mсs.

Il est plus coûteux d'envoyer le dossier à quelqu'un d'autre qu'au vôtre.

 
A100:

Il s'agit d'un défaut important. Parce que le modèle d'événement MQL est incomplet - il n'existe pas d'événement nul, c'est-à-dire un événement qui est appelé lorsqu'il n'y a pas d'autres événements dans la file d'attente. Elle peut être émulée par un événement personnalisé. Mais, compte tenu de cet inconvénient, le modèle événementiel n'a aucun sens pour ceux qui s'intéressent à la vitesse.

OnTimer vous permet de passer des appels en arrière-plan jusqu'à 16 ms.
 
Renat Fatkhullin:
OnTimer vous permet de passer des appels en arrière-plan avec une fréquence allant jusqu'à 16 ms.

Correct, c'est-à-dire qu'on perd au moins16ms pour rien (on peut revenir au plus tôt).Et nous pourrions n'en perdre aucun s'il y avait un événement nul gratuit ou des événements personnalisés gratuits. Et maintenant le modèle d'événement dans le cas ci-dessous fonctionne de manière limitée :

Forum sur le trading, les systèmes de trading automatisé et les tests de stratégies de trading

MT5 et la vitesse en action

fxsaber, 2020.10.06 01:27

Vous êtes complètement à côté de la plaque. Disons que vous devez ouvrir deux positions dans OnTick. Le premier envoi de commande est de quelques millisecondes. Après cela, vous devez faire un cliché. Et ensuite le deuxième OrderSend devrait être appelé.

Seul OnTick peut être exécuté pendant des centaines de millisecondes. Et vous suggérez de prendre un instantané de OnTimer.

Et OnTimer a été libéré à d'autres fins.
 
De plus, OnTimer ne nous permet pas d'être sûrs d'avoir reçu un événement nul car il semble avoir une priorité plus élevée que les autres gestionnaires, ce qui est probablement le principal contre-argument.
 
fxsaber:

Au sujet d'Alert.

Pour l'instant, on peut dire qu'Alert ne peut pas être utilisé dans les endroits critiques. L'asynchronisme est nécessaire.

Alerte avec une empreinte, vous pouvez essayer de la remplacer par une écriture rapide quelque part.
Native sql in memory me vient à l'esprit

 
Renat Fatkhullin:
Je ne suggérais pas un instantané, je répondais à une question directe sur le minuteur en millisecondes.

Il est là, bien que dans le testeur actuel il soit toujours déclenché avec une fréquence de 1 sec. Dans le nouveau testeur que nous sommes en train d'écrire, nous allons essayer de changer cela.

J'utilise souvent le fait que le Testeur a exactement une minuterie en millisecondes, et non en secondes. Preuve.

// Демонстрация корректной работы миллисекундного таймера в Тестере.
#include <MT4Orders.mqh> // https://www.mql5.com/ru/code/16006
#define  Ask SymbolInfoDouble(_Symbol, SYMBOL_ASK)

void OnTick()
{
  static bool FirstRun = true;
  
  if (FirstRun)
  {
    MqlTick Tick;
    
    if (SymbolInfoTick(_Symbol, Tick) && Tick.bid && Tick.ask)
      FirstRun = !EventSetMillisecondTimer(29); // 29 мс таймер.
  }
}

void OnTimer()
{
  static int Count = 0;
  
  if (Count < 10)
  {
    if ((bool)((++Count) & 1)) // Попеременно
      OrderSend(_Symbol, OP_BUY, 0.1, Ask, 0, 0, 0); // Открываем позицию
    else if (OrderSelect(0, SELECT_BY_POS))
      OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 0); // Закрываем позицию
  }
}

void OnDeinit( const int )
{
  // Распечатали историю в конце бэктеста.
  for (int i = OrdersHistoryTotal() - 1; i >= 0; i--)
    if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY))
      OrderPrint();
}


Résultat.

2020.10.07 19:17:59.232 Core 1  2020.10.06 23:59:57   #11 2020.10.06 00:00:00.320 buy 0.10 EURUSD 1.17859 0.00000 0.00000 2020.10.06 00:00:00.349 1.17827 0.00 0.00 -3.20 0
2020.10.07 19:17:59.232 Core 1  2020.10.06 23:59:57   #9 2020.10.06 00:00:00.262 buy 0.10 EURUSD 1.17859 0.00000 0.00000 2020.10.06 00:00:00.291 1.17827 0.00 0.00 -3.20 0
2020.10.07 19:17:59.232 Core 1  2020.10.06 23:59:57   #7 2020.10.06 00:00:00.204 buy 0.10 EURUSD 1.17859 0.00000 0.00000 2020.10.06 00:00:00.233 1.17827 0.00 0.00 -3.20 0
2020.10.07 19:17:59.232 Core 1  2020.10.06 23:59:57   #5 2020.10.06 00:00:00.146 buy 0.10 EURUSD 1.17859 0.00000 0.00000 2020.10.06 00:00:00.175 1.17827 0.00 0.00 -3.20 0
2020.10.07 19:17:59.232 Core 1  2020.10.06 23:59:57   #3 2020.10.06 00:00:00.088 buy 0.10 EURUSD 1.17859 0.00000 0.00000 2020.10.06 00:00:00.117 1.17827 0.00 0.00 -3.20 0
2020.10.07 19:17:59.232 Core 1  2020.10.06 23:59:57   #1 2020.10.06 00:00:00.000 balance 0.00 0.00000 0.00000 0.00000 2020.10.06 00:00:00.000 0.00000 0.00 0.00 100000000.00 0

Il y a exactement 29 ms entre l'ouverture et la fermeture de la position.

Raison: