Erreurs, bugs, questions - page 2879

 
Alexandr Andreev:

Je l'ai retravaillé un peu

(il est donc préférable de ne pas utiliser de macro ;)

Lors des tests, je brouille le code autant que possible pour éviter que l'optimiseur ne lance des boucles vides.

vous avez

 //  for(int i = 0; i < 5; i++) sum += u.param[i];

L'optimisation de l'exécution MQL peut mettre fin à la première boucle avant, puisque les valeurs calculées ne sont pas utilisées, donc quelque chose doit être fait après le SpeedTest() avec les résultats - cette boucle

j'ai vérifié avec la boucle commentée, je ne l'ai pas jetée, mais dans l'autre test je peux me planter


la macro est une question de goût, je l'ai testé plusieurs fois et ça marche, je ne vois pas l'intérêt d'écrire la même chose à la main



UPD : j'ai trouvé l'endroit où j'ai lu comment les compilateurs modernes fonctionnent maintenant, c'est assez instructif.

https://habr.com/ru/post/431688/

https://habr.com/ru/post/47878/

 

le code donne la valeur iRSI des handles et tps toujours seulement 10, mais les prix et le graphique changent aussi.

iRSI(_Symbole,PERIOD_H1,14,PRICE_CLOSE)


construire 2652

Документация по MQL5: Константы, перечисления и структуры / Константы графиков / Периоды графиков
Документация по MQL5: Константы, перечисления и структуры / Константы графиков / Периоды графиков
  • www.mql5.com
Все предопределенные периоды графиков имеют уникальные идентификаторы. Идентификатор PERIOD_CURRENT означает текущий период графика, на котором запущена mql5-программа.
 
Aleksei Skrypnev:

le code donne la valeur iRSI des handles et tps toujours seulement 10, mais les prix et le graphique changent aussi.

iRSI(_Symbole,PERIOD_H1,14,PRICE_CLOSE)


construire 2652

Vous avez la poignée de l'indicateur, c'est 10

Ensuite, vous devez obtenir les valeurs sur la barre de droite

//--- создадим хэндл индикатора
   if(type==Call_iRSI)
      handle=iRSI(name,period,ma_period,applied_price);

//--- индикаторный буфер
double  rsi_buffer[];

//--- заполняем часть массива iRSIBuffer значениями из индикаторного буфера под индексом 0
   if(CopyBuffer(ind_handle,0,0,amount,rsi_buffer)<0)
     {
      //--- если копирование не удалось, сообщим код ошибки
      PrintFormat("Не удалось скопировать данные из индикатора iRSI, код ошибки %d",GetLastError());
      //--- завершим с нулевым результатом - это означает, что индикатор будет считаться нерассчитанным
      return(false);
     }

Lisez l'aide, ou cherchez des réponses sur le forum - elles sont nombreuses.

Документация по MQL5: Технические индикаторы / iRSI
Документация по MQL5: Технические индикаторы / iRSI
  • www.mql5.com
//|                                                    Demo_iRSI.mq5 | //|                        Copyright 2011, MetaQuotes Software Corp. | //|                                             https://www.mql5.com | //| Перечисление способов создания хэндла                            |  Creation             type=Call_iRSI;               ...
 
Vitaly Muzichenko:

Vous avez la poignée de l'indicateur, c'est 10

Ensuite, vous devez obtenir les valeurs sur la barre de droite

Lisez l'aide, ou cherchez des réponses sur le forum - il y en a beaucoup.

Je l'ai. Je vais étudier les tampons. C'est étrange, j'avais l'impression que tout devait fonctionner comme ça, j'ai peut-être confondu avec mql4.

Ce qui est étrange, c'est que je l'ai cherché sur Google et que je n'ai pas trouvé dans mql5 le moyen d'obtenir les données de l'indicateur.


Aha, selon votre exemple tel que je l'ai compris la valeur de l'indicateur RSI est à la fin dans une variable de la forme suivante

rsi_buffer[0] 
 
Igor Makanu:

vérifié :

2020.10.15 21:48:01.401 SpeedTst (EURUSD,H1) tst 1 : : boucles=10000000000 ms=10864370

2020.10.15 21:48:12.264 SpeedTst (EURUSD,H1) tst 2 : : boucles=10000000000 ms=10862287

la différence n'est pas significative, il est très probable que si nous inversons les tests dans l'ordre inverse, les résultats seront inversés.

non critique

il n'est guère judicieux d'inclure rand() dans le test, car cette fonction consomme beaucoup plus de ressources que les autres commandes.
Je pense que ce serait un test plus correct :

#define  Num 1000000
#define  SpeedTest(msg,s,EX)  {ulong mss=GetMicrosecondCount(); EX \
                                    mss=GetMicrosecondCount()-mss;\
                                    printf("%-22s%llu µs; Сумма - %llu",msg,mss,s);}
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
{
   ulong sum = 0;
   ushort in[];
   ArrayResize(in,Num*2);
   for (int i=0; i<Num*2; i++) in[i] = (ushort)rand();
   SpeedTest("test binary shift : ", sum,
   for (int i =0;i<(2*Num-1) && !_StopFlag;i+=2)
   {
      sum+=in[i]<<(sizeof(ushort)*8) | in[i+1];
   });
//--   
   sum = 0;
   union ushortTouint
   {
      uint param;
      ushort in[2];
   } u;
   SpeedTest("test union : ", sum,
   for (int i =0;i<(2*Num-1) && !_StopFlag;i+=2)
   {
      u.in[0]=in[i+1];
      u.in[1]=in[i];
      sum+=u.param;
   });
}

Résultat :

2020.10.15 17:14:03.168 TestMakanu (USDCAD,M1)  test binary shift :   1384 µs; Сумма - 1074434582054198
2020.10.15 17:14:03.169 TestMakanu (USDCAD,M1)  test union :          1209 µs; Сумма - 1074434582054198
2020.10.15 17:14:19.370 TestMakanu (USDCAD,M1)  test binary shift :   1891 µs; Сумма - 1073924616844949
2020.10.15 17:14:19.371 TestMakanu (USDCAD,M1)  test union :          1289 µs; Сумма - 1073924616844949
2020.10.15 17:14:20.949 TestMakanu (USDCAD,M1)  test binary shift :   1342 µs; Сумма - 1073194788831653
2020.10.15 17:14:20.950 TestMakanu (USDCAD,M1)  test union :          1178 µs; Сумма - 1073194788831653
2020.10.15 17:14:27.141 TestMakanu (USDCAD,M1)  test binary shift :   1365 µs; Сумма - 1075017290553168
2020.10.15 17:14:27.142 TestMakanu (USDCAD,M1)  test union :          1362 µs; Сумма - 1075017290553168
2020.10.15 17:14:28.202 TestMakanu (USDCAD,M1)  test binary shift :   1354 µs; Сумма - 1075051817914563
2020.10.15 17:14:28.203 TestMakanu (USDCAD,M1)  test union :          1105 µs; Сумма - 1075051817914563

Heureusement, je l'ai mis sur le mauvais cheval après tout. Les syndicats sont un peu plus rapides. Ils sont plus pratiques à utiliser et le code est plus lisible.

 
Nikolai Semko:

il n'est guère correct d'inclure rand() dans le test, car cette fonction est un ordre de grandeur plus gourmand en ressources que les autres commandes.

pas du tout critique

Le temps d'exécution de rand() est constant, il s'agit probablement d'une fonction C++ commune, recherchez dans Google "rand c++ source code".

vous devez l'initialiser, mais si vous l'initialisez avec des constantes, vous pouvez rencontrer des problèmes d'optimisation.

en général, je ne comprends pas l'aversion pour rand()

une option est d'initialiser avec quelque chose comme ceci :

void OnStart()
{
   for(int i=0;i<20;i++) Print(Myvalue());

}
//+------------------------------------------------------------------+
int Myvalue()
{
   const static int arr[] = {3, 1, 4, 1, 5, 9, 2, 6};
   static int cnt = ArraySize(arr);
   if(--cnt < 0) cnt = ArraySize(arr) - 1;
   return(arr[cnt]);
}

serait rapide.


J'ai exécuté votre script, mais il n'est pas correct.

Le temps principal est le chargement du code dans le cache, puis dans le processeur.

et ajoutez le caractère discret du temporisateur du système

nous obtenons... presque un nombre aléatoire.

vous devez le tester pendant longtemps, environ 100500 fois, imho

 
Nikolai Semko:

Il est peu probable qu'il soit correct d'inclure rand() dans le test, car cette fonction consomme un ordre de grandeur plus important de ressources que les autres commandes.
Je pense que ce serait un test plus correct :

Résultat :

Heureusement, j'ai parié sur le mauvais cheval après tout. Les syndicats sont un peu plus rapides. Ils sont plus pratiques à utiliser et le code est plus lisible.


Une fois pour toutes, et à une distance de la première victoire, (comme si la première méthode avait supprimé la ligne de conversion de court à quelque chose)

 
Igor Makanu:

pas du tout critique

Le temps d'exécution de rand() est constant, il s'agit probablement d'une fonction C++ commune, recherchez dans Google "rand c++ source code".

vous devez l'initialiser, mais si vous l'initialisez avec des constantes, vous pouvez rencontrer des problèmes d'optimisation.

en général, je ne comprends pas l'aversion pour rand()

comme une variante à initialiser avec quelque chose comme ceci :

sera rapide

L'idée est que vous devez mesurer exactement ce que vous devez mesurer, sans aucun élément superflu.

 
Alexandr Andreev:

Il s'agit de mesurer exactement ce qui est nécessaire, sans supplément.

pas de

S'il y a des fragments de code répétés, vous obtiendrez des tests d'optimisation !

Quelle différence cela fait-il de savoir combien de temps rand() est exécuté ?

laissez-le s'exécuter aux 2/3 du temps de test, l'essentiel étant que le temps de rand() soit constant.

Votre code MQL utilisera les fonctions MQL du système, n'est-ce pas ? - Quel est l'intérêt de tester un code parfait ?

 
Igor Makanu:

pas de

s'il y a des sections de code répétitives, vous obtiendrez des tests d'optimisation !

Quelle différence cela fait-il de savoir combien de temps rand() est exécuté ?

Laissez-le s'exécuter aux 2/3 du temps de test, l'essentiel étant que le temps de rand() soit constant.

Votre code MQL utilisera les fonctions MQL du système, n'est-ce pas ? - Quel est l'intérêt de tester un code parfait ?

)) la différence de vitesse pourrait être 4 fois en faveur d'une des méthodes (1 à 4), mais comme l'opération rand est 10 fois plus lente que le reste du code, cette différence ne serait pas visible (11 à 14)

Raison: