MT5 et la vitesse en action - page 46

 
Renat Fatkhullin:

Le minuteur en millisecondes existe depuis longtemps : EventSetMillisecondTimer()

Vous êtes complètement à côté de la plaque. Supposons que vous ayez besoin d'ouvrir deux positions dans OnTick. Le premier envoi de commande est de quelques millisecondes. Après cela, vous devez faire un instantané. 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.

 
Renat Fatkhullin:

Il y a également des problèmes avec la bibliothèque de mesure elle-même. Il y a beaucoup de choses inutiles, y compris les frais généraux.

Des disputes dans le studio !

 
Renat Fatkhullin:

Voici mon code et le temps d'exécution stable : pas de centaines ou de milliers de microsecondes sur 20 graphes en parallèle

Combien de cœurs avez-vous et quel type de processeur ? i7-2600 ?

8 cœurs.

2020.10.06 02:27:59.464 Terminal        MetaTrader 5 x64 build 2630 started for MetaQuotes Software Corp.
2020.10.06 02:27:59.465 Terminal        Windows 10 build 19042, Intel Core i7-2700 K  @ 3.50 GHz, 7 / 15 Gb memory, 19 / 29 Gb disk, IE 11, Admin, GMT+3

Un nouveau test de stress caché avec des millions de requêtes en parallèle ?

Je vous ai dit plusieurs fois que le conseiller en combat. Réduire autant que possible le nombre d'appels. En théorie (je ne l'ai pas mesuré) jusqu'à 10 appels par OnTick.


Soyez plus transparent. Ce n'est pas parce que vous avez posté un couple de simples appels _B que cela prouve vos autres affirmations. Vous oubliez brusquement le code et la description réelle des conditions dès que vous faites des affirmations farfelues.

Vous n'avez pas besoin d'imaginer quoi que ce soit dans votre esprit - dites et montrez ce que vous appelez et testez réellement. Pas un résultat déchiré du genre "j'ai exécuté un test de résistance inconnu et j'attends une alerte pour le montrer au monde entier", mais exactement le code complet du test.

Je publie les résultats de l'EA en direct. Il y a 70 fichiers mqh là, y compris WinAPI. Si vous ne vous contentez pas d'en parler, mais que vous le comprenez vraiment, je vous donnerai le code source. Vous allez reproduire les freins assez rapidement.

 
fxsaber:

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 instantané. 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.

Je n'ai pas suggéré le snapping, j'ai répondu à une question directe sur le timer en millisecondes.

Il est là, bien que dans le testeur actuel, il se déclenche toujours à 1 seconde. Dans le nouveau testeur que nous sommes en train d'écrire, nous allons essayer de changer cela.
 
fxsaber:

8 cœurs.

Plusieurs fois dit conseiller de combat. Réduire autant que possible le nombre d'appels. En théorie (je ne l'ai pas mesuré) jusqu'à 10 appels par OnTick.


Je publie les résultats de l'Expert Advisor. Il y a 70 fichiers mqh là, y compris WinAPI. Si vous ne vous contentez pas d'en parler, mais que vous le comprenez vraiment, je vous donnerai le code source. Vous jouerez les freins assez rapidement.

On va trouver, donnez-nous le code source.
 
fxsaber:

Des arguments sur la table !

Tout votre benchmark est surchargé de déchets et en fait, voici une version propre et compréhensible (contrairement à votre fouillis de code) de celui-ci :


