エラー、バグ、質問 - ページ 2652

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

なぜ戦うのですか?一緒に何か役に立つことをしませんか?

Stanislavは、KBに幻想的な有用なスクリプトを投稿 しました。MQLファイルやリソースを使ったアーカイブを簡単に作成することができます。

数百のmqh-fileを持つEAを持っています。このスクリプトを使えば、自分のEAを簡単にソースコードに転送し、バージョンを管理し、他の人と共有することができるようになりました。

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

 это так?

"タイムコピーレートによるバーインデックス取得 "について

ホラー、本当にあるんだ!課題は、インジケータ自体はM5タイムフレームで動作しているが、インジケータにM1タイムフレームのバーを取得することであった。

1. OnCalculate()で目的のタイムフレームを初期化して、インジケータの開始前にロードする必要がありました(初期化の後、FirstStartFlag = false;)。覚えておいてほしいのは、インジケータでは、読み込まれていない場合は-1、あるいは完全に読み込まれていない場合は、読み込まれているかどうかをチェックし、十分でない場合は、return(0) の先頭に行くということです。

冒頭で配列MqlRates rates[]を宣言し、cnt_bars*5; - M1のバーの数M5を再計算 する

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

その後、計算を行うたびに必要な関数本体でM1のヒストリカルデータを 更新しています。

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

さらに、M5バーのループの中で、対応するM1バーのインデックスを検索するループを埋め込みます。time[s]は 計算対象の時間枠の現在のM5バー です。

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

そして、このインデックスを使って必要なM1バーのデータを探します。私の場合、それはrates[IndexRates-5].timeとrates[IndexRates-k-4].closeです。

このネストされたループは、90日間の履歴であっても、すぐにバーを通過してくれるのがありがたい。しかし、バイナリサーチ関数ArrayBsearchを使って配列rates[].timeの中のバーインデックスを検索できればいいのですが......。

Документация по 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
であり、例えばパラメータA*を持つものとパラメータB*を持つものの2つのオーバーロード関数が実装されています。
このような関数に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
で、例えばA*とB*の2つの関数が実装されています。
このような関数にC*またはD*オブジェクトを渡すと、MQLは "ambiguous call to overloaded function "というコンパイルエラーを発生させます。

質問:この馬鹿げたバグに対して、上で紹介したものよりもっと賢明な回避策はあるのでしょうか?

まあ、STLは一対一でトランスポーズしているわけではないのですが。ここでは、その具体的な内容をよく見てください。最も簡単な方法は、ベースクラスやインターフェースの抽象メソッドに可能な限りの機能を書き、その子孫には、実装か=delteのどちらかを書くことである。この場合、ベースクラスのメソッドに同じ型のポインタまたは参照を渡す必要があります。仮想テーブルという弊害はありますが、高価なdynamic_castの分岐がどこにもないようなアーキテクチャにしたほうがよいでしょう。