オフラインまたはティック分布がない場合、さまざまな時間枠の情報を取得するにはどうすればよいですか?

 

オフラインまたはティック分布なし(MTF:マルチタイムフレーム操作、MT5)のときに、指定したタイムフレームに対してiBars()が必要です。


私が見つけた方法は、チャートを右クリックして更新を実行するか、手動で一度別の時間枠に切り替えてから、目的の時間枠に戻ってチャートを表示するかのいずれかです。これをコードで解決したいと思います。指定した時間枠で iBars() が成功すれば、問題なく各関数が取得できるようです。つまり、オフラインまたはティック分布がないときに、インジケーターをチャートに適用したとき、またはターミナルを再起動したときに問題が発生します。 Refresh() はインジケーター以外のオブジェクトの再描画のみに関連する関数であるため、この問題には影響しないようです。また、ChartSetSymbolPeriod()関数は使いにくいです。

問題点を考察するためのインジケーターコード(MT5)を添付します。

ありがとう。

 

オフラインとはカスタムシンボルのことですか?

ティック分布とは何のことか分かりません。

一応私の理解としては、カスタムシンボルで、ある時間枠から別の時間枠の計算をするためにiBars()の値を取得したいということでいいでしょうか?

添付のプログラムを実行してみると確かに0が返ってきます。

しかし1度終了してから、もう一度実行すると今度は正しく読み取れています。

そこで、ibars_time_frame == 0 ならプログラムを強制終了して、同時にOnDeinitで再実行するようにしたらいいのと違いますか?

 

英語で投稿したのですが、一部おかしな訳になっているようです。

オフラインとはネットワークの切断のことで、チックの配信が無い(土曜、日曜)ときも同様です。このとき、現在のタイムフレームつまりインジケータを表示しているH1とかの時間枠とは異なる、M5などのタイムフレームの情報(主に iBars)を取得しようとするとゼロ(0)になってしまう。

オンライン及びティック配信があるときは最初のティックを受け取るとどのタイムフレームの情報も取得できるようになります。あるいは先に書いたようにチャート上で「更新」を実行すると取得できます。

どうしてこのような仕様になっているのか理解に苦しみます。他の時間枠の情報もいつでも安定して取得できるようにしてほしいと思っています。


>OnDeinit()で再実行...


これはいいかもしれませんね。ありがとうございました。
 

ChartSetSymbolPeriod()に関して、シンボルとタイムフレームが現在と同じときは無視され何も実行されないと思い込んでいました。

しかし現在のシンボル、タイムフレームを指定すると、チャート上で右クリック「更新」と同じ動作になるとヘルプで見つけました。ただし非同期な動作ということで、そのあとのコードの実行とプログラムの再起動が両方同時にしばらく実行されます。OnCalculate() の retern(0) はこの事に都合よく、うまく「更新」ができます。これをなんとか OnInit() の中にもっていこうとしても上手くいきませんでした。

「プログラムを強制終了して、同時にOnDeinitで再実行」という仕組みはすぐに分かるかなと思っていましたが手こずり成果は出ませんでした。

ChartSetSymbolPeriod() を使ったコードを添付します。

これで安心してMTF(Multi Time Frame)が構築できそうです。

願わくば、Metatrader5 の仕組みとして「更新」を掛けなくても、オフラインであっても、取り込み済みのデータは特別な操作を必要とせず扱えるようにしてほしいです。

(英語では「更新」を update と訳しているようですが、MT5ターミナルの言語を English にした時のチャート右クリックに現れるのは "Reflesh" です)

 

なるほど。 ChartSetSymbolPeriod() の動作については私も知りませんでした。

強制終了は ChartIndicatorDelete() で、再起動は ChartIndicatorAdd() でできます。

起動するときの指標ハンドルは iCustom で取得できます。

この時、起動条件を設定しておかないと手動で終了することができなくなります。

 

解決したと思っていましたが週末になり、 On-Line だけれど Tick 配信が無い状態、つまり土日にブローカーとつながっている状態では、先のどちらのコードも動作に不具合がでました。どうやらこの状況では、 Refresh をコードや手動で行うと、一旦は 目的のタイムフレームのバー数 を取得してインジケーターを描くループを経過したあと、return(rates_total); で戻るはずが、prev_caluculated = 0 とし、および、目的のタイムフレームのバー数をなぜか  ゼロ としてもう一度 OnCalculate を回します。どうにもならないので、教えていただいたインジケーターの再起動に挑戦してみました。まだ履歴を取得していない新しい銘柄のデータを取得中にタイムフレームを手動で切り替えるなどの特殊な場合はチャートの削除で止まってしまうことは有りましたが、そのほかは大丈夫そうです。

コードを添付します。指標を描くと成功したような気になるので、あえて Empty_value としました。

教えていただき、ありがとうございました!

起動するときの指標ハンドルは 重要ですね。起動条件というのは DeInt() の reason かなと。)

 

もっと単純化してもいいかなと思います。

return(rates_total); の後、先に進まないのでその後の動作は確認していません。

int OnInit()
{
   //--- indicator buffers mapping
   SetIndexBuffer(0, indPriceBf, INDICATOR_DATA);
   ArraySetAsSeries(indPriceBf, true);
   IndicatorSetString(INDICATOR_SHORTNAME, shortname);
   //
   ibars_time_frame = iBars(_Symbol, inpTimeFrame);
   ibars_current = iBars(_Symbol, _Period);
   Print(__FUNCTION__, "   ibars_current:", ibars_current, "   ibars_time_frame:", ibars_time_frame);
   
   chartid = ChartID();
   chartwindow = ChartWindowFind();
   
   if (ibars_time_frame == 0)
        ChartIndicatorDelete(chartid, chartwindow, shortname);
   //---
   return (INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
 string filename = StringSubstr(__FILE__, 0, (StringFind(__FILE__, ".", 0)));
  indicator_handle_iCustom = iCustom(_Symbol, _Period, filename);
                
 if (ibars_time_frame == 0)
      ChartIndicatorAdd(chartid, chartwindow, indicator_handle_iCustom);
}

 
Nagisa Unada #:

もっと単純化してもいいかなと思います。

return(rates_total); の後、先に進まないのでその後の動作は確認していません。


ありがとうございます。
Tick の配信を受けている状態でも支障ありませんでした。
問題点をまとめると:
インジケーターにて任意のタイムフレームの情報を取得しようとするとき、Tick の配信を受けている平日は問題ない。ネットワークがオフラインのときは更新(チャートのRefresh 、またはChartSetSymbolPeriod()の実行)が必要。ネットワークがオンラインでも Tick 配信が無い週末ではインジケーターの再起動が必要。インジケーターの再起動はこれらの状態(オンライン、オフライン、Tick配信の有無)全てで有効です。

こんな風にMT5の動作がなっているのは解せませんが、サーバーから取得済みのデータ(履歴データ)はオンラインや Tick 配信の有無に限らず簡単にアクセスできるようにしてほしいものです。
 

その後、iBars() が取得できた状況でも iTime() が機能しない場合があることが発覚しました。

iTime() は OnCalculate()内で return(0) で返せば機能することが分かりましたので、これを盛り込んで code を書きました。これを添付します。このテストコードで MTF(Multi time frame) で取得するのは単純に終値です。

皆さんはMTF にてどのような戦略とするかは豊富な情報を持っておられると推察します。今回のテーマは、MTF の根幹である、Current とは別のタイムフレームの情報を確実に取得することです。

MT5にて、このことが改良されることを切に願っています。

ファイル:
理由: