MT5 et la vitesse en action - page 2

 
fxsaber:

Veuillez donner un diagramme-code rudimentaire pour cette idée. À première vue, cela ressemble à un malentendu total.

Pendant 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.

Dans sa forme la plus simple :

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

Il suffit de modifier l'approche des calculs eux-mêmes (faire des retours intermédiaires aussi souvent que la tâche l'exige). Mais si c'est difficile, considérez à l'étape 1 que OnMain n'existe pas pour vous (vous déplacez le code principal non pas dans OnMain, mais dans On2XX), respectivement, dans OnMain vous n'avez pas besoin d'apprendre quelque chose

 
A100:

Les béquilles sont fabriquées dans la mauvaise direction :

Laissez les fonctions OnXXX uniquement copier les événements (paramètres) dans la file d'attente et appeler la fonction principale OnMain. Déplacer tout leur 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 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 ?

Ce n'est pas ce que vous écrivez.
Le problème est que la fonctionnalité de remplissage des champs dans les variables d'entrée de la fonction "OntaredeTransaction" ne correspond pas à la description donnée dans l'Aide, pour le pire :
c'est-à-dire que de nombreux champs ne sont pas remplis dans les appels et même dans l'appel final de TRADE_TRANSACTION_HISTORY_ADD.
Par conséquent, tous les traders sont à l'agonie ici pour déterminer d'une manière ou d'une autre ces paramètres manquants au moment de l'arrivée.
Il y a eu de nombreuses discussions ici, il suffit de faire une recherche sur le forum - la mauvaise fonctionnalité "OntaredeTransaction" entraîne des dépenses supplémentaires à la fois en temps et en "charge" les commerçants avec du temps supplémentaire passé sur le développement d'un code qui fonctionne correctement (c'est-à-dire d'énormes pertes de temps et une inefficacité colossale au niveau de la communauté).
Les réponses actuelles des développeurs sont du type "Si vous avez un symbole d'exécution du marché, il aura une valeur de prix nulle ; cela devrait être comme ça" (Lien).(Lien) - une fois de plus, c'est INNORMAL -
l'absence de valeurs exhaustives dans le dernier appel de fonction entraîne beaucoup de travail supplémentaire.

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

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.


Malheureusement, un tel appel de HistorySelect prend 5-30 millisecondes (je l'ai mesuré moi-même dans la Release-EX5). Lorsque le conseiller expert effectue plusieurs de ces mises à jour en OnTick (cela devrait être fait après toute pause, par exemple, après chaque OrderSend), alors tout devient follement coûteux/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.

Avez-vous des preuves de ce que "un tel appel à HistorySelect dure 5-30 millisecondes" ?

Si j'ai bien compris votre idée, alors le code de test devrait ressembler à ceci :

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");
  }

C'est ainsi que les requêtes 100000 fonctionnent :

100000 HistorySelect = 141.63 ms
 
Anton:

Avez-vous des preuves de ce que "un tel appel à HistorySelect dure 5-30 millisecondes" ?

Si j'ai bien compris votre point de vue, alors le code de test devrait ressembler à ceci :

C'est ainsi que fonctionnent les requêtes 100 000 :

Et une requête ? Je ne serais pas surpris que le compilateur, en optimisant, fasse exactement cela))).
 
Anton:

Avez-vous des preuves de ce que "un tel appel à HistorySelect dure 5-30 millisecondes" ?

Si j'ai bien compris votre point de vue, alors le code de test devrait ressembler à ceci :

C'est ainsi que fonctionnent les requêtes 100 000 :

Exécution de votre script.

        100000 HistorySelect = 19493.96 ms


Lancez un autre script.

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

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


HistoryDealsTotal() = 17828
HistoryOrdersTotal() = 22142


Nombre normal de combats. Pas HFT.


Au fait, votre script a montré que HistorySelect recalcule tout à chaque fois. Et les paramètres d'entrée n'ont pas changé, la table d'historique n'a pas été mise à jour, les autres fonctions HistorySelect n'ont pas été appelées.

 
fxsaber:

Exécution de votre script.

Il faut alors des détails.

Mon test s'est déroulé sur un ordinateur qui n'est pas le plus rapide "Intel Xeon E5-2630 v4 @ 2.20GHz" avec beaucoup d'autres processus en arrière-plan.

L'historique de mon compte test montre 31315 ordres plus ou moins réguliers depuis 2009, dont 8 ordres pour aujourd'hui.

Il se peut qu'un script ou un conseiller expert ait été exécuté en même temps, ce qui a chargé de façon considérable les bases de données du terminal. Essayez-le sur un terminal "propre".

Test plus informatif :

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());
  }

Trois courses :

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:

Il faut alors des détails.

Mon test a été exécuté sur un ordinateur qui n'est pas le plus rapide "Intel Xeon E5-2630 v4 @ 2.20GHz" avec beaucoup d'autres processus en arrière-plan.

Le compte test avait 31315 ordres dans son historique plus ou moins uniformément depuis 2009, dont 8 ordres pour aujourd'hui.

Il se peut qu'un script ou un conseiller expert ait été exécuté en même temps, ce qui a entraîné un chargement considérable des bases de données du terminal. Essayez-le sur un terminal "propre".

Videz le Terminal sur le même compte et la même machine.

        100000 HistorySelect = 19367.01 ms


Sur d'autres comptes et terminaux, la même image. Configuration.

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


Je demande aux lecteurs de donner leurs résultats de ce scénario.

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 plus informatif :

Trois départs :

        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

Terminal vide 2460.


ZS Exécuter sur un compte vide.

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


La vitesse semble être fortement influencée par le nombre de transactions, et non par les ordres.

 
fxsaber:

Videz le Terminal sur le même compte et la même machine.


Sur d'autres comptes et terminaux, le même schéma. Configuration.


Je demande aux lecteurs de citer leurs résultats de ce scénario.

Cela ne prouve rien, mais le fait qu'à chaque nouvelle exécution (sur un symbole différent), le temps augmente - est alarmant...

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
 
Сергей Таболин:

Doit fonctionner sur un compte avec un long historique de transactions.