Erreurs, bugs, questions - page 2465

 

MT5. Construit en 2055.
La fonction ChartGetDouble(0,CHART_PRICE_MAX) et ChartGetDouble(0,CHART_PRICE_MIN) est exécutée incorrectement (écrit des zéros) lors du changement de TF.
Et il écrit correctement la première fois en démarrant l'indicateur. Ensuite, lorsque TF est décalé sur le mensuel TF est toujours nul, sur les autres parfois au début, puis il est normalisé.

#property indicator_chart_window
#property indicator_plots   1 
#property indicator_buffers 1

int OnInit()
  {
  Print(EnumToString(_Period) +":  PriceMax="+string(ChartGetDouble(0,CHART_PRICE_MAX))+";  PriceMin="+string(ChartGetDouble(0,CHART_PRICE_MIN)));
   return(INIT_SUCCEEDED);
  }
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])
  {
   return(rates_total);
  }

résultat :

2019.05.20 02:30:31.689 TestMinMax (NZDUSD,MN1) PERIOD_MN1:  PriceMax=0.8995;  PriceMin=0.3258  // первый раз нормально
2019.05.20 02:30:37.492 TestMinMax (NZDUSD,W1)  PERIOD_W1:  PriceMax=0.8995;  PriceMin=0.3258
2019.05.20 02:30:39.233 TestMinMax (NZDUSD,MN1) PERIOD_MN1:  PriceMax=0.0;  PriceMin=0.0
2019.05.20 02:30:41.838 TestMinMax (NZDUSD,H4)  PERIOD_H4:  PriceMax=0.6986;  PriceMin=0.6352
2019.05.20 02:30:43.237 TestMinMax (NZDUSD,MN1) PERIOD_MN1:  PriceMax=0.0;  PriceMin=0.0
2019.05.20 02:30:51.404 TestMinMax (NZDUSD,M1)  PERIOD_M1:  PriceMax=0.0;  PriceMin=0.0
2019.05.20 02:30:54.108 TestMinMax (NZDUSD,MN1) PERIOD_MN1:  PriceMax=0.0;  PriceMin=0.0
2019.05.20 02:30:57.420 TestMinMax (NZDUSD,M5)  PERIOD_M5:  PriceMax=0.0;  PriceMin=0.0
2019.05.20 02:31:00.537 TestMinMax (NZDUSD,M15) PERIOD_M15:  PriceMax=0.0;  PriceMin=0.0
2019.05.20 02:31:02.512 TestMinMax (NZDUSD,M30) PERIOD_M30:  PriceMax=0.679;  PriceMin=0.6477000000000001
2019.05.20 02:31:03.780 TestMinMax (NZDUSD,M15) PERIOD_M15:  PriceMax=0.6689000000000001;  PriceMin=0.649
2019.05.20 02:31:05.977 TestMinMax (NZDUSD,M5)  PERIOD_M5:  PriceMax=0.6593;  PriceMin=0.6502
2019.05.20 02:31:07.502 TestMinMax (NZDUSD,M1)  PERIOD_M1:  PriceMax=0.6541;  PriceMin=0.6508
2019.05.20 02:31:10.136 TestMinMax (NZDUSD,MN1) PERIOD_MN1:  PriceMax=0.0;  PriceMin=0.0
Dossiers :
 

https://www.mql5.com/ru/docs/basis/types/classes

offsetof – это специальная команда, которая непосредственно связана в атрибутом pack. Она позволяет получить смещение члена от начала структуры.

struct Parent{ 
      char              c;    // sizeof(char)=1 
};
     
struct Children pack(2) : Parent{ 
      short             s;   // sizeof(short)=2 
};

void OnStart(){ 
//--- объявим переменную типа Children 
   Children child;   
//--- узнаем смещения от начала структуры  
   Print("offsetof(child.c)=",offsetof(child.c)); 
   Print("offsetof(child.s)=",offsetof(child.s));
}   


Au début, j'ai été surpris, car je ne savais pas que l'offsetof existait.
Mais la réalité a remis tout à sa place :

offsetof' - fonction non définie

 
Sergey Dzyublik:

https://www.mql5.com/ru/docs/basis/types/classes

J'ai d'abord été surpris car je ne connaissais pas l'existence de l'offsetof.
Mais la réalité a remis tout à sa place :

offsetof' - fonction non définie

Vous avez vous-même écrit

#include <TypeToBytes.mqh>

Print("offsetof(child.c)=",_OFFSET(child, c)); 
Print("offsetof(child.s)=",_OFFSET(child, s));
 

Si vous ouvrez un signal de la section Signaux, vous pouvez voir un exemple d'infographie :



Normalement, l'objectif d'une infographie est de transmettre à l'utilisateur final les avantages et les inconvénients d'un ensemble de propriétés de l'objet analysé.
Cependant, l'essence de cette infographie n'est pas claire, lorsqu'un drawdown de 100% est affiché comme un résultat de 100% sur le graphique.
De même, le même indicateur est utilisé deux fois dans le même graphique : une fois en positif et une seconde fois en négatif (indicateurs de "Trades profitables" et de "Trades perdants").

Modifications proposées :
1. Introduisez un compte à rebours pour les indicateurs "Maximum drawdown", "Maximum deposit load", "Losing trades" (plus la valeur est petite - plus la valeur de l'indicateur est grande sur le graphique) ;
2. Remplacez l'un des indicateurs dupliqués ("trades profitables" ou "trades perdants") par un nouvel indicateur (par exemple, l'écart moyen du montant des achats et des ventes, ou autre chose) ;
3. Pour certains indicateurs, tels que "Maximum drawdown" et "Maximum deposit load", remplacez l'échelle en % omniprésente sur le graphique par une échelle logarithmique ou autre. L'objectif est d'augmenter l'impact de l'indicateur sur l'attractivité du signal.

 
class A{
   int  data;
};

struct Wrap{
   A arr[];
};
   
   
void OnStart(){  
   Wrap data_1;
   ArrayResize(data_1.arr, 10);
   
   Wrap data_2 = data_1;
   PRINT(ArraySize(data_2.arr));      // result: 10
   
   A arr[];
   PRINT(ArrayCopy(arr, data_1.arr)); //'arr' - structures or classes containing objects are not allowed
}


Pourquoi les structures peuvent faire une copie profonde, maisArrayCopy, même si la classe a un constructeur de copie, ne peut rien faire et donne une erreur de compilation?
"Ce n'est pas normal, ce n'est pas juste !" ©

 
bool  ArrayInsert( 
   void&        dst_array[],          // receiving array 
   const void&  src_array[],          // source array 
   uint         dst_start,            // receiver array index to be inserted 
   uint         src_start=0,          // source array index to be copied 
   uint         count=WHOLE_ARRAY     // number of elements to insert 
   );
int  ArrayCopy( 
   void&        dst_array[],         // destination array 
   const void&  src_array[],         // source array 
   int          dst_start=0,         // index starting from which write into destination array 
   int          src_start=0,         // first index of a source array 
   int          count=WHOLE_ARRAY    // number of elements 
   );

Des différences dans des fonctions presque "identiques" :
1. pas de paramètre par défaut pour ArrayInsert.
2. l'absence d'une description "standard" des paramètres.

L'utilisation de types de données différents pour les mêmes paramètres (int, uint) peut être comprise, en référence à la compatibilité.
 
Sergey Dzyublik:
Pas de paramètre par défaut pour ArrayInsert.
Il n'est pas nécessaire à cet endroit.
Mais le fait que la fonction retourne un bool, alors qu'elle devrait retourner le nombre d'éléments ajoutés...
 
Sergey Dzyublik:


Pourquoi les structures peuvent faire une copie profonde, maisArrayCopy, même si la classe a un constructeur de copie, ne peut rien faire et donne une erreur de compilation?
"Ce n'est pas normal, ce n'est pas juste !" ©

J'ai dû implémenter moi-même un ArrayCopy à part entière.
Je ne pense pas, mais peut-être que quelqu'un pourrait trouver ça utile...

#define  PRINT(x) ; Print(#x, ":", string(x))

template<typename T>
uint  ArrayCopy_bypass( 
   T&            dst_array[],         // destination array 
   const T&      src_array[],         // source array 
   uint          dst_start=0,         // index starting from which write into destination array 
   uint          src_start=0,         // first index of a source array 
   uint          count=WHOLE_ARRAY    // number of elements 
   )
{
   uint src_size = ArraySize(src_array);
   uint dst_size = ArraySize(dst_array);
   bool src_array_is_dynamic = ArrayIsDynamic(src_array);
   bool dst_array_is_dynamic = ArrayIsDynamic(dst_array);
   
   // validate input parameters
   if(src_size <= src_start 
      || ( !dst_array_is_dynamic && (dst_size <= dst_start))){
      return 0;
   }
   
   uint max_allowed_array_size = uchar(INT_MAX);
   uint same_array_check_min_count_limit = 5;
   
   //--- the same array could be passed to dst_array and src_array parameters
   bool same_array_is_used = true;
   bool dst_array_resize_was_applied = false;
   if (src_size != dst_size || src_array_is_dynamic != dst_array_is_dynamic){
      same_array_is_used = false;
   }
   
   //--- normalize copy count based on src_array data
   if(count == uint(WHOLE_ARRAY) || count > src_size - src_start){
      count = src_size - src_start;
   }
   
   //--- normalize copy count based on dst_start data
   uint dst_required_size = dst_start + count;
   if (dst_required_size > max_allowed_array_size){
      return 0;
   }
   
   if(dst_size <= dst_required_size){
      if(dst_array_is_dynamic){
         ArrayResize(dst_array, dst_required_size);
         dst_array_resize_was_applied = true;
         
         dst_size = ArraySize(dst_array);
         src_size = ArraySize(src_array);
         
         if(same_array_is_used && src_size != dst_size){
            same_array_is_used = false;
         }
      }    
      count = dst_size - dst_start;
   }
   
   //--- check copy count
   if(count == 0){
      return 0;
   }
   
   //--- the same array could be passed to dst_array and src_array parameters, let's confirm it
   if(count >= same_array_check_min_count_limit 
         && same_array_is_used 
         && !dst_array_resize_was_applied)
   {
      if(dst_array_is_dynamic && dst_size + 1 <= max_allowed_array_size){
         ArrayResize(dst_array, dst_size + 1);
         dst_array_resize_was_applied = true;
         
         if(ArraySize(src_array) != dst_size + 1){
            same_array_is_used = false;
         }
         ArrayResize(dst_array, dst_size);
      }
   }
   
   //copy arrays
   if(same_array_is_used){
      T src_copy[];
      ArrayResize(src_copy, count);
      
      for(uint i = 0; i < count; i++){
         src_copy[i] = src_array[src_start + i];
      }
      
      for(uint i = 0; i < count; i++){
         dst_array[dst_start + i] = src_copy[i];
      }
   }else{
      for(uint i = 0; i < count; i++){
         dst_array[dst_start + i] = src_array[src_start + i];
      }
   }
   return count;
}
   
   
class A{
   uchar data;
};
   
   
void OnStart(){
   uchar test_data[10] = {0,1,2,3,4,5,6,7,8,9};
   
   PRINT("TEST 1 (Static)");     
   uchar data_1[8]; 
   
   PRINT(ArrayCopy_bypass(data_1, test_data));
   ArrayPrint(data_1);
   
   PRINT(ArrayCopy_bypass(data_1, test_data, 1, 0, 1));
   ArrayPrint(data_1);
   
   PRINT(ArrayCopy_bypass(data_1, test_data, 5));
   ArrayPrint(data_1);
   
   PRINT(ArrayCopy_bypass(data_1, test_data, 30, 8, 5));
   ArrayPrint(data_1);
   
   
   PRINT("TEST 2 (DYNAMIC)");  
   uchar data_2[]; 
   
   PRINT(ArrayCopy_bypass(data_2, test_data));
   ArrayPrint(data_2);
   
   PRINT(ArrayCopy_bypass(data_2, test_data, 1, 0, 1));
   ArrayPrint(data_2);
   
   PRINT(ArrayCopy_bypass(data_2, test_data, 5));
   ArrayPrint(data_2);
   
   PRINT(ArrayCopy_bypass(data_2, test_data, 30, 8, 5));
   ArrayPrint(data_2);
   
   
   A data_a1[10];
   A data_a2[];
   ArrayCopy_bypass(data_a2, data_a1);            //10
   //PRINT(ArrayCopy(data_a2, data_a1));          //'data_a2' - structures or classes containing objects are not allowed
}


Résultat :

2019.05.21 00:27:59.870 Test_ArrayCopy (EURUSD,H1)      TEST 1 (Static):TEST 1 (Static)
2019.05.21 00:27:59.870 Test_ArrayCopy (EURUSD,H1)      ArrayCopy_bypass(data_1,test_data):8
2019.05.21 00:27:59.870 Test_ArrayCopy (EURUSD,H1)      0 1 2 3 4 5 6 7
2019.05.21 00:27:59.870 Test_ArrayCopy (EURUSD,H1)      ArrayCopy_bypass(data_1,test_data,1,0,1):1
2019.05.21 00:27:59.870 Test_ArrayCopy (EURUSD,H1)      0 0 2 3 4 5 6 7
2019.05.21 00:27:59.870 Test_ArrayCopy (EURUSD,H1)      ArrayCopy_bypass(data_1,test_data,5):3
2019.05.21 00:27:59.870 Test_ArrayCopy (EURUSD,H1)      0 0 2 3 4 0 1 2
2019.05.21 00:27:59.870 Test_ArrayCopy (EURUSD,H1)      ArrayCopy_bypass(data_1,test_data,30,8,5):0
2019.05.21 00:27:59.870 Test_ArrayCopy (EURUSD,H1)      0 0 2 3 4 0 1 2
2019.05.21 00:27:59.870 Test_ArrayCopy (EURUSD,H1)      TEST 2 (DYNAMIC):TEST 2 (DYNAMIC)
2019.05.21 00:27:59.870 Test_ArrayCopy (EURUSD,H1)      ArrayCopy_bypass(data_2,test_data):10
2019.05.21 00:27:59.870 Test_ArrayCopy (EURUSD,H1)      0 1 2 3 4 5 6 7 8 9
2019.05.21 00:27:59.870 Test_ArrayCopy (EURUSD,H1)      ArrayCopy_bypass(data_2,test_data,1,0,1):1
2019.05.21 00:27:59.870 Test_ArrayCopy (EURUSD,H1)      0 0 2 3 4 5 6 7 8 9
2019.05.21 00:27:59.870 Test_ArrayCopy (EURUSD,H1)      ArrayCopy_bypass(data_2,test_data,5):10
2019.05.21 00:27:59.870 Test_ArrayCopy (EURUSD,H1)      0 0 2 3 4 0 1 2 3 4 5 6 7 8 9
2019.05.21 00:27:59.870 Test_ArrayCopy (EURUSD,H1)      ArrayCopy_bypass(data_2,test_data,30,8,5):2
2019.05.21 00:27:59.870 Test_ArrayCopy (EURUSD,H1)      0 0 2 3 4 0 1 2 3 4 5 6 7 8 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 8 9
 
Bon après-midi.
Quelqu'un peut-il me dire comment faire en sorte que le rapport du bilan dans la dernière fenêtre Profit inclue également le swap et la commission !
Ou comment le faire ?
Il n'est pas commode de regarder le bénéfice et de se rendre compte ensuite qu'il faut soustraire la commission et les swaps. C'est terriblement ennuyeux !
 

Erreur logique

void f( const int  ) {}
void f( const int& ) {}
void OnStart()
{
          int i = 0; f( i ); //(1) нормально
    const int j = 0; f( j ); //(2) Error: 'f' - ambiguous call to overloaded function with the same parameters
}

Quelle est la différence entre (1) et (2) ?