[SERVICE DESK】タイマーでシニアTFの時刻を取得する際にエラーが発生!? - ページ 5

 
Vitaly Gorbunov:
iBarShiftメソッドでは履歴の穴を見つけることができますが、間隔を空けて履歴を確認する必要があります。これを行う自分用のプロシージャを書き、それ以降はMtFのプログラムの隙間は忘れています。
穴」を検出する問題ではなく、その人は履歴の最後のバーを取得したかったのです。 そして、これは必ずしも時間的に現在のバーであるとは限りません。
 
Vitaly Gorbunov:
4066エラーでデータが読み込まれ、その後、メタコトーブの障害である、最も可能性が高い受信データは、この状況のために処理され、エラーは発明されませんでした。そして、その時点までは、すべてが理にかなっているのです。

あるエラーが「発明されていない」としても、それは「存在しない」という意味ではありません。

 
Alexey Navoykov:
穴」を検出するのではなく、履歴の最後のバーを取得したいとのことでした。 そして、これは必ずしも現在の時刻のバーとは限りません。

iBarShift()のことではありません。iTime()、SeriesInfoInteger()と同様のエラーを送出します。ここでは、初期化時に取得した時間をタイマーからの時間と比較するところにヒントを得ています。これは、IBarShift()ではなく、ターミナルを読み込む際に正しい実際のデータを取得できるようにするためのものです。

はい、そして時間が15:00:45(例)で、15:00のバーにはまだティックがなく、最後の時間のバーが開く時間が 14:00であれば、すべてが正しい、と私は思います。そして、システムが13:00を返してきたら......それは問題です。

 
Alexey Kozitsyn:

1.イゴール、コードを見たか?OnInit()のどこに何かあるのでしょうか?

この場合、OnInit()の直後に1つまたは複数のOnTimerコールが実行されます。OnCalculate()イベントはまだありません。

2.何のチェック?インジケータが正しく動作するためには、少なくとも一度はOnCalculate()を使用しなければならないとありますが、どこに書かれていますか?

ここで、端末のロジックを理解する必要があります。OnInit()は、インジケータをチャートに接続する際にすぐに呼び出されます。ターミナルを起動すると、チャートウィンドウを作成した直後に、インジケーターとチャートの接続が実行されます。この時点では、端末はサーバーにリクエストを送信すらしていない。

最初の OnCalculate() は、利用可能な相場がローカルに読み込まれた後に呼び出されます。まれに、ローカルに何もないことがあります。この場合、Time[0]にアドレス指定すると、インジケータは配列から外れてしまいます。そのため、iTime機能などを利用するのがよいでしょう。

2回目と次のOnCalculate()は、ヒストリのロード時または実Tickの到着時に発生します。

 
Ihor Herasko:

最初のOnCalculate()は、ローカルで利用可能な引用符を読み込んだ後に呼び出されます。まれに、ローカルに何もないことがあります。この場合、Time[0]を参照すると、インジケータは配列から外れてしまいます。そのため、iTime機能などを利用するのがよいでしょう。

私たちはMQL5について話しているのだと思いますが、OHLCの準備はMT4とは異なっています。

私は長い間、テンプレートを元にインジケーターを書いてきました。

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[])
  {
//---
   int i,limit;
   if(prev_calculated==0)
     {
      limit=rates_total-1;    //--- Первый вызов индикатора или смена таймфрейма или подгрузка данных из истории
     }
   else limit=rates_total-prev_calculated+1;
   for(i=limit;i>=0;i--)      //---- Основной цикл расчета
     {                        
     }
   return(rates_total);
  }

MT4では、チャートが初めて準備されるまでOnCalculate()が実行されず、履歴がロードされている場合、私はそれを確認していませんが、prev_calculated=0 、MT5ではあなたが書いたようになります - OHLCデータが既に準備されているかどうかを確認するための追加チェックが必要です。

 
Ihor Herasko:

この場合、OnInit()の直後に1つまたは複数のOnTimerコールが実行されます。OnCalculate()イベントはまだありません。

ここでは、端末のロジックを理解する必要があります。OnInit()は、インジケータをチャートに接続する際にすぐに呼び出されます。ターミナルを起動すると、チャートウィンドウが作成された直後にインジケーターとチャートの接続が行われます。この時点では、端末はサーバーにリクエストを送信すらしていない。

最初の OnCalculate() は、利用可能な相場がローカルに読み込まれた後に呼び出されます。まれに、ローカルに何もないことがあります。この場合、Time[0]にアドレス指定すると、インジケータは配列から外れてしまいます。そのため、iTime機能などを利用するのがよいでしょう。

2回目と次のOnCalculate()は、ヒストリのロード時または実Tickの到着時に発生します。

問題を解決するために、どのようなことを提案しますか(ありますか、あなたの意見で)。OnCalculate() が1-2回呼ば れるまで待つ?

 
Alexey Kozitsyn:

問題を解決するために、どのようなことを提案しますか(ありますか、あなたの意見で)。OnCalculate() が1-2回呼ば れるまで待つ?

prev_calculated==0の 値をグローバルスコープの変数にコピーして、OnTimer()でインジケータが計算されたかどうか見て みるとよいでしょう。OnCalculate() - いずれにしても計算されます。TFデータが準備できていなかった 場合、return(rates_total)は0を返し、次のOnCalculate()の呼び出しでprev_calculated=0を示す のではないかと思います、おおよそですが

void OnTimer(){
   if(Global_prev_calculated==0)return;
}
 
Igor Makanu:

prev_calculated==0の 値をグローバルスコープの変数にコピーして、OnTimer()でインジケータが計算されたかどうかを確認することができます; 私は上で、MT4で間違った計算をするバグを見たことが ないと書きましたOnCalculate() - どのような場合でも計算されます、私はTFデータが準備ができていなかった場合、return(rates_total)は0を返し、次のOnCalculate()の呼び出しでprev_calculated=0の符号と なることを疑って いる。

最も確実な解決策は、取引サーバーへの接続を確認しながらOnCalculate()の呼び 出しを待つことだと思われます。接続チェック(IsConnected())を行わないと、端末を読み込むOnCalculate()でも取得されてしまうのだそうです。

2018.09.21 23:45:27.128 test_isNewDayInOnCalculate_iBarShift() EURGBP.e,M1: test_isNewDayInOnCalculate_iBarShift().mq4: Актуальное время открытия бара М15 = 2018.09.21 21:30. Ошибка #0
2018.09.21 23:45:25.990 test_isNewDayInOnCalculate_iBarShift() EURGBP.e,M1: initialized
2018.09.21 23:45:25.975 Custom indicator test_isNewDayInOnCalculate_iBarShift() EURGBP.e,M1: loaded successfully

しかし、すべての疑問が解消されるわけではありません。

1.IsConnected()のドキュメントに、OnCalculate()でシニアTFから(少なくとも)データを受け取る前に必ず呼ばれなければならないと書かれていないのはなぜでしょうか?

2.OnTimer()内のIsConnected()が実際に動作しないのはなぜですか?トレードサーバーとの接続を確立するということは、データが取得できるということではないのでしょうか。

3.トレードサーバとの接続を確立し、OnTimer()でデータを受信しようとした場合、iTime()、iBarShift()、SeriesInfoInteger()やそれに類する関数は、情報を取得するこの特定のトレードサーバからのデータがまだ同期されていなければエラーを返すべきではないでしょうか。そうでなければ、一旦エラー4066を返して、その後、現在のデータを好きなように使うような、ナンセンスな感じになります。

 
Alexey Kozitsyn:

しかし、これですべての疑問が解消されるわけではありません。

1.IsConnected()のドキュメントには、OnCalculate()でシニアTFから(少なくとも)データを受け取る前に必ず呼び出さなければならないと書かれていないのはなぜでしょうか?

2.OnTimer()内のIsConnected()が実際に動作しないのはなぜですか?トレードサーバーとの接続を確立するということは、データが取得できるということではないのでしょうか。

3.トレードサーバとの接続を確立し、OnTimer()でデータを受信しようとした場合、iTime()、iBarShift()、SeriesInfoInteger()やそれに類する関数は、情報を取得するこの特定のトレードサーバからのデータがまだ同期されていなければエラーを返すべきではないでしょうか。そうでなければ、一旦4066エラーを返して、その後、既存のデータを好きなように使うというようなナンセンスなことになるようです。

1.まあ、誰もヒストリカルデータでインジケータ呼び出しの ケースをキャンセル、あなたがオンラインで動作する必要がある場合は、接続を確認し、そうでない場合、というか重要ではない、その後私のバージョンのテンプレートが動作します。 IsConnected()関数群は、実際には少しトリッキーです、彼らは時々、 IsTradeContextBusy()、 IsConnected()自体を交差し IsTradeAllowed()・・・。サーバー側をごまかして、ニュースタイムに端末を切断するとか、そういう操作をしていると思います

2,3.はうまくいくのですが、GetLastError()が呼び出し後に状態をリセットすることを忘れています。おそらく状態を更新するためにGetLastError()は端末に制御を移す必要があり、おそらく端末はタイマーからの呼び出し前にGetLastError()で状態ISConnected()を再セットする時間を持っていなかった...と思います。OnTimer()関数は、データ受信を目的としていないのでは?"MQL4 Reference / Status Check - OnTimer()が呼ばれるが、端末環境の変数は更新されず、onCalculate() ではtickが来たときに端末からすべてのデータを準備することが保証 されている。

 
Igor Makanu:

1.まあ、過去のデータでインジケータを呼び出す ケースは誰もキャンセルしていないのですが...。

2,3.はうまくいくのですが、GetLastError()が呼び出し後に状態をリセットすることを忘れています。おそらく状態を更新するためにGetLastError()は端末にコントロールを渡す必要があり、おそらく端末はタイマーからの呼び出し前にGetLastError()で状態ISConnected()を再セットする時間がないのです・・・・・。OnTimer()関数は、データ受信を目的としていないのでは?"MQL4 Reference / Status Check - OnTimer()が呼び出されますが、端末環境の変数は更新されず、ティックが来た時に端末が全てのデータを準備することが保証 されています -OnCalculate()"です。

1.バー番号0が不正確な時刻であっても、残りの履歴は正しい時刻になると思いますか?)

2,3.データアクセス関数が意味のあるエラーを設定するのに十分な時間がない場合、何らかの方法でエラーを報告させることができます。残りの「かも」は推測に過ぎない。そして、証拠がなければ、何も話すことはありません。

OnTimer()関数は、データを取得するためのものではありません...

ノーコメントです。

OnTimer()は呼び出されるが、端末の環境変数は必ずしも更新されない

4066エラーは何のために必要なのでしょうか?