Errori, bug, domande - pagina 2652

 
Алексей Тарабанов:

Perché state litigando? Perché non facciamo qualcosa di utile insieme?

Stanislav ha postato uno script fantasticamente utile in KB. Crea facilmente archivi con file MQL e risorse.

Ho un EA con centinaia di file mqh. Usando lo script posso ora trasferire facilmente il mio EA al codice sorgente, controllare le versioni e condividere con gli altri.

MQL5 Program Packer
MQL5 Program Packer
  • www.mql5.com
This script allows you to assemble a zip-file of your MQL5-program with all dependencies automatically. The dependencies are: included source files via #include directive (both modes of absolute () and relative ("") references are supported); icons linked by #property icon directive; resources (images, sounds, and other types) embedded by...
 
I commenti non relativi a questo argomento sono stati spostati in "Tutte le domande dei neofiti su MQL4 e MQL5, aiuto e discussione su algoritmi e codici".
 
Vladislav Andruschenko:
Grazie. Cercherò di rompere e controllare le opzioni con gli eventi del grafico.

Dai un'occhiata al thread, recentemente ha trattato la questione in dettaglio -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) Циклом-перебором до тех пор пока дата не будет совпадать(минус - скорость работы)

 это так?

A proposito di "ottenere l'indice delle barre per copiare il tempo"

Orrore, lo è davvero! Il compito era quello di ottenere le barre del timeframe M1 nell'indicatore, anche se l'indicatore stesso funziona su timeframe M5.

1. abbiamo dovuto inizializzare il timeframe desiderato in OnCalculate() per caricarlo prima dell'inizio dell'indicatore (dopo l'inizializzazione il FirstStartFlag = false;). Ricordate, negli indicatori, se non è caricato, darà -1 o non completamente caricato, quindi controlliamo quanto è caricato, se non abbastanza, andiamo all'inizio direturn(0);

dichiarare array MqlRates rates[]; all'inizio, dovecnt_bars*5; - ricalcolare il numero di barre M5 in 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);  
      }

Dopo di che, aggiorniamo i dati storici su M1 nel corpo della funzione richiesta ogni volta che eseguiamo i calcoli:

//--- загрузка актуальных данных М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);  

Inoltre, nel ciclo delle barre M5, facciamo un ciclo incorporato di ricerca dell'indice della barra M1 corrispondente,essendo time[s] la barra M5 corrente del timeframe in elaborazione:

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

E poi usiamo questo indice per trovare i dati necessari della barra M1, nel mio caso è rates[IndexRates-5].time e rates[IndexRates-k-4].close

Grazie al cielo questo ciclo annidato passa attraverso le barre rapidamente, anche su una storia di 90 giorni. Ma vorrei essere in grado di cercare gli indici delle barre nell'array rates[].time come una ricerca binaria usando la funzione ArrayBsearch

Документация по MQL5: Константы, перечисления и структуры / Торговые константы / Информация об исторических данных по инструменту
Документация по MQL5: Константы, перечисления и структуры / Торговые константы / Информация об исторических данных по инструменту
  • www.mql5.com
Константы, перечисления и структуры / Торговые константы / Информация об исторических данных по инструменту - справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 
Quali sono le differenze per il compilatore delle seguenti linee?
Print("123" "456");
Print("123" + "456");
Print("123", "456");
 
I MQL si demoralizzano poco a poco:
#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 

Breve riassunto del bug:
Quando c'è eredità di classe A <= B <= C <= D
e vengono implementate due funzioni di sovraccarico, per esempio, una con parametro A* e una con parametro B*,
Quando si passa un oggetto C* o D* in una tale funzione, il MQL causa un errore di compilazione "chiamata ambigua a funzione sovraccaricata".

Domanda: c'è un workaround più sensato a questo bug idiota di quello presentato sopra?
 
Ecco un altro foglio "Perché MQL != C++"...
 
Сергей Таболин:
Eccoci con altri "Perché MQL != C++"...

Perché commentare qualcosa se non si è arrivati in fondo?

 
Sergey Dzyublik:

Perché commentare qualcosa se non si è arrivati in fondo?

Perché ho aperto da tempo un topic per tali chiarimenti (perché nessuno come te potrebbe farlo da solo).

E poi che la differenza di lingue non ha niente a che vedere con errori o bug!

MQL v C++. Что хотелось бы, чего нет, что не так, куда копать.
MQL v C++. Что хотелось бы, чего нет, что не так, куда копать.
  • 2019.08.02
  • www.mql5.com
Общую тему багов и вопросов просто уже снасильничали такими разборками. Предложил открыть специализированную ветку, никто не чешется...
 
Sergey Dzyublik:
Il MQL si sta demoralizzando a poco a poco:

Breve riassunto del bug:
Quando c'è eredità di classe A <= B <= C <= D
e due funzioni sono implementate, per esempio, una per A* e una per B*,
In MQL, il passaggio di un oggetto C* o D* in una tale funzione causerà un errore di compilazione "chiamata ambigua a funzione sovraccaricata".

Domanda: c'è un workaround più sensato a questo bug idiota di quello presentato sopra?

Beh, STL non è trasposto uno a uno. Qui bisogna guardare da vicino le specifiche. Il modo più semplice è quello di scrivere tutte le funzionalità possibili nei metodi astratti in una classe base o interfaccia, e nei discendenti - o implementazione o =delte. In questo caso, è necessario passare puntatori o riferimenti dello stesso tipo ai metodi della classe base. Anche se c'è un male inevitabile sotto forma di una tabella virtuale, ma è meglio organizzare l'architettura in modo tale che non ci siano costose ramificazioni tramite dynamic_cast da nessuna parte.