//--- benchmark macros
#define _B(_function,_alert_interval)               \
          {                                         \
           ulong _latency=GetMicrosecondCount();    \
           _function;                               \
           _latency=GetMicrosecondCount()-_latency; \
           if(_latency > _alert_interval)           \
              ::Alert("Time[" + __FILE__ + " " + (string)__LINE__ + " in " + __FUNCTION__+ ": " + #_function + "] = " + (string)_latency + " mсs"); \
          }



//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnTick()
  {
   MqlTick Tick;
   
   _B(SymbolInfoTick(_Symbol,Tick),0);
   _B(SymbolInfoTick(_Symbol,Tick),0);
  }

Quels sont vos problèmes ?

  1. code illisible

  2. Liaison dans une classe avec beaucoup de frais généraux

  3. le coût de stockage de 50 résultats dans la pile
      static bool Set( const string Str )
      {
        if (BENCHMARK::Amount == BENCHMARK::ReserveSize)
          BENCHMARK::ReserveSize = ::ArrayResize(BENCHMARK::Bench, BENCHMARK::ReserveSize + BENCHMARK_RESERVE);
    
        BENCHMARK::Bench[BENCHMARK::Amount++].Set(Str);
    
        return(true);
      }
    
  4. prise des résultats - un solide transparent et des déchets dans les liaisons d'objets
      static ulong Get( const uint AlertInterval = 0 )
      {
        const int Pos = BENCHMARK::Amount - 1;
        const ulong Res = (Pos < 0) ? 0 : BENCHMARK::Bench[Pos].Get();
    
        if (Pos >= 0)
        {
          if (AlertInterval && (Res > AlertInterval))
            ::Alert("Time[" + BENCHMARK::Bench[Pos].Str + "] = " + (string)Res + " mсs.");
    
          BENCHMARK::Amount = Pos;
        }
    
        return(Res);
      }
    


J'espère que vous n'avez pas désactivé l'optimisation du code pour les tests ?

Je veux dire le paramètre global Optimize=0 dans metaeditor.ini

 
Renat Fatkhullin:

L'ensemble de votre benchmark est surchargé de déchets et, en fait, voici une version propre et compréhensible (contrairement à votre fouillis de code) de celui-ci :

Votre version en est, malheureusement, au stade initial de la compréhension de la commodité. C'est pratique quand on peut le faire comme ça.

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

Bibliothèques : Benchmark

fxsaber, 2020.10.01 23:49

Nous essayons maintenant de trouver où se trouve le hic dans la variante standard. Nous ajoutons quelques symboles au code source.

    for (long Chart = _B2(::ChartFirst()); (Chart != -1) && !Res; Chart = _B2(::ChartNext(Chart)))
      Res = (Chart != chartID) && _B2(::ChartGetInteger(Chart, CHART_IS_MAXIMIZED));

Et on en voit immédiatement la raison.

2020.10.02 00:45:14.113 Alert: Time[Test9.mq5 36 in IsInvisible: ::ChartGetInteger(Chart,CHART_IS_MAXIMIZED)] = 878 mсs.
2020.10.02 00:45:14.114 Alert: Time[Test9.mq5 36 in IsInvisible: ::ChartGetInteger(Chart,CHART_IS_MAXIMIZED)] = 943 mсs.
2020.10.02 00:45:14.114 Alert: Time[Test9.mq5 36 in IsInvisible: ::ChartGetInteger(Chart,CHART_IS_MAXIMIZED)] = 297 mсs.
2020.10.02 00:45:14.116 Alert: Time[Test9.mq5 36 in IsInvisible: ::ChartGetInteger(Chart,CHART_IS_MAXIMIZED)] = 1787 mсs.
2020.10.02 00:45:14.116 Alert: Time[Test9.mq5 35 in IsInvisible: ::ChartNext(Chart)] = 2 mсs.
2020.10.02 00:45:14.117 Alert: Time[Test9.mq5 36 in IsInvisible: ::ChartGetInteger(Chart,CHART_IS_MAXIMIZED)] = 980 mсs.
2020.10.02 00:45:14.117 Alert: Time[Test9.mq5 35 in IsInvisible: ::ChartNext(Chart)] = 2 mсs.
2020.10.02 00:45:14.117 Alert: Time[Test9.mq5 36 in IsInvisible: ::ChartGetInteger(Chart,CHART_IS_MAXIMIZED)] = 59 mсs.
2020.10.02 00:45:14.118 Alert: Time[Test9.mq5 36 in IsInvisible: ::ChartGetInteger(Chart,CHART_IS_MAXIMIZED)] = 803 mсs.
2020.10.02 00:45:14.119 Alert: Time[Test9.mq5 36 in IsInvisible: ::ChartGetInteger(Chart,CHART_IS_MAXIMIZED)] = 1059 mсs.

CHART_IS_MAXIMIZED est trop lent pour les graphiques de quelqu'un d'autre. Le rapport de bug est prêt ! C'était très facile avec la bibliothèque.


Quel est le problème ?

  1. code illisible

  2. s'attacher à un cours avec beaucoup de frais généraux

  3. coût du stockage en pile de 50 résultats
  4. obtenir des résultats - une surcharge massive et des déchets dans les liaisons d'objets

La facilité d'utilisation l'emporte sur les faibles frais généraux. C'est misérable si vous regardez de près la façon dont elle est mise en œuvre. Par exemple, ArrayResize est une surcharge, son utilisation est donc réduite au minimum.

J'espère que vous n'avez pas désactivé l'optimisation du code pour les tests ?

Je veux dire le paramètre global Optimize=0 dans metaeditor.ini

Pas intéressé par les modes lents. Je cherche à améliorer les performances de l'EA de combat, en prêtant attention à l'optimisation de l'algorithme et du compilateur, bien sûr.

 
Renat Fatkhullin:

Tout votre benchmark est surchargé de déchets et en fait, voici une version propre et compréhensible (contrairement à votre fouillis de code) de celui-ci :

C'est quoi ton problème ?

  1. code illisible

  2. s'intégrer dans une classe avec beaucoup de frais généraux

  3. coût du stockage en pile de 50 résultats
  4. récupération des résultats - tous les frais généraux et les déchets dans les liaisons d'objets


J'espère que vous n'avez pas désactivé l'optimisation du code pour les tests ?

Je veux dire le paramètre global Optimize=0 dans metaeditor.ini

Ici, c'est du style C, c'est simple et vraiment sans déchets. Merci pour l'exemple.

Un des professeurs de langage C a recommandé de ne pas utiliser le trait de soulignement _B dans les noms d'utilisateur
Parce que ce préfixe est utilisé par les développeurs de bibliothèques, de programmes, etc.
Et pour ne pas risquer de chevauchement, il a recommandé de ne pas l'utiliser.

Dans mql5, est-il possible de faire des chevauchements avec vos noms ?
Ou les noms personnalisés sont complètement protégés des noms MQ ?

 
Roman:

L'un des professeurs de C a recommandé de ne pas utiliser le trait de soulignement _B dans les noms d'utilisateur
, car ce préfixe est utilisé par les développeurs de bibliothèques, de logiciels, etc.
Et pour éviter les chevauchements, il a recommandé de ne pas l'utiliser.

En C, les noms commençant par "_" sont utilisés comme noms de service, de système ou spéciaux. Dans ce cas, je pense que c'est permis. Puisque cette fonction est utilisée pour la maintenance et l'examen du code.

 
Edgar Akhmadeev:

Les noms commençant par "_" sont utilisés en C comme noms de service, de système ou spéciaux. Dans ce cas - acceptable, je pense. Puisque cette fonction est utilisée pour la maintenance et l'examen du code.

C'est le problème, à part mql5, il y a des noms de services MQ pour les développeurs.