初心者の方からの質問 MQL5 MT5 MetaTrader 5 - ページ 602

 
Karputov Vladimir:
インジケータかEA/スクリプトのどちらで?
インジケーターで
 

Yuri Evseenkov:

fromme2you

もう一つの質問:MT4とMQLのコード実行環境の開発者が、私の例のような例外を処理する言語の開発に心血を注ぐようにするには、どうしたらいいでしょうか?


servesdeskに連絡する、フォーラムにスレッド/アンケートを作成する。

MT4が埋もれたのは、そう昔の話ではない。彼らは市場に対して明確な見解を持っているわけではなく、市場の規制に対して明確な見解を持っているのです。

今日のレナトの投稿を ご覧ください。

レナト・ファットフーリン

...

MT4の開発は停止 しており、修正と化粧品のみとなります。

 
Alex:

こんにちは。この問題を解決する方法を教えてください。ある時間、例えば01:00のバーのオープンプライスを、例えば過去50本のバーを分析することによって見つける必要があるのです。mql5でこの作業を行うにはどうしたらいいのかわからない。


現在の日付+必要な時間を計算し、24時間を足すことでも、この方法はmql4で動作しました。

私が理解した限りでは、mql5は時間出力を持つ特殊な構造を持っていますが、なぜかそれと連動して動きません。

回答ありがとうございました。

どなたか、思考回路を理解するために、小さなコードを投げていただけるとありがたいです。
アレックス
インジケーターに

ここで、理解を深めるために、まずバーの番号に注目することをお勧めします。まず、MQL5インジケータの右端のバーがどのように番号付けされているかを正確に理解する必要があります。

そのためには、OnCalculateのインジケータに以下のようなコメントを入れてください。

//+------------------------------------------------------------------+
//|                                                         test.mq5 |
//|                              Copyright © 2016, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2016, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   1
#property  indicator_type1   DRAW_LINE
#property  indicator_color1  Blue
//--- indicator buffers
double Buffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,Buffer,INDICATOR_DATA);
//---
   ArrayInitialize(Buffer,1);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   Comment("rates_total=",IntegerToString(rates_total),
           ", time[rates_total-1]=",TimeToString(time[rates_total-1],TIME_DATE|TIME_MINUTES|TIME_SECONDS));

//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+

このコードでは、このような結果になります。

MQL5インジケータ配列の番号付け、デフォルトでは

つまり、MQL5のインジケーター配列の一番右のバーは、デフォルトで「rates_total-1」に等しいインデックスを持っています。

質問に戻りますが、最後の50小節を取り、通過する必要があります。そして、バーのオープン時間(time[]配列)を分析し、バーの時間が指定したものと等しい場合、バーのインデックスを記憶します。そして、このインデックスを使用して、open[]配列から始値を取得します。

これと似たような感じですね。

//+------------------------------------------------------------------+
//|                                                         test.mq5 |
//|                              Copyright © 2016, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2016, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.00"
#property indicator_chart_window
#property indicator_plots   0
//--- input parameters
input datetime time_open=D'01:00';     // время искомого бара
//--- parameters
int open_hour;                         // время искомого бара (часы)
int open_min;                          // время искомого бара (минуты)
bool first_start=false;                // false - значит бары ещё не искались
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   MqlDateTime str1;
   TimeToStruct(time_open,str1);
   open_hour=str1.hour;
   open_min=str1.min;
//---
   first_start=false;
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
//Comment("rates_total=",IntegerToString(rates_total),
//        ", time[rates_total-1]=",TimeToString(time[rates_total-1],TIME_DATE|TIME_MINUTES|TIME_SECONDS));
   if(!first_start)
     {
      int index=-1;
      for(int i=rates_total-1;i>rates_total-1-50;i--)
        {
         MqlDateTime str2;
         TimeToStruct(time[i],str2);
         if(str2.hour==open_hour && str2.min==open_min)
           {
            index=i;
            first_start=true;
            Print("Бар ",IntegerToString(i)," имеет время открытия ",TimeToString(time[i],TIME_DATE|TIME_MINUTES|TIME_SECONDS),
                  " и цену открытия ",DoubleToString(open[i],Digits()));
           }
        }
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
 
Karputov Vladimir:

ここで、後ほど理解を深めていただくために、まずはバーの番号付けから見ていただくことをお勧めします。つまり、MQL5インジケーターの一番右のバーがどのように番号付けされているかをまず正確に理解する必要があります。

そのためには、OnCalculateのインジケータに以下のようなコメントを入れてください。

このコードでは、このような結果になります。


つまり、MQL5のインジケーター配列の一番右のバーは、デフォルトで「rates_total-1」に等しいインデックスを持っています。

質問に戻りますが、最後の50小節を取り、通過する必要があります。そして、バーのオープン時間(time[]配列)を分析し、バーの時間が指定したものと等しい場合、バーのインデックスを記憶します。次に、open[]配列から始値を取得します。

だいたいこんな感じです。

カルプトフ ウラジミール、 ありがとうございました。お任せください。mql5はより柔軟に時系列にアクセスできると思いますが、「初心者」プログラマーには少し複雑です。:))
 
Alex:
カルプトフ ウラジミール、 ありがとうございました。本当に感謝しています。mql5はより柔軟に時系列にアクセスできると思いますが、「初心者」プログラマーには少し複雑です。:))
慣れの問題ですね。そうすれば、すべてが構造化され、簡単で正しいことが理解できるはずです。
 
Karputov Vladimir:
それは、習慣の問題です。そうすれば、すべてが構造化され、簡単で正しいことがわかるでしょう。

もうひとつ質問です。パラメータ

const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])


インジケータが適用されているペアを担当しているのだと思います。つまり、他の通貨ペアの同じ情報を得ることは不可能なのでしょうか? つまり、より普遍的な解決策は、Copy関数によってのみOCHLの同じアレイを作成することでしょうか・・・?
 
Alex:

もうひとつ質問です。パラメータ

インジケータを適用するペアの責任者であると理解しています。そして、その助けを借りて、別の通貨ペアの同じ情報を引き出すことは不可能なのでしょうか? では、より普遍的な解決策は、コピー関数を通じてのみ同じ配列OCHLを作成することでしょうか・・・?
他人のシンボルにアクセスする場合、データアクセスのオーガナイズという 理解・認識が必要なニュアンスがあります。つまり、他人のシンボルの時系列データを要求する場合、まずそのデータが用意され、存在していることを確認する必要があるのだ。これは、他人のシンボルから要求されたデータが正しいことを確認する唯一の方法です。
 
Karputov Vladimir:
他人の文字にアクセスする場合、以下のようなニュアンスで理解・認識する必要があります。つまり、他人のシンボルの時系列データを要求する場合、まずそのデータが準備され、存在していることを確認する必要があるのです。こうすることで、宇宙人に要求するデータが正しいかどうかを確認することができます。

了解です。ありがとうございます。

もう一つの質問ですが、Print()関数では常に値を文字列型に変換しているのですか?何のためにこんなことをするのか?翻訳を行わない場合、int型、double型などは、Print()関数で全く同じように表示されます。

 
Alex:

了解です。ありがとうございます。

もう一つの質問ですが、Print()関数では常に値を文字列型に変換しているのですか?何のためにこんなことをするのか?翻訳を行わない場合、int、double などの型は Print() で全く同じように表示されます。

数値がコンピュータのメモリに格納される方法と、出力される方法の2つが大きな違いです。特に浮動小数点数では、小数点以下の桁数を制限した方が良いに決まっています。

そのため、私は常に出力を正しくフォーマットするよう心がけています。IntegerToStringやDoubleToStringを 使用します。

 
Karputov Vladimir:

数値がコンピュータのメモリに格納される方法と、出力される方法の2つが大きな違いです。特に浮動小数点数では、小数点以下の桁数を制限した方が良いに決まっています。

そのため、私はいつもIntegerToStringやDoubleToStringを使って 数値出力を適切にフォーマットするようにしています。

ご回答いただき、ありがとうございました。


ウラジミール、私はあなたに疲れているのでしょう :)しかし、基本的な部分の進歩は非常に遅れています。Copy機能を使ってテストタスクをやってみたのですが・・・。指標は描かれていないが、プリンテの数字があるのに...。何もわからないんです。


//+------------------------------------------------------------------+
//|                                                        Bars.mq5 |
//|                                                                  |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright ""
#property link      ""
#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_plots   2
//--- plot UpBar
#property  indicator_label1  "UpBar"
#property  indicator_type1   DRAW_HISTOGRAM
#property  indicator_color1  clrGreen
#property  indicator_style1  STYLE_SOLID
#property  indicator_width1  6
//--- plot DnBar
#property  indicator_label2  "DnBar"
#property  indicator_type2   DRAW_HISTOGRAM
#property  indicator_color2  clrRed
#property  indicator_style2  STYLE_SOLID
#property  indicator_width2  6
//--- input parameters
input int   Histori=30;
input ENUM_TIMEFRAMES TimeFrame=0; 
input string  Simvol="EURUSD";
//--- indicator buffers
double         UpBar[];
double         DnBar[];
double         O_Price[];
double         C_Price[];



  
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,UpBar,INDICATOR_DATA);
   SetIndexBuffer(1,UpBar,INDICATOR_DATA);
   SetIndexBuffer(2,O_Price,INDICATOR_CALCULATIONS);
   SetIndexBuffer(3,C_Price,INDICATOR_CALCULATIONS);



   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,           
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
 {
ArraySetAsSeries(O_Price,true);
ArraySetAsSeries(C_Price,true);
CopyOpen(Simvol,TimeFrame,0,Histori,O_Price);
CopyClose(Simvol,TimeFrame,0,Histori,C_Price);

     for (int t=3; t<Histori; t++) 
       {
          UpBar[t]=MathAbs(NormalizeDouble((O_Price[t]-C_Price[t]),Digits()));   
          Print(DoubleToString(UpBar[t],Digits()));
       }

   return(rates_total);
  }
理由: