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

 

質問:ある期間に設定されたHandelが、他の期間のCopyBufferに 値を渡さないのはなぜですか?そして、どうすればいいのか?

もし、異なる時間軸で配列 バッファの要素を シフトさせることが問題であれば、私は問題を解決します。という具合に、まったくわからないのです。

 
kopeyka2:

質問:ある期間に設定されたHandelが、他の期間のCopyBufferに 値を渡さないのはなぜですか?そして、どうすればいいのか?

もし、異なる時間軸で配列 バッファの要素を シフトさせることが問題であれば、私は問題を解決します。という具合に、まったくわからないのです。

ハンドルの作成に成功した場合、作成時に渡したパラメータでハンドルを作成します。また、任意の時間枠で指標データを出すことができます。ただし、作成時に指定した時間枠のデータは出ます。そして、動作する時間枠に正しく表示するためには、インジケータハンドルから受け取ったデータを、インジケータが動作する時間枠に変換する必要があります。

 
kopeyka2:

ちょうどこれをチェックしていたところです。しかし、問題なのは、ハンデルを一つの永久的な期間に設定することで、である。

他の時間枠のコピーバッファの値は転送できません。設定されたハンドル期間では0.0(ゼロ)、小さい時間枠では0.0(ゼロ)となっていました。バッファを求めて移動...。ゼロです。なぜCopyBufferに 渡さないのですか?

コピーしてあるのですが・・・。

//--- Подготовка данных
   int count=(limit>1 ? rates_total : 2),copied=0;
      ResetLastError();
   if(CopyBuffer(handle_ma,0,0,1,BufferPrice)<0)
     {
      PrintFormat("Failed to copy data from the handle_ma indicator, error code %d",GetLastError());
      return(0.0);
     }
//   copied=CopyBuffer(handle_ma,0,0,count,BufferPrice);
Print(BufferPrice[0]);

もう一つの問題は、何がコピーされるのかです :)コピーするバーの本数がTFの本数を超えている可能性があります。

Print("count=",count," Bars=",Bars(Symbol(),Timeframes));
 
Artyom Trishkin:

ハンドルの作成に成功した場合、作成時に指定したパラメータで作成されたことになります。また、任意の時間枠で指標データを出すことができます。しかし、作成時に設定した時間枠のデータは出ます。そして、動作するタイムフレームに正しく表示するためには、インジケータハンドルから取得したデータを、インジケータが動作するタイムフレームに変換する必要があります。

実験のやり方は正しかったのだろうか?

1)期間D1のハンドルを作成しました。
2) 次に、CopyBufferに 指示に従い(どこからどこまで)値を入れる。
ゼロからN本目まで書きました。
ハンドルネームは、理論上、この間隔内に書く必要があります。他のタイムフレームに移行する場合でも、設定されたD1の値である必要があります。見えません。それとも何か問題があるのでしょうか?ハンドルを設定する際に、他に付け加えるべきことはありますか?バッファの転送がないため。
 
kopeyka2:
実験のやり方は正しかったのだろうか?

1)期間D1にハンドルを作成しました。
2)次に、CopyBufferに、指示に従って(どこからどこまで)値を入れていきます。
ゼロからN本目まで書きました。
ハンドルネームは、理論上、この間隔内に書く必要があります。他のタイムフレームに移行する場合でも、設定されたD1の値である必要があります。見えません。それとも何か問題があるのでしょうか?ハンドルを設定する際に、他に付け加えるべきことはありますか?バッファの移動がないため。

方向性を示したのは...

勉強して ください。


//+------------------------------------------------------------------+
//|                                                     MTF_LRMA.mq5 |
//|                        Copyright 2018, MetaQuotes Software Corp. |
//|                                                 https://mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link      "https://mql5.com"
#property version   "1.00"
#property description "Multi Timeframe Linear Regression Moving Average with signal line"
#property indicator_chart_window
#property indicator_buffers 6
#property indicator_plots   2
//--- plot LWMA
#property indicator_label1  "LRMA"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrLimeGreen
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- plot Signal
#property indicator_label2  "Signal"
#property indicator_type2   DRAW_LINE
#property indicator_color2  clrRed
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1
//--- enums
enum ENUM_DRAW_MODE
  {
   DRAW_MODE_STEPS,  // Steps
   DRAW_MODE_SLOPE   // Slope
  };
//--- input parameters
input uint              InpPeriod      =  34;               // LRMA period
input uint              InpSignal      =  5;                // Signal period
input ENUM_TIMEFRAMES   InpTimeframe   =  PERIOD_H1;        // LRMA timeframe
input ENUM_DRAW_MODE    InpDrawMode    =  DRAW_MODE_STEPS;  // Drawing mode
//--- indicator buffers
double         BufferLRMA[];
double         BufferSignal[];
double         BufferLRMATmp[];
double         BufferSignalTmp[];
double         BufferLWMA[];
double         BufferSMA[];
//--- global variables
ENUM_TIMEFRAMES   timeframe1;
int               period_lrma;
int               signal;
int               handle_lwma;
int               handle_sma;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- timer
   EventSetTimer(90);
//--- set global variables
   period_lrma=int(InpPeriod<1 ? 1 : InpPeriod);
   signal=int(InpSignal<1 ? 1 : InpSignal);
   timeframe1=(InpTimeframe>Period() ? InpTimeframe : Period());
//--- indicator buffers mapping
   SetIndexBuffer(0,BufferLRMA,INDICATOR_DATA);
   SetIndexBuffer(1,BufferSignal,INDICATOR_DATA);
   SetIndexBuffer(2,BufferLRMATmp,INDICATOR_CALCULATIONS);
   SetIndexBuffer(3,BufferSignalTmp,INDICATOR_CALCULATIONS);
   SetIndexBuffer(4,BufferLWMA,INDICATOR_CALCULATIONS);
   SetIndexBuffer(5,BufferSMA,INDICATOR_CALCULATIONS);
//--- setting indicator parameters
   string label=TimeframeToString(timeframe1)+" LRMA("+(string)period_lrma+","+(string)signal+")";
   IndicatorSetString(INDICATOR_SHORTNAME,label);
   IndicatorSetInteger(INDICATOR_DIGITS,Digits());
//--- setting plot buffer parameters
   PlotIndexSetString(0,PLOT_LABEL,TimeframeToString(timeframe1)+" LRMA("+(string)period_lrma+")");
   PlotIndexSetString(1,PLOT_LABEL,TimeframeToString(timeframe1)+" Signal("+(string)signal+")");
//--- setting buffer arrays as timeseries
   ArraySetAsSeries(BufferLRMA,true);
   ArraySetAsSeries(BufferSignal,true);
   ArraySetAsSeries(BufferLRMATmp,true);
   ArraySetAsSeries(BufferSignalTmp,true);
   ArraySetAsSeries(BufferLWMA,true);
   ArraySetAsSeries(BufferSMA,true);
//--- create handles
   ResetLastError();
   handle_lwma=iMA(NULL,timeframe1,period_lrma,0,MODE_LWMA,PRICE_CLOSE);
   if(handle_lwma==INVALID_HANDLE)
     {
      Print(__LINE__,": The ",TimeframeToString(timeframe1)," iMA(",(string)period_lrma,") object was not created: Error ",GetLastError());
      return INIT_FAILED;
     }
   handle_sma=iMA(NULL,timeframe1,period_lrma,0,MODE_SMA,PRICE_CLOSE);
   if(handle_sma==INVALID_HANDLE)
     {
      Print(__LINE__,": The ",TimeframeToString(timeframe1)," iMA(",(string)period_lrma,") object was not created: Error ",GetLastError());
      return INIT_FAILED;
     }
//--- get timeframe
   Time(NULL,timeframe1,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[])
  {
//--- Проверка количества доступных баров
   if(rates_total<fmax(signal,4)) return 0;
//--- Проверка и расчёт количества просчитываемых баров
   int limit=rates_total-prev_calculated;
   if(limit>1)
     {
      limit=rates_total-signal-2;
      ArrayInitialize(BufferLRMA,0);
      ArrayInitialize(BufferSignal,0);
      ArrayInitialize(BufferLRMATmp,0);
      ArrayInitialize(BufferSignalTmp,0);
      ArrayInitialize(BufferLWMA,0);
      ArrayInitialize(BufferSMA,0);
     }
//--- Подготовка данных
   if(Time(NULL,timeframe1,1)==0)
      return 0;
   int bars=(timeframe1==Period() ? rates_total : Bars(NULL,timeframe1));
   int count=(limit>1 ? fmin(bars,rates_total) : 1),copied=0;
   copied=CopyBuffer(handle_lwma,0,0,count,BufferLWMA);
   if(copied!=count) return 0;
   copied=CopyBuffer(handle_sma,0,0,count,BufferSMA);
   if(copied!=count) return 0;
      
//--- Расчёт индикатора
   for(int i=limit; i>=0 && !IsStopped(); i--)
     {
      BufferLRMATmp[i]=3.0*BufferLWMA[i]-2.0*BufferSMA[i];
      BufferSignalTmp[i]=GetSMA(bars,i,signal,BufferLRMATmp);
     }
   for(int i=limit; i>=0 && !IsStopped(); i--)
     {
      DataConversion(rates_total,NULL,timeframe1,i,BufferLRMATmp,BufferLRMA,InpDrawMode);
      DataConversion(rates_total,NULL,timeframe1,i,BufferSignalTmp,BufferSignal,InpDrawMode);
     }

//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Custom indicator timer function                                  |
//+------------------------------------------------------------------+
void OnTimer()
  {
   Time(NULL,timeframe1,1);
  }
//+------------------------------------------------------------------+
//| Transfering data from the source timeframe to current timeframe  |
//+------------------------------------------------------------------+
void DataConversion(const int rates_total,
                    const string symbol_name,
                    const ENUM_TIMEFRAMES timeframe_src,
                    const int shift,
                    const double &buffer_src[],
                    double &buffer_dest[],
                    ENUM_DRAW_MODE mode=DRAW_MODE_STEPS
                   )
  {
   if(timeframe_src==Period())
     {
      buffer_dest[shift]=buffer_src[shift];
      return;
     }
   int bar_curr=BarToCurrent(symbol_name,timeframe_src,shift);
   if(bar_curr>rates_total-1)
      return;
   int bar_prev=BarToCurrent(symbol_name,timeframe_src,shift+1);
   int bar_next=(shift>0 ? BarToCurrent(symbol_name,timeframe_src,shift-1) : 0);
   if(bar_prev==WRONG_VALUE || bar_curr==WRONG_VALUE || bar_next==WRONG_VALUE)
      return;
   buffer_dest[bar_curr]=buffer_src[shift];
   if(mode==DRAW_MODE_STEPS)
      for(int j=bar_curr; j>=bar_next; j--)
         buffer_dest[j]=buffer_dest[bar_curr];
   else
     {
      if(bar_prev>rates_total-1) return;
      for(int j=bar_prev; j>=bar_curr; j--)
         buffer_dest[j]=EquationDirect(bar_prev,buffer_dest[bar_prev],bar_curr,buffer_dest[bar_curr],j);
      if(shift==0)
         for(int j=bar_curr; j>=0; j--)
            buffer_dest[j]=buffer_dest[bar_curr];
     }
  }
//+------------------------------------------------------------------+
//| Возвращает бар заданного таймфрейма как бар текущего таймфрейма  |
//+------------------------------------------------------------------+
int BarToCurrent(const string symbol_name,const ENUM_TIMEFRAMES timeframe_src,const int shift,bool exact=false)
  {
   datetime time=Time(symbol_name,timeframe_src,shift);
   return(time!=0 ? BarShift(symbol_name,Period(),time,exact) : WRONG_VALUE);
  }
//+------------------------------------------------------------------+
//| Возвращает смещение бара по времени                              |
//| https://www.mql5.com/ru/forum/743/page11#comment_7010041&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |
//+------------------------------------------------------------------+
int BarShift(const string symbol_name,const ENUM_TIMEFRAMES timeframe,const datetime time,bool exact=false)
  {
   int res=Bars(symbol_name,timeframe,time+1,UINT_MAX);
   if(exact) if((timeframe!=PERIOD_MN1 || time>TimeCurrent()) && res==Bars(symbol_name,timeframe,time-PeriodSeconds(timeframe)+1,UINT_MAX)) return(WRONG_VALUE);
   return res;
  }
//+------------------------------------------------------------------+
//| Возвращает Time                                                  |
//+------------------------------------------------------------------+
datetime Time(const string symbol_name,const ENUM_TIMEFRAMES timeframe,const int shift)
  {
   datetime array[];
   ArraySetAsSeries(array,true);
   return(CopyTime(symbol_name,timeframe,shift,1,array)==1 ? array[0] : 0);
  }
//+------------------------------------------------------------------+
//| Уравнение прямой                                                 |
//+------------------------------------------------------------------+
double EquationDirect(const int left_bar,const double left_price,const int right_bar,const double right_price,const int bar_to_search)
  {
   return(right_bar==left_bar ? left_price : (right_price-left_price)/(right_bar-left_bar)*(bar_to_search-left_bar)+left_price);
  }
//+------------------------------------------------------------------+
//| Timeframe to string                                              |
//+------------------------------------------------------------------+
string TimeframeToString(const ENUM_TIMEFRAMES timeframe)
  {
   return StringSubstr(EnumToString(timeframe),7);
  }
//+------------------------------------------------------------------+
//| Simple Moving Average                                            |
//+------------------------------------------------------------------+
double GetSMA(const int rates_total,const int index,const int period,const double &price[],const bool as_series=true)
  {
//---
   double result=0.0;
//--- check position
   bool check_index=(as_series ? index<=rates_total-period-1 : index>=period-1);
   if(period<1 || !check_index)
      return 0;
//--- calculate value
   for(int i=0; i<period; i++)
      result+=(as_series ? price[index+i]: price[index-i]);
//---
   return(result/period);
  }
//+------------------------------------------------------------------+
 
Aleksey Vyazmikin:

コピーしてあるのですが・・・。

もうひとつの疑問は、何をコピーしているのか、ということです :)おそらく、そのTFにあるより多くのバーをコピーするように要求しているのでしょう。

すべてがより控えめになっています。束で入れないんです。D1では1-2小節のみ。より正確には int lm=IBarShift(NULL,PERIOD_D1, iTime(NULL,PERIOD_CURRENT, limit)) となります。
int bars=PeriodSeconds(PERIOD_D1/PeriodSecond(_Period);

int startbar=lm-(lm-bars);

CopyBufferでlimitとrate_totalを使わずにカウントしてみました。

簡単に言うと、CopyBufferで実験して、何を入れるか、そのはずです。でも、ないんです。
 

kopeyka2:
Верно ли я провел эксперемент.?

...

...他のタイムフレームに切り替えても、設定されたD1の値である必要があります。それこそ、目に見えない。それとも何か問題があるのでしょうか?ハンドルを設定する際に、他に付け加えるべきことはありますか?バッファの転送がないため。

簡単に言えば、CopyByfferで実験して、何を入れるべきかという ことです。でも、それがないんです。

データの可用性を確認していないのに、コピーしようとしている。上のコードを見てください。1分半ごとに非ネイティブのタイムフレームにアクセスする秒タイマーがあります - データを最新に保つためです。そして、コードの最初にあるのは、要求されたデータが利用可能かどうかを確認することです。もし、準備できていなければ、次のティックとインジケーターの完全な計算のためにゼロを返します。そして、すべてのデータの受信と計算、表示が終わると、次のティックで完全な再計算をしないために、最後に計算したデータ 量が返されます。

 
ありがとうございます。全部読みました。探し続けます。
 
kopeyka2:
ありがとうございます。全部読みました。探し続けます。

何をお探しですか?上記のコードは完全に動作しています。好きなように解剖してください。私はあなたの間違いを指摘しました。あなたはデータの可用性をチェックしていません。

ここのラインでも。

int lm=IBarShift(NULL,PERIOD_D1, iTime(NULL, PERIOD_CURRENT, limit));

iTime()が何を返したかのチェックはどこにある?チェックはありません。しかし、未知の結果をそのままiBarShift()に押し込んでしまうのです。関数に期待通りのものを与えているか?

 
Artyom Trishkin:

ハンドルの作成に 成功した場合、作成時に指定したパラメータで作成 されます。そして、どのタイムフレームでもインジケーターデータを通過させることができます。ただし、作成時に設定した時間枠のデータは出ます。そして、動作する時間枠に正しく表示するためには、インジケータハンドルから受け取ったデータを、インジケータが動作する時間枠に変換する必要があります。

まさにその通りだと思いました。誤解を招く問題は、「パラメータ」という言葉です。そこで、handle --> CopyBufferに関係するすべての変数を調べ始めました。

1)当初からの疑問は、タイムフレームSCREENを切り替えてハンドルデータを保存することでした。MT4でそのまま。

そして実際、そうなっているのです。

handle_ma=iMA(NULL,PERIOD_H1,period,0,MODE_SMA,PRICE_CLOSE); 

 Comment(handle_ma);  // ВСЕГДА 10

常に、そしてすべてのタイムフレームで、同じ値である10を表示します。

ここで何も得られなかったので、私は次に進みました。

2)そして、引用します。"指定されたインジケータの指定されたバッファのデータを指定された量だけバッファ配列に取得 します"。

CopyBuffer(handle_ma,0,0,count,BufferPrice);  //

つまり、手でカウントを 設定することで 、値との間にINTERVALを 持たせる必要があります。 そして、そこにいるのは!しかし!!!!!!!ハンドル期間と一致する場合のみ

PERIOD_H1 のタイムフレームをモニター画面に 表示します。 すべての価値をクリアに伝える。しかし、別のタイムフレームに移動すると、画面上にデータがありません。

一切送信されません!!!! そして、私の質問はまさにそれでした。そして、バーの数は、そこになければ、ここではそれほど重要ではありません!!!!


提案されているインジケータMTF_LRMA.mq5を見て みましたが、同じ です。 画面上の別のタイムフレームに切り替わり、データは画面のタイムフレームで進みます。携帯機でお願いします。

例えば、iClose(NULL, PERIOD_H1, 5); 全てのタイムフレームで同じ値:H1の5本のバーのクローズとなります。

これまで全ての例は、 CopyBufferの カウント補正に関するものでした。 しかし、配列は空である。


理由: