MT5 et la vitesse en action

 

La MT5 est une plateforme agile. Mais il existe des goulets d'étranglement qui réduisent à néant tous les efforts visant à accélérer les transactions.

Je voudrais rassembler les problèmes ici, en discuter et les résoudre quelque part avec mes propres efforts, quelque part avec l'aide des développeurs.

 

HistoireSelect.


C'est une fonction incroyablement coûteuse. Et, malheureusement, aucune quantité de cache ne peut rendre sa vitesse acceptable maintenant.


Par exemple, dans les évaluations environnementales de champs de bataille, il est important de travailler avec des données réelles. En particulier, que les ticks de Market Watch et CopyTicks ne soient pas périmés si possible.

Pour ce faire, il existe des mécanismes pas très bons, mais forcés, pour vérifier la pertinence des données de prix actuelles. Une partie de ce mécanisme consiste à détecter les situations où une transaction sur un symbole est passée après le dernier tick. Cela n'arrive pas rarement, il est donc important de savoir si la tique actuelle est toujours d'actualité ou non.


Pour cette détection, vous devez pouvoir accéder à l'historique des transactions récentes. Cela se fait en utilisant le HistorySelect de la manière schématique suivante.

void OnTick()
{
  MqlTick Tick;

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


Malheureusement, un tel appel à HistorySelect prend 5-30 millisecondes (je l'ai mesuré moi-même dans Release-EX5). Lorsque le Conseiller Expert fait plusieurs mises à jour de ce type dans OnTick (dans le bon sens du terme, cela devrait être fait après chaque pause. Par exemple, après chaque OrderSend.), tout devient alors follement cher/long. HistorySelect peut consommer collectivement plusieurs secondes dans un seul OnTick.


Chers développeurs, pourquoi est-ce si cher ? Cette fonction peut s'exécuter instantanément avec une mise en œuvre appropriée.


Veuillez penser à introduire de telles fonctions pour travailler avec l'histoire.

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

Ils fermeraient complètement les freins de l'HistorySelect. Parce que cela résoudrait le problème d'obtenir les dernières offres à très bas prix. Pour l'instant, c'est un tourment dans l'exécution du combat.


Il n'est pas toujours possible de contrôler les dernières transactions via OnTradeTransaction, il est donc urgent de travailler rapidement sur l'historique.

 

Accès aux événements ChartEvent et TradeTransaction.


Une idée et l'une des mises en œuvre possibles ont été suggérées. Je ne fais que le copier ici.

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

Erreurs, bugs, questions

Sergey Dzyublik, 2020.05.20 00:47

Suggestion aux développeurs.
Veuillez envisager d'ajouter dans MQL une fonction qui permet aux utilisateurs d'appeler indépendamment le traitement des "messages" accumulés dans OnChartEvent à partir d'un code personnalisé.
1) Cela permettrait d'appeler la gestion de OnChartEvent entre les itérations d'un calcul qui prend du temps, rendant l'interface utilisateur graphique au moins un peu réactive sans construire un jardin potager de : pool de tâches, transfert de données, synchronisation d'état, sauvegarde et restauration de contexte....
2) Cela permettrait d'utiliser OnChartEvent dans les scripts.

Merci.

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

Bugs, bugs, questions

Sergey Dzyublik, 2020.05.20 13:39

Pas tout à fait, je préférerais appeler cette fonction comme HandleNextEvent, une signature possible :

bool HandleNextEvent (ENUM_EVENT_TYPE);


Lorsqu'il est appelé, de manière similaire à GetNextEvent, il vérifie si le ENUM_EVENT_TYPE spécifié est présent dans la file d'attente,
et si cet événement est présent, il transmet automatiquement le contrôle au code utilisateur du gestionnaire correspondant (OnChartEvent, OnTrade, OnTradeTransaction, ...). (mercià fxsaber pour l'ajout)).
Retourne vrai s'il y avait un événement dans la file d'attente, sinon retourne faux.


Cas d'utilisation possible :

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

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

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

Erreurs, bogues, questions

Sergey Dzyublik, 2020.05.20 14:38

2) C'est exact. Si je suis intéressé par le traitement d'un événement particulier, et non de tous les événements du système, il serait agréable de pouvoir traiter uniquement ce type d'événements, en laissant le traitement des autres événements dans le mode habituel.
3) Si HandleNextEvent est appelé à nouveau pendant le traitement - appelez et traitez. La seule chose qui peut arriver est le débordement de pile, mais c'est le problème de l'utilisateur et du code, pas celui du développeur.
4) Les événements qui ne tombent pas sous le filtre restent dans la même séquence et seront appelés lorsque l'utilisateur rendra le contrôle au système, comme d'habitude.


Maintenant, nous devons créer des béquilles pour accéder aux mêmes événements TradeTransaction dans le code en cours d'exécution.

Les Expert Advisors ont vraiment besoin de cette fonctionnalité pour l'application de combat.

 
fxsaber:

Iln'est pas toujours possible de suivre les transactions récentes via OnTradeTransaction, c'est pourquoi un travail rapide avec l'historique est pertinent.

Veuillez donner un exemple où il n'est pas possible de contrôler ?

 
prostotrader:

Veuillez me donner un exemple où il n'y a pas de contrôle ?

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

Particularités de mql5, trucs et astuces

fxsaber, 2020.04.23 19:51

Les flèches d'ouverture/fermeture que MT5 place automatiquement en temps réel sont basées sur les événements TradeTransaction.


Je viens de voir que ces événements (ouverture et fermeture d'une douzaine de positions) ne sont pas parvenus au terminal en raison d'une interruption momentanée de la connexion - c'est une telle coïncidence, j'étais assis devant mon PC et je les ai vus de mes propres yeux. Par conséquent, il n'y a pas de flèches correspondantes.


Et, comme cela a parfois été dit ici, vous ne pouvez pas compter sur OnTradeTransaction dans les EA de combat. Il est dommage qu'il n'existe pas de mécanisme public fiable pour traiter OrderSendAsync.


Et aussi lorsque plusieurs OrderSend sont placés dans le code. Lorsqu'un OrderSend dépend du précédent.

 
fxsaber:

Également lors du placement de plusieurs OrderSend dans le code. Lorsqu'un envoi de commande dépend de l'envoi de commande précédent.

S'il y a une rupture de communication, rien ne sera ajouté à l'historique non plus !

J'utiliseOrderSendAsync depuis plus de 5 ans(il y avait des problèmes avec OrderSend à l'époque) + OnTradeTransaction() uniquement en mode combat - aucun problème !

S'il y a une rupture de connexion, elle est détectée par l'assistant qui est affecté à chaque ordre (sur le FOREX, c'est difficile à faire car les noms des symboles ne sont pas standardisés).

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

S'il y a une rupture de communication, rien ne sera ajouté à l'historique non plus !

J'utiliseOrderSendAsync depuis plus de 5 ans(il y avait des problèmes avec OrderSend à l'époque) + OnTradeTransaction() uniquement en mode combat - aucun problème !

Vous ne pouvez pas vous empêcher de constater que vous vous êtes cassé les dents sur Async+OnTrade pendant des années. Vous actualisez les données par ce mécanisme et tout le reste, il n'y a pas de problème.

S'il vous plaît, ne dites pas "vous ne savez pas cuisiner" ici, au moins.

 
fxsaber:

Vous ne pouvez pas vous empêcher de remarquer que vous avez poussé pour Async+OnTrade pendant des années. Vous faites également des mises à jour de données par ce mécanisme et tout le reste, car il n'y a pas de problème.

S'il vous plaît, ne prétendez pas que "vous ne savez pas cuisiner", du moins ici.

Vous vous "battez" pour des microsecondes et, dans le même temps, vous écrivez des tonnes de code, ce qui fait également perdre du temps,

et 99% du temps, vous n'en avez pas besoin.

 
Je vous encourage à ne vous exprimer que de manière constructive.
 
fxsaber:

Accès aux événements ChartEvent et TradeTransaction.

Une idée et l'une des mises en œuvre possibles ont été suggérées. Donc je le copie ici.

Maintenant, afin d'avoir accès à ces événements TradeTransaction dans le code en cours d'exécution, nous devons utiliser des béquilles.

Vous faites des béquilles dans une mauvaise direction :

Laisser dans les fonctions OnXXX uniquement la copie des événements (paramètres) dans la file d'attente et appeler la fonction principale OnMain. Déplacez tout leur code vers les fonctions dupliquées de On2XX. Appelez ces fonctions On2XX dupliquées depuis le OnMain dans l'ordre où vous en avez besoin, en leur passant à leur tour les données des files d'attente comme paramètres.

Ensuite, effectuez des mesures et montrez le gain de vitesse, et vous pourrez alors suggérer de compléter le MQL avec une fonctionnalité appropriée. Mais pourquoi ajouter, si vous avez déjà tout fait vous-même ici et maintenant ?

 
A100:

Laissez les fonctions OnXXX uniquement copier les événements (paramètres) dans la file d'attente et appeler la fonction principale OnMain. Déplacez tout le code pour dupliquer les fonctions de On2XX. Appelez ces fonctions On2XX dupliquées depuis le OnMain dans l'ordre où vous en avez besoin, en leur passant à leur tour les données de la file d'attente comme paramètres.

Veuillez me donner un schéma-code rudimentaire de cette idée. À première vue, cela ressemble à un malentendu total.

Lors de l'exécution de la fonction OnMain, il n'y a aucun moyen de connaître l'état de la file d'attente réelle actuelle. Le seul moyen d'y parvenir est d'utiliser un logiciel espion comme indiqué dans le lien.

Raison: