Erreurs, bugs, questions - page 2652

 
 
Vladislav Andruschenko:
Merci. Je vais essayer de le décomposer et de vérifier les options avec des événements graphiques.

Jetez un coup d'œil au fil de discussion, qui a récemment traité la question en détail -https://www.mql5.com/ru/forum/327888.

EventChartCustom => indicator is too slow
EventChartCustom => indicator is too slow
  • 2019.12.06
  • www.mql5.com
Использую в советнике для получения тиков с других инструментов "индикатор-шпион": Периодически в журнале появляются записи "indicator is too slow...
 
Anton Shpilyuk:

2) Циклом-перебором до тех пор пока дата не будет совпадать(минус - скорость работы)

 это так?

Sur le sujet "obtenir l'index des barres par les copyrates du temps"

L'horreur, ça l'est vraiment ! La tâche était d'obtenir les barres de l'échelle M1 dans l'indicateur, bien que l'indicateur lui-même fonctionne sur l'échelle M5.

1. nous avons dû initialiser le timeframe désiré dans OnCalculate() pour le charger avant le démarrage de l'indicateur (après l'initialisation le FirstStartFlag = false ;). Rappelez-vous, dans les indicateurs, s'il n'est pas chargé, il donnera -1 ou pas complètement chargé, donc nous vérifions combien est chargé, si pas assez, nous allons au début dereturn(0);

déclarer le tableau MqlRates rates[] ; au début, oùcnt_bars*5; - recalculer le nombre de barres M5 dans M1

//--- загрузка данных М1 таймфрейма для поминутной экспирации в оптимизаторе   
   if(FirstStartFlag) 
      {
         int count = cnt_bars*5;
         int copied=CopyRates(_Symbol,PERIOD_M1,0,count,rates);
         if(copied>0) 
            {
               if(debug) Print("Скопировано баров: "+IntegerToString(copied)+", надо было "+IntegerToString(count)); 
               if(copied<count)
                  {
                      Print("Не удалось получить достаточно исторических данных, ждем");
                      return(0);
                  }
                
            }
         else  
            {
               Print("Не удалось получить исторические данные, ждем");
               return(0);
            } 
         ArraySetAsSeries(rates,true);  
      }

Ensuite, nous mettons à jour les données historiques sur M1 dans le corps de la fonction requise chaque fois que nous effectuons des calculs :

//--- загрузка актуальных данных М1 таймфрейма для поминутной экспирации в оптимизаторе    
   int count = cnt_bars*5;
   copied=CopyRates(_Symbol,PERIOD_M1,0,count,rates);
   if(copied>0) 
      {
         Print("cnt_Statist() Скопировано баров: "+IntegerToString(copied)+", надо было "+IntegerToString(count)); 
         if(copied<count)
            {
                Print("cnt_Statist() Не удалось получить достаточно исторических данных");
            }
          
      }
   else  
      {
         Print("cnt_Statist() Не удалось получить исторические данные"); 
      } 
   ArraySetAsSeries(rates,true);  

De plus, dans la boucle des barres M5, nous effectuons une boucle intégrée de recherche de l'indice de la barre M1 correspondante,time[s] étant la barre M5 actuelle du cadre temporel traité:

                          for(h=copied-1;h>0;h--)
                              {
                                 if(rates[h].time == time[s])
                                    {
                                       IndexRates = h;
                                       break;
                                    }
                              }

Ensuite, nous utilisons cet indice pour trouver les données de la barre M1 nécessaires, dans mon cas, il s'agit de rates[IndexRates-5].time et rates[IndexRates-k-4].close.

Dieu merci, cette boucle imbriquée passe les barres rapidement, même sur un historique de 90 jours. Mais je voudrais pouvoir rechercher les index des barres dans le tableau rates[].time comme une recherche binaire en utilisant la fonction ArrayBsearch.

Документация по MQL5: Константы, перечисления и структуры / Торговые константы / Информация об исторических данных по инструменту
Документация по MQL5: Константы, перечисления и структуры / Торговые константы / Информация об исторических данных по инструменту
  • www.mql5.com
Константы, перечисления и структуры / Торговые константы / Информация об исторических данных по инструменту - справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 
Quelles sont les différences pour le compilateur des lignes suivantes ?
Print("123" "456");
Print("123" + "456");
Print("123", "456");
 
Les MQLs se démoralisent peu à peu :
#ifdef __cplusplus
    #include<iostream>
    #include<stdio.h>
#endif

class input_iterator_tag  {};
class output_iterator_tag {};
class forward_iterator_tag       : public input_iterator_tag         {};
class bidirectional_iterator_tag : public forward_iterator_tag       {};
class random_access_iterator_tag : public bidirectional_iterator_tag {};

struct MyIterator{
public:
   int index;
   class iterator_category : public random_access_iterator_tag{};
   
   MyIterator(int __index = 0):index(__index){}
   
   bool operator!=(MyIterator &it){
      return index != it.index;
   }
   
   int operator-(MyIterator &it){
      return index - it.index;
   };
   
   MyIterator operator++(){
      index+=1;
#ifdef __cplusplus
      return *this;
#else
      return this;
#endif 
   } 
};

template <typename _InputIter>
int __distance(_InputIter &__first, _InputIter &__last, input_iterator_tag*){
    int __r=0;
    for (; __first != __last; ++__first)
        ++__r;
    return __r;
}

template <typename _RandIter>
int __distance(_RandIter &__first, _RandIter &__last, forward_iterator_tag*){
    return __last - __first;
}


//+------------------------------------------------------------------+
//| MQL realization                                                  |
//+------------------------------------------------------------------+
#ifdef __MQL5__
// Bypass the bug (https://www.mql5.com/ru/forum/1111/page2648#comment_15015191)
template <typename _InputIter>
int __distance(_InputIter &__first, _InputIter &__last, forward_iterator_tag* __category){
   return __distance(__first, __last, (input_iterator_tag*) __category);
};

template <typename _InputIter>
int __distance(_InputIter &__first, _InputIter &__last, random_access_iterator_tag* __category){
   return __distance(__first, __last, (bidirectional_iterator_tag*) __category);
};


// Bypass Compilation ERROR: '_InputIter' - struct undefined    
template<typename T>
class GetStructType{
public:
   struct type : public T{};
};


template <typename _InputIter>
int distance_mql(_InputIter &__first, _InputIter &__last){
   //_InputIter::iterator_category category;                      //Compilation ERROR: '_InputIter' - struct undefined  
   GetStructType<_InputIter>::type::iterator_category category;
   GetStructType<_InputIter>::type::iterator_category* ptr = &category;
   
   // Bypass the bug (https://www.mql5.com/ru/forum/1111/page2648#comment_15015191)
   random_access_iterator_tag* ptr_ra = dynamic_cast<random_access_iterator_tag*>(ptr);
   if(ptr_ra != NULL){
      return __distance(__first, __last, ptr_ra);
   };
   
   bidirectional_iterator_tag* ptr_bd = dynamic_cast<bidirectional_iterator_tag*>(ptr);
   if(ptr_bd != NULL){
      return __distance(__first, __last, ptr_bd);
   };
   
   forward_iterator_tag* ptr_fw = dynamic_cast<forward_iterator_tag*>(ptr);
   if(ptr_fw != NULL){
      return __distance(__first, __last, ptr_fw);
   };
   
   input_iterator_tag* ptr_in = dynamic_cast<input_iterator_tag*>(ptr);
   if(ptr_in != NULL){
      return __distance(__first, __last, ptr_in);
   };
   
   //TODO RAISE EXCEPTION
   return -1;
}

void OnStart(){
   MyIterator it1(1);
   MyIterator it2(5);
   printf("result:%d", distance_mql(it1, it2));            
}
#endif 


//+------------------------------------------------------------------+
//|  C++ realization, online: https://onlinegdb.com/S1tcVt9XU 	     |
//+------------------------------------------------------------------+
#ifdef __cplusplus
template <typename _InputIter>
int distance_cplusplus(_InputIter &__first, _InputIter &__last){
    return __distance(__first, __last, (typename _InputIter::iterator_category*)(NULL));
}

int main(){
   MyIterator it1(1);
   MyIterator it2(5);
   printf("result:%d", distance_cplusplus(it1, it2)); 
   
   return 0;
}
#endif 

Bref aperçu du problème:
Quand il y a un héritage de classe A <= B <= C <= D
et deux fonctions de surcharge sont mises en œuvre, par exemple, une avec le paramètre A* et une avec le paramètre B*,
En passant un objet C* ou D* dans une telle fonction, le MQL provoque une erreur de compilation "appel ambigu à une fonction surchargée".

Question : Existe-t-il une solution de contournement de ce bug idiot plus raisonnable que celle présentée ci-dessus ?
 
C'est parti pour une nouvelle fiche "Pourquoi MQL != C++"...
 
Сергей Таболин:
C'est reparti pour un nouveau "Pourquoi MQL != C++"...

Pourquoi commenter quelque chose si vous n'êtes pas allé au fond des choses ?

 
Sergey Dzyublik:

Pourquoi commenter quelque chose si vous n'êtes pas allé au fond des choses ?

Parce que j'ai depuis longtemps ouvert un sujet pour de telles clarifications (parce que personne comme vous ne pouvait le faire vous-même).

Et puis que la différence de langues n'a rien à voir avec les erreurs ou les bugs !

MQL v C++. Что хотелось бы, чего нет, что не так, куда копать.
MQL v C++. Что хотелось бы, чего нет, что не так, куда копать.
  • 2019.08.02
  • www.mql5.com
Общую тему багов и вопросов просто уже снасильничали такими разборками. Предложил открыть специализированную ветку, никто не чешется...
 
Sergey Dzyublik:
Le MQL se démoralise peu à peu :

Brève description du problème:
Quand il y a un héritage de classe A <= B <= C <= D
et deux fonctions sont mises en œuvre, par exemple, une pour A* et une pour B*,
Dans MQL, le passage d'un objet C* ou D* dans une telle fonction provoquera une erreur de compilation "ambiguous call to overloaded function".

Question : Existe-t-il une solution de contournement de ce bogue idiot plus raisonnable que celle présentée ci-dessus ?

Eh bien, la STL n'est pas transposée de un à un. Il faut regarder de près les détails ici. La manière la plus simple est d'écrire toutes les fonctionnalités possibles dans les méthodes abstraites d'une classe de base ou d'une interface, et dans les descendants - soit l'implémentation, soit =delte. Dans ce cas, vous devez passer des pointeurs ou des références du même type aux méthodes de la classe de base. Bien qu'il y ait un mal inévitable sous la forme d'une table virtuelle, il est préférable d'organiser l'architecture de telle sorte qu'il n'y ait nulle part de branchement coûteux via dynamic_cast.

 
Vladimir Simakov:

Eh bien, la STL n'est pas une solution universelle. Il faut faire très attention aux détails ici.

Vous confondez doux et chaud.
Ce n'est pas une question de STL. Je me débrouillerai là-bas moi-même... (si quelqu'un ne l'a pas, cela ne signifie pas que cela ne peut pas être fait en principe)

La façon la plus simple de mettre en œuvre toutes les fonctionnalités possibles avec des méthodes abstraites dans une classe de base ou une interface, et dans les descendants - soit la mise en œuvre ou =delte.
Dans ce cas, vous devez passer des pointeurs ou des références du même type aux méthodes de la classe de base.
Bien qu'il y ait un mal inévitable sous la forme d'une table virtuelle, il est préférable d'organiser l'architecture de telle sorte qu'il n'y ait nulle part de branchement coûteux via dynamic_cast.

La méthode que vous avez suggérée a été mise en œuvre précédemment et repose également sur le même bogue: https://www.mql5.com/ru/forum/1111/page2648#comment_15015191.


Le bogue se situe dans les priorités d'appel des fonctions rechargées lorsqu'une conversion de type implicite est effectuée pour un paramètre de type pointeur/classe.
En C++ tout est OK, mais en MQL l'erreur de compilation"appel ambigu à une fonction surchargée"
Une des variantes de contournement est suggérée ci-dessus, mais elle est volumineuse et peu pratique, et je n'ai aucune envie de l'utiliser pour une douzaine de fonctions similaires.
Peut-être y a-t-il quelque chose de plus simple ?

Raison: