Ошибки, баги, вопросы - страница 2652

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

Че бодаетесь? Сделали бы вместе что-нибудь полезное. 

Станислав выложил фантастический по полезности скрипт в КБ. С легкостью создает архивы с MQL-работами, куда включаются mq?-файлы и ресурсы.

У меня советник из сотни mqh-файлов. С помощью скрипта теперь могу запросто переносить в исходниках советник, контролировать версии и делиться с другими.

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...
 
Комментарии, не относящиеся к этой теме, были перенесены в "Любые вопросы новичков по MQL4 и MQL5, помощь и обсуждение по алгоритмам и кодам".
 
Vladislav Andruschenko:
Спасибо. Попробую разобрать и проверить варианты событиями графика. 

Загляните в веточку, недавно как раз разбирал вопрос подробно - 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) Циклом-перебором до тех пор пока дата не будет совпадать(минус - скорость работы)

 это так?

По теме "получить индекс бара по времени copyrates"

Ужас, реально так! Стояла задача в индикаторе получить бары М1 таймфрейма, хотя сам индикатор работает на М5 таймфрейме.

1. пришлось инициализировать нужный таймфрейм в OnCalculate(), чтобы он подгрузился до старта индикатора (после инициализации флаг FirstStartFlag = false;). Помним, что в индикаторах, если не подгружено, выдаст -1 или загрузит не полностью, поэтому проверяем сколько загружено, если не достаточно, идем в начало return(0);

объявляем массив MqlRates rates[]; в начале, где cnt_bars*5; - пересчитываем количество баров М5 в М1

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

После этого уже в теле нужной функции каждый раз при расчетах обновляем исторические данные по М1:

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

Далее, в цикле перебора М5 баров делаем вложенный цикл поиска индекса соответствующего М1 бара, time[s] - текущий обрабатываемый бар М5 таймфрейма:

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

Ну и далее используем этот индекс для нахождения нужных данных М1 баров, в моём случае rates[IndexRates-5].time и rates[IndexRates-k-4].close 

Слава богу этот вложенный цикл быстро перебирает бары. даже на истории 90 дней. А так бы хотелось, чтобы можно было искать индекс бара в массиве rates[].time по типу двоичного поиска функцией ArrayBsearch

Документация по MQL5: Константы, перечисления и структуры / Торговые константы / Информация об исторических данных по инструменту
Документация по MQL5: Константы, перечисления и структуры / Торговые константы / Информация об исторических данных по инструменту
  • www.mql5.com
Константы, перечисления и структуры / Торговые константы / Информация об исторических данных по инструменту - справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 
Какие различия для компилятора у следующих строк?
Print("123" "456");
Print("123" + "456");
Print("123", "456");
 
MQL понемногу деморализует:
#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 

Краткая суть бага:
Когда есть наследование классов A <= B <= C <= D
и реализованы две overloading функции, например одна c параметра А*, а вторая с B*,
то передача в такую функцию объекта C* или D* в MQL вызывает ошибку компиляции "ambiguous call to overloaded function".

Вопрос: есть ли более вменяемый обход этого идиотского бага, чем представленный выше?
 
Пошли очередные простыни "Почему MQL != C++"...
 
Сергей Таболин:
Пошли очередные простыни "Почему MQL != C++"...

Зачем что-то комментировать, если вы ни как не разобрались в сути вопроса?

 
Sergey Dzyublik:

Зачем что-то комментировать, если вы ни как не разобрались в сути вопроса?

Затем, что я уже давно открыл тему для подобных выяснений (потому что никто из таких как Вы сами никак этого сделать не могли).

И затем, что разница в языках ни к ошибкам, ни к багам не относится!

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

Краткая суть бага:
Когда есть наследование классов A <= B <= C <= D
и реализованы две функции, например одна для параметра А*, вторая для B*,
то передача в такую функцию объекта C* или D* в MQL вызывает ошибку компиляции "ambiguous call to overloaded function".

Вопрос: есть ли более вменяемый обход этого идиотского бага, чем представленный выше?

Ну не перекладывается STL один в один. Тут надо с большим оглядом на специфику. Проще всего весь возможный функционал абстрактными методами в базовом классе или интерфейсе прописать, а в наследниках - или реализацию, или =delte. В этом случае передаются в методы указатели или ссылки с типом этого самого базового класса. Правда тут неизбежное зло в виде виртуальной таблицы, но это бог с ним, а вот архитектуру желательно выстроить, что бы не было нигде дорогого ветвления через dynamic_cast.

Причина обращения: