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

 
原理的にはそうなのですが、私のインジケータのハンドルはOnTick関数で作成されており、同じティックですぐにデータがコピーされることがエラーになっているのだと思われます。夜中に理解できたので、今度はOnInit関数に インジケータハンドルを転送してみようと思います。
Документация по MQL5: Основы языка / Функции / Функции обработки событий
Документация по MQL5: Основы языка / Функции / Функции обработки событий
  • www.mql5.com
Основы языка / Функции / Функции обработки событий - Документация по MQL5
 
sss20192:
OnTick関数で作成したインジケータハンドルにエラーがあり、同じtickでデータがコピーされる。夜中に理解できたので、今度はOnInit関数に インジケータハンドルを転送してみようと思います。

うまくいかなかった。以下は、現在のコードです。


#property version   "1.00"

input int                  InpFastEMA=12;                // Fast EMA period
input int                  InpSlowEMA=26;                // Slow EMA period
input int                  InpSignalMA=9;                // Signal MA period
input ENUM_APPLIED_PRICE   InpAppliedPrice=PRICE_CLOSE;  // Applied price
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int Handle1, Handle2, Handle3;
double MacdArray[];

int OnInit()
  {
//---
  Handle1 = iMACD(_Symbol, PERIOD_M5, InpFastEMA, InpSlowEMA, InpSignalMA, InpAppliedPrice);
  Handle2 = iMACD(_Symbol, PERIOD_M15, InpFastEMA, InpSlowEMA, InpSignalMA, InpAppliedPrice);
  Handle3 = iMACD(_Symbol, PERIOD_H1, InpFastEMA, InpSlowEMA, InpSignalMA, InpAppliedPrice);
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
        CopyBuffer(Handle1, 0, 1, 1, MacdArray);
        Print(MacdArray[0], " ", GetLastError());
        
        CopyBuffer(Handle2, 0, 1, 1, MacdArray);
        Print(MacdArray[0], " ", GetLastError());
        
        CopyBuffer(Handle3, 0, 1, 1, MacdArray);
        Print(MacdArray[0], " ", GetLastError());
  }
//+------------------------------------------------------------------+

ログには次のようなメッセージが表示されます。

2013.04.13 15:21:31 2010.01.04 00:00:01 6.187448020344988e-005 0

2013.04.13 15:21:31 2010.01.04 00:00:01 6.187448020344988e-005 0

2013.04.13 15:21:31 2010.01.04 00:00:01 6.187448020344988e-005 0

そして、いつもそうなんです。コピーエラーはないようです。

 
sss20192: 役に立たなかった。以下はそのコードです。

しかし、今のところ、ハンドルの作成に 成功した場合のチェックも、インジケータの計算に 成功した場合のチェックも、コピーのチェックもできていませんね。ハンドルの初期化をOnInit()に移すという考え方は正しいです。

また、OnTick() の最初にPrint(MacdArray[0]) 行を追加して、バッファのコピーを開始する前に配列にどんなゴミ値が含まれているかを確認するようにします。

追加すること。もちろん、関数自体の後でGetLastError()を使うのは、プログラミングスタイルの特殊性かもしれません。私の記憶では、GetLastError()の値がNullであっても、その関数が正常に動作したとは限りません。

 
Yedelkin:
しかし、今のところ、ハンドルの作成に 成功した場合のチェックも、インジケータの計算に成功した場合のチェックも、コピーのチェックもできていませんね。ハンドルの初期化をOnInit()に移すという考え方は正しいです。
でも、最初だけです。も し、プログラムの他の場所で、あるハンドルが無効であることが判明した場合、再度ハンドルを取得する必要があります。したがって、OnInit()でハンドルを取得するために書かれたコードが完全に問題を解決し、100%正しいとは言えません。))
 
CopyBuffer関数で どれだけデータがコピーされたかを確認したところ、常に1が書き込まれており、エラーは発生していませんが、やはりデータがおかしいです。
Документация по MQL5: Доступ к таймсериям и индикаторам / CopyBuffer
Документация по MQL5: Доступ к таймсериям и индикаторам / CopyBuffer
  • www.mql5.com
Доступ к таймсериям и индикаторам / CopyBuffer - Документация по MQL5
 

tol64

Yedelkin :ハンドルの初期化をOnInit()に移すというのは、いいアイデアですね。

でも、最初だけです。もし、プログラムのどこかでハンドルが無効であることが判明した場合、再度ハンドルを取得する必要があります。したがって、OnInit()でハンドルを取得するために書かれたコードが完全に問題を解決し、100%正しいとは言えません。))

ハンドルの初期化をOnTick()からOnInit()に移すという発想自体が間違って いるということでしょうか。
 
sss20192:
CopyBuffer関数で どれだけデータがコピーされたかを確認したところ、常に1が書き込まれており、エラーは発生していないのですが、データがおかしいままです。

このコードをテスターにかけると、このような結果になります。

//---

テスト前にやったことは、ログに出力する前のインジケータの値を変換しただけです。

Print(DoubleToString(MacdArray[0],Digits())," ",GetLastError());
 
Yedelkin:
ハンドラの初期化をOnTick()からOnInit()に移すというアイデア自体が間違って いるということでしょうか?
OnInit()の中だけで、他のどこにもない場合は、はい - 間違いです。OnInit()で初めてハンドルを取得しようとする。そして、インジケータデータの取得を試みる前に、毎回ハンドルが有効かどうかをチェックします。有効であればデータを取得し、有効でなければ再度ハンドルの取得を試みる。
 
tol64:

このコードをテスターで確認したところ、このような結果になりました。

//---

テスト前に行ったのは、ログに出力する前にインジケータの値を単純に変換しただけです。

Ooohtyg genius!ありがとうございました。3日目の問題解決)
 
tol64:
Yedelkin: ハンドルの初期化をOnTick()からOnInit()に移すというアイデア自体が間違って いるということでしょうか。
OnInit()の中だけで、他のどこにもない場合、はい - 間違いです。OnInit()で初めてハンドルを取得しようとする。そして、インジケータデータの取得を試みるたびに、そのハンドルが有効かどうかをチェックするのです。有効であればデータを取得し、有効でなければ再度ハンドルの取得を試みる。

そして、"if "なし?この特別な状況との関連は?インジケーターのハンドルは、 毎ティック 中のOnTick関数で 作成され、同じティックの間にデータがコピーされます。有効/無効を確認せず、毎回同じインジケータハンドルを要求したことを意味します。このような背景から、ハンドルの初期化をOnTick()からOnInit()に移すという考え方 自体が間違って いると主張し続けるのでしょうか。

PS.その人を助けたようですから、質問は出尽くしたとみてよいでしょう。

理由: