記事"MQL4からMQL5への移植"についてのディスカッション

 

新しい記事 MQL4からMQL5への移植 はパブリッシュされました:

多くの開発者はMQL4に書かれたインディケータやトレード戦略を集積しています。それらをMetatrader 5で使うにはMQL5に変換する必要があります。プログラムをすべてMQL5で書くのはそうたやすいことではありません。翻訳参照があれば変換する方が ずっと簡単です。例があればよりよいでしょう。

本稿はMQL4言語関数の簡単なガイドです。MQL4からMQL5へプログラムを移植するのに役立つことでしょう。MQL4関数(トレーディング関数以外)にはそれぞれ記述とMQL5実装が存在します。そのため移行時間が大幅に削減されます。利便性を考え、MQL4関数はグループ分けされておりMQL4参照に似た形になっています。

作者: Sergey Pavlov

 

本当にうまくいくのか?

単純なコンパイルですでに疑問が生じる。

第二に、この関数は何を返すのだろうか!

     CopyClose(symbol,timeframe,start,count,Close);
      return(ArrayMaximum(Close,start,count));

終値をKlose配列にコピーし、"start "の位置からコピーし、"counts "の数を正しくコピーする。

そしてKlose配列の 最大要素の インデックスを返す。

あなたの異端は何ですか......率直で申し訳ありません......。

 
 
テーブルの「No analogue」と書かれているセルには、mql5ではどのように解決されているのか、ドキュメントの特定のセクションを参照しながら簡単に説明してください(例えば、このように「mql5ではこうこうこう だから意味がない」というようなものです)。
 
CoreWinTT:

本当にうまくいくのか?

はい、効きます。

//+------------------------------------------------------------------+
//|をテストします。mq5
//|著作権 DC2008
//|http://mql5.commql5.com
//+------------------------------------------------------------------+
#property copyright "DC2008"
//--- 時系列配列
double            Close[];
double            Open[];
double            High[];
double            Low[];
long              Volume[];
datetime          Time[];
//+------------------------------------------------------------------+
//| エキスパート初期化関数|
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   ArraySetAsSeries(Close,true);
   ArraySetAsSeries(Open,true);
   ArraySetAsSeries(High,true);
   ArraySetAsSeries(Low,true);
   ArraySetAsSeries(Volume,true);
   ArraySetAsSeries(Time,true);
   ArraySetAsSeries(Low,true);

//---
   return(0);
  }
//+------------------------------------------------------------------+
|エキスパート初期化関数|
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| エキスパート・ティック機能|
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   Comment(
           "\niHighest",iHighest("EURUSD",PERIOD_M2,0,10,0),
           " iLowest ",iLowest("EURUSD",PERIOD_M2,0,10,0),"   Open",
           "\niHighest",iHighest("EURUSD",PERIOD_M2,1,10,0),
           " iLowest ",iLowest("EURUSD",PERIOD_M2,1,10,0),"   Low",
           "\niHighest",iHighest("EURUSD",PERIOD_M2,2,10,0),
           " iLowest ",iLowest("EURUSD",PERIOD_M2,2,10,0),"   High",
           "\niHighest",iHighest("EURUSD",PERIOD_M2,3,10,0),
           " iLowest ",iLowest("EURUSD",PERIOD_M2,3,10,0),"   Close",
           "\niHighest",iHighest("EURUSD",PERIOD_M2,4,10,0),
           " iLowest ",iLowest("EURUSD",PERIOD_M2,4,10,0),"   Volume",
           "\niHighest",iHighest("EURUSD",PERIOD_M2,5,10,0),
           " iLowest ",iLowest("EURUSD",PERIOD_M2,5,10,0),"   Time",
           "\n",""
           );

  }
//+------------------------------------------------------------------+
//||
//+------------------------------------------------------------------+
int iLowest(string symbol,
            int tf,
            int type,
            int count=WHOLE_ARRAY,
            int start=0)
  {
   ENUM_TIMEFRAMES timeframe=TFMigrate(tf);
   if(type<=0)
     {
      CopyOpen(symbol,timeframe,start,count,Open);
      return(ArrayMinimum(Open,start,count));
     }
   if(type==1)
     {
      CopyLow(symbol,timeframe,start,count,Low);
      return(ArrayMinimum(Low,start,count));
     }
   if(type==2)
     {
      CopyHigh(symbol,timeframe,start,count,High);
      return(ArrayMinimum(High,start,count));
     }
   if(type==3)
     {
      CopyClose(symbol,timeframe,start,count,Close);
      return(ArrayMinimum(Close,start,count));
     }
   if(type==4)
     {
      CopyTickVolume(symbol,timeframe,start,count,Volume);
      return(ArrayMinimum(Volume,start,count));
     }
   if(type>=5)
     {
      CopyTime(symbol,timeframe,start,count,Time);
      return(ArrayMinimum(Time,start,count));
     }
//---
   return(0);
  }
//+------------------------------------------------------------------+
//||
//+------------------------------------------------------------------+
int iHighest(string symbol,
             int tf,
             int type,
             int count=WHOLE_ARRAY,
             int start=0)
  {
   ENUM_TIMEFRAMES timeframe=TFMigrate(tf);
   if(type<=0)
     {
      CopyOpen(symbol,timeframe,start,count,Open);
      return(ArrayMaximum(Open,start,count));
     }
   if(type==1)
     {
      CopyLow(symbol,timeframe,start,count,Low);
      return(ArrayMaximum(Low,start,count));
     }
   if(type==2)
     {
      CopyHigh(symbol,timeframe,start,count,High);
      return(ArrayMaximum(High,start,count));
     }
   if(type==3)
     {
      CopyClose(symbol,timeframe,start,count,Close);
      return(ArrayMaximum(Close,start,count));
     }
   if(type==4)
     {
      CopyTickVolume(symbol,timeframe,start,count,Volume);
      return(ArrayMaximum(Volume,start,count));
     }
   if(type>=5)
     {
      CopyTime(symbol,timeframe,start,count,Time);
      return(ArrayMaximum(Time,start,count));
     }
//---
   return(0);
  }
//+------------------------------------------------------------------+
ENUM_TIMEFRAMES TFMigrate(int tf)
{
   switch(tf)
   {
      case 0: return(PERIOD_CURRENT);
      case 1: return(PERIOD_M1);
      case 5: return(PERIOD_M5);
      case 15: return(PERIOD_M15);
      case 30: return(PERIOD_M30);
      case 60: return(PERIOD_H1);
      case 240: return(PERIOD_H4);
      case 1440: return(PERIOD_D1);
      case 10080: return(PERIOD_W1);
      case 43200: return(PERIOD_MN1);      
      default: return(PERIOD_CURRENT);
   }
}
 
marketeer:
テーブルの「No analogue」と書かれているセルには、mql5ではどのように解決されているのか、ドキュメントの特定のセクションを参照しながら簡単に説明してください(例えば、このように「mql5ではこうこうこう だから意味がない」というようなものです)。

実装が複雑すぎるし、正当化されていない。結局のところ、目標はMQL4の関数を完全に放棄することなのだ。

しかし、似たようなことをするのに使えるMQL5関数への リンクを提供することができれば、私はそれを考慮しようと思います。

 

これはTF m2から取っているんだ。

TFマイグレートは0バールからのものです。

  default: return(PERIOD_CURRENT);

0小節から。

でも、例えば20気圧から試してみると...。

また混乱させようとしている。

などと、あらゆる機能でナンセンスなことを言っている。

それに、なぜTFマイグレートなんだ?

もしmql5が、mql4が持っているTFをすべて持っているとしたら......。

完全に異端だ。)

どうしてモデレーターはそんなことを見逃したのですか?

親愛なるユージーン!あなたがこの記事をチェックした人でないことを祈ります。

 
CoreWinTT:

完全に異端 =)))

司会者はどうしてこのことを見逃したのですか?

親愛なるユージーン!この記事をチェックしなかったことを願うよ。

親愛なるヴァシリー!

コメントありがとうございます。現在のバージョンを確認してください。

作者は多くの仕事をしており、エラーがあるかもしれません。

TFMigrate(int tf)関数は、MQL5のタイムフレームの 正しい値を 代入するために必要です。例えば、MQL4ではPERIOD_H1定数の数値は60であり、MQL5ではPERIOD_H1の数値は16385、すなわちTFMigrate(60)=16385である。

 

ミスはもっとたくさんあると思う。

なぜなら、そのような単純な瞬間でさえもミスは起こるからです。


あるセクションでは、関数同士が比較されている。

ある部分では、関数同士が比較されている。


この記事をどのように実装するかについて、成功した例はひとつもない、

私が理解する限り、この記事はμl4から何かを移そうとしたものだと思うのだが......。


あなたの検証に対する姿勢はいつも賞賛に値します。

それは、あなたの目に塵を投げ込みたいという著者の抑えきれない欲望だと思います。

それは確かに成功している。

私は、チェックされる素材に対するあなたの感受性を知っている。

 
CoreWinTT:


例えば20本でやってみたらどうだろう。

また混乱させようとしているのか。

などと、あらゆる機能でナンセンスなことを言っている。

そして、なぜTFを移行させるのか?

mql4が持っているTFを、mql5がすべて持っているとしたら......。

完全に異端だ。)


エラーを発見してくれてありがとう。ゼロバー以外から検索を開始できることを見落としていました。修正した関数はこちら:

//+------------------------------------------------------------------+
//|をテストします。mq5
//|著作権 DC2008
//|http://mql5.commql5.com
//+------------------------------------------------------------------+
#property copyright "DC2008"
//--- 時系列配列
double            Close[];
double            Open[];
double            High[];
double            Low[];
long              Volume[];
datetime          Time[];
//+------------------------------------------------------------------+
//| エキスパート初期化関数|
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   ArraySetAsSeries(Close,true);
   ArraySetAsSeries(Open,true);
   ArraySetAsSeries(High,true);
   ArraySetAsSeries(Low,true);
   ArraySetAsSeries(Volume,true);
   ArraySetAsSeries(Time,true);
   ArraySetAsSeries(Low,true);

//---
   return(0);
  }
//+------------------------------------------------------------------+
|エキスパート初期化関数|
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| エキスパート・ティック機能|
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   Comment(Open[0],Close[0],Open[1],Close[1],
           "\niHighest",iHighest("EURUSD",PERIOD_M2,0,10,20),
           " iLowest ",iLowest("EURUSD",PERIOD_M2,0,10,20),"   Open",
           "\niHighest",iHighest("EURUSD",PERIOD_M2,1,10,20),
           " iLowest ",iLowest("EURUSD",PERIOD_M2,1,10,20),"   Low",
           "\niHighest",iHighest("EURUSD",PERIOD_M2,2,10,20),
           " iLowest ",iLowest("EURUSD",PERIOD_M2,2,10,20),"   High",
           "\niHighest",iHighest("EURUSD",PERIOD_M2,3,10,20),
           " iLowest ",iLowest("EURUSD",PERIOD_M2,3,10,20),"   Close",
           "\niHighest",iHighest("EURUSD",PERIOD_M2,4,10,20),
           " iLowest ",iLowest("EURUSD",PERIOD_M2,4,10,20),"   Volume",
           "\niHighest",iHighest("EURUSD",PERIOD_M2,5,10,20),
           " iLowest ",iLowest("EURUSD",PERIOD_M2,5,10,20),"   Time",
           "\n",""
           );

  }
//+------------------------------------------------------------------+
//||
//+------------------------------------------------------------------+
int iLowest(string symbol,
            int tf,
            int type,
            int count=WHOLE_ARRAY,
            int start=0)
  {
   ENUM_TIMEFRAMES timeframe=TFMigrate(tf);
   if(type<=0)
     {
      CopyOpen(symbol,timeframe,start,count,Open);
      return(ArrayMinimum(Open,0,count));
     }
   if(type==1)
     {
      CopyLow(symbol,timeframe,start,count,Low);
      return(ArrayMinimum(Low,0,count));
     }
   if(type==2)
     {
      CopyHigh(symbol,timeframe,start,count,High);
      return(ArrayMinimum(High,0,count));
     }
   if(type==3)
     {
      CopyClose(symbol,timeframe,start,count,Close);
      return(ArrayMinimum(Close,0,count));
     }
   if(type==4)
     {
      CopyTickVolume(symbol,timeframe,start,count,Volume);
      return(ArrayMinimum(Volume,0,count));
     }
   if(type>=5)
     {
      CopyTime(symbol,timeframe,start,count,Time);
      return(ArrayMinimum(Time,0,count));
     }
//---
   return(0);
  }
//+------------------------------------------------------------------+
//||
//+------------------------------------------------------------------+
int iHighest(string symbol,
             int tf,
             int type,
             int count=WHOLE_ARRAY,
             int start=0)
  {
   ENUM_TIMEFRAMES timeframe=TFMigrate(tf);
   if(type<=0)
     {
      CopyOpen(symbol,timeframe,start,count,Open);
      return(ArrayMaximum(Open,0,count));
     }
   if(type==1)
     {
      CopyLow(symbol,timeframe,start,count,Low);
      return(ArrayMaximum(Low,0,count));
     }
   if(type==2)
     {
      CopyHigh(symbol,timeframe,start,count,High);
      return(ArrayMaximum(High,0,count));
     }
   if(type==3)
     {
      CopyClose(symbol,timeframe,start,count,Close);
      return(ArrayMaximum(Close,0,count));
     }
   if(type==4)
     {
      CopyTickVolume(symbol,timeframe,start,count,Volume);
      return(ArrayMaximum(Volume,0,count));
     }
   if(type>=5)
     {
      CopyTime(symbol,timeframe,start,count,Time);
      return(ArrayMaximum(Time,0,count));
     }
//---
   return(0);
  }
//+------------------------------------------------------------------+
ENUM_TIMEFRAMES TFMigrate(int tf)
{
   switch(tf)
   {
      case 0: return(PERIOD_CURRENT);
      case 1: return(PERIOD_M1);
      case 5: return(PERIOD_M5);
      case 15: return(PERIOD_M15);
      case 30: return(PERIOD_M30);
      case 60: return(PERIOD_H1);
      case 240: return(PERIOD_H4);
      case 1440: return(PERIOD_D1);
      case 10080: return(PERIOD_W1);
      case 43200: return(PERIOD_MN1);      
      default: return(PERIOD_CURRENT);
   }
}
 
CoreWinTT:

ミスはもっとたくさんあると思う。

なぜなら、そのような単純な瞬間でさえもミスは起こるからです。


あるセクションでは、関数同士が比較されている。

ある部分では、関数同士が比較されている。


この記事をどのように実装するかについて、成功した例はひとつもない、

私が理解する限り、この記事はμl4から何かを移そうとしたものだと思うのだが......。


あなたの検証に対する姿勢はいつも賞賛に値します。

それは、あなたの目に塵を投げ込みたいという著者の抑えきれない欲望だと思います。

それは確かに成功している。

私は、チェックされる素材に対するあなたの感受性を知っている。


間違いがあるかもしれない。

移植の話題(より正確には、MQL4のメソッドでエミュレーター・クラスを書くという話題)は別の記事で扱った(完成することを願っている)。 資料を読む過程で、私たちは著者に、MQL4のすべての機能(トレーディングを除く - それらの解決策の1つをすぐに見ることができるだろう)をカバーし、MQL5でそれらのそれぞれのアナログを提供し、一般的に、MQL4のプログラムを書き直す人がすぐにアナログを見つけることができるようにすべてをまとめるために、参考書の形で記事を書くように頼んだ。自由奔放な欲望について、考慮したセクションの数について言えば、私たちはすべての関数をカバーすることにこだわった(250以上になった)。

いくつかのセクションの機能の比較については、正確には比較ではなかった。たとえ同じであっても、アナログを与える必要があった。すべての関数について。だから、比較はしているようだが、たとえば数学の関数が同じであることは比較からわかる。ちなみに、推奨事項として、各セクションの冒頭で、このようなことに注意するよう記載すると便利でしょう。

この理由(エミュレータ関数のアーキテクチャ)のために、著者は実装の中でいくつかの明白でないもの(例えば、iLowest/iHighestのグローバルOpen[]...High[]...のために、以前はグローバルに宣言され、OnInitでAsSeriesにされていた)を持っていました。

テクニカル・インジケータの 操作に関しては、多くの疑問があるかもしれないが、MQL4のように操作すべきではない。しかし、ターミナルがインジケータを即座に破棄しないため、著者の提案するアプローチも機能する。というわけで、微妙な点はたくさんある。

重要なのは、もしあなたが(提案された関数の構造によって引き起こされるものも含めて)エラーを見つけたら、あなたのバリアントを提供してください。