トップ  >  自作してみる >  時系列配列について  >  T4.マルチタイムフレーム分析[MTF]
T4.マルチタイムフレーム分析[MTF]


マルチタイムフレーム分析について

マルチタイムフレーム分析は、ざっくり言うと「異なる時間軸のチャートを見て相場の状況を分析する」事です。
MT4でマルチタイムフレーム分析というと、「異なる時間軸のインジケータを表示する」の方が一般的です。

具体的には
時系列配列

このように、15分足チャートに1時間足チャートの移動平均線を表示する事です。
これはM4.トレンド系インジケータ作成(マルチタイムフレームMA)で既に説明済みです。

が、それでも「さっぱり分からない」や、「マルチタイムフレーム分析のためのローソク足取得」について解説して欲しいという要望があります。
単純に読み飛ばしされているか、単純にそのページだけ読んでその前の基本的な部分については読み飛ばしているだけだと思いますが・・・
「読んだけど分からない」という人を追及すると、「読み飛ばしてそのページだけしか読んでなかった」というギフテッドが多いです。
なのでこのページは本来必要無いのですが、時系列配列の説明ついでにもう一度説明します。
今回はより詳細に説明しますが、どちらにしろ読み飛ばして見たいページしか見てこなかった初心者には理解できないと思います。

何をすれば良いか整理する

時系列配列の説明ページで何度か同じ事を言っていますが、
まず何をすれば良いのか考えて整理する必要があります。

初心者や外注SESは何をすれば良いのか分かっていない状態で突然ソースコードを書こうとします。
ソースコードが書こうとしてチンプンカンプンになるのはMQL4の知識不足以前の問題が多いです。
本人が何をしたら良いのか分かっていないので、ソースコードを書けないのは当然です。

例えば「日足の高値ラインを表示させたい」と思ったとします。
この目的は初心者でもベテランでも同じです。

初心者はや外注SESこの目的だけで突然ソースコードを書こうとします。
ベテランは「この目的を実現する為にはどうすれば良いか?」を考えます。

この違いは分かりますでしょうか?
ベテランは設計してから実際にソースコードを書き始めます。
この設計というプロセスを紙に書いたり、脳内で完結させたりして、自分が何をするかを明確にしてからソースコードを書き始めます。

初心者はまずこの設計という作業をやって下さい。
これをやらない限り何も始まりません。一生他人に聞いて理解できないまま意味も分からず作業をする事になります。
外注SESのように意味も分からずソースコードを適当に修正して致命的な不具合を仕込んだプログラムをテストもせずに納品して発注元企業の社会的信用を失墜させるような自体を招く事になります。
時系列配列

設計する

では実際に、「日足の高値ラインを表示するインジケータ」を設計してみましょう。
この目的を達成する為にどうしたら良いのか考える必要があります。

まずは完成したインジケータはどんな表示になるのかを想像して絵を描いてみましょう。
時系列配列

これはMT4を使って手動でトレンドオブジェクトを配置して、1時間足チャートに「日足の高値ラインはこんな感じで表示させたい」
というイメージが伝わるようにしています。こんなちゃんとしたものじゃなくて、手描きで紙に描いた方が簡単です。

「はぁ?バカにしてるんですか?何をすればいいのかなんてそんな事しなくても分かってるわ!」
と思ってやらない初心者の人は多いでしょう。
実際に目の前に完成品のイメージ図を置くのと、何も置かないのでは設計のし易さが大分変わります。

私は今でもこの作業をまず最初に行います。
何か新しい物を作る時は、まず最初に完成品のイメージ図を手描きで描きます。
そこからどうやって作り上げるかを考えます。


それでは設計作業に入りましょう。
目的はもう明確なのでリストにまとめましょう。
作業内容 詳細
目的 日足の高値ラインを表示するインジケータを作成する

設計(状況判断)


続いて状況判断ですね。
・日足の高値ラインと時間軸を指定しているので、どんな時間軸チャートでも日足のデータを取得する必要があります。
・時系列配列から取得出来るのは、始値・高値・安値・終値・オープン時間・tick出来高。
・時系列配列から値を取得するにはシフト(インデックス)を指定する必要がある。

ここまで大丈夫でしょうか?
もし何を言っているのか分からない人は完全に読み飛ばしてこのページだけを読んでいるので、分かるようになるまで前のページに戻って下さい。

次は最も重要な部分です。
現在表示されているチャートと異なる時間軸の高値を取得するにはどうすれば良いか?
「はぁ?バカにしてるんですか?そんなの当たり前じゃねーか」
と思ってやらない初心者の人は多いでしょう。
でも実際は考える事を放棄して「日足の高値を表示するにはどうすればいいですか?」と聞いてきます。
時系列配列

人間相手ならそのまま言えば良いですが、何度も言うようにコンピュータは1から10まで全て指示しないと何も出来ません。
つまり具体的な指示をする必要があります。

具体的には
・時系列配列データを取得するにはインデックスを指定する必要がある。
・現在表示されているチャートのインデックスに対応した日足のインデックスはどれか?
という事が考えられるかどうかです。

例えば、1時間足の最新のローソク足は、日足のどのローソク足に対応しているのか?
時系列配列

人間なら「2020/11/30 14:00なんだから、2020/11/30の日足が対応する」という事が判断出来ます。
この例は最新のローソク足なので、日足も最新のローソク足が対応する事が分かっているので簡単です。

では次の例ではどうでしょう?
時系列配列

人間相手ならどの日足が対応するか判断出来ます。
ではこれをコンピュータ相手に指示するならどうすれば良いでしょうか?
考えて下さい。

ええ分かります、初心者は思考放棄するのが大好きなので一切考える事無く、
「能書きはいいからさっさと答えを教えろよ」と舌打ちしながらモニタに向かって文句を言っている姿が想像出来ます。
時系列配列

何をどう指示する必要があるのかを日本語で書き出して下さい。
まぁどうせやらないんでしょうけどw

ちょっとここまでの作業をまとめましょう。
作業内容 詳細
目的 日足の高値ラインを表示するインジケータを作成する
状況 ・日足の高値ラインと時間軸を指定しているので、どんな時間軸チャートでも日足のデータを取得する必要がある
・時系列配列から取得出来るのは、始値・高値・安値・終値・オープン時間・tick出来高。
・時系列配列から値を取得するにはシフト(インデックス)を指定する必要がある。
・現在表示されているチャートのインデックスに対応した日足のインデックスはどれか?

設計(分析)

現在の状況を確認して、必要な材料は全て揃っています。
ここからは自分の頭で考えて分析する必要があります。

さて
・現在表示されているチャートのインデックスに対応した日足のインデックスはどれか?
についてですが、コンピュータ相手に指示するには曖昧過ぎてこれをそのままソースコードにする事は不可能です。

もう少し具体的な内容にすると、
・現在チャートのN番目のインデックスは、日足チャートの何番目のインデックスに対応するか?
となります。指示内容が大分明確になりましたよね?

時系列配列

次は、人間相手に指示した際に「人間はどうやって判断するか?」を考えてみましょう。
人間相手に指示した時に「2020/11/30 14:00なんだから、2020/11/30の日足が対応する」と判断しますよね?
つまり指示された人間も対応する日足チャートを選別する時は「日付時間」という情報を使って判断している事が分かります。
人間が考えて判断した方法を使ってコンピュータに指示すれば良いだけです。


もう答えは出ましたよね?
・時間を用いて対応するインデックスを判断する
これを頭で理解出来ていてそれを日本語で説明出来るかです。

何も考えずに答えを聞いた後に「そんなの当たり前じゃねーか!」と思った人は、
答えを聞いてから「そんなの当たり前じゃねーか!俺は最初から分かってたんだぜぇ~」と言う会社の無能上司と同じですw
時系列配列

日本語で説明出来ないと言うことは何も分かっていない証明をしているようなものです。


ここまで分かったら次にやるべき事は、
・どうやって対応する日足のインデックスを取得するか?
です。

これもやり方は色々あります。
単純に現在チャートのN番目の日付時間を基準にして、日足のインデックスを全てチェックして対応する日付時間がヒットしたインデックスを取得する方法が考えられます。
具体的にはforループで日足のオープン時間を総ナメチェックします。

時系列配列

MQL4には指定した日付時間のインデックスを取得するiBarShift()関数が用意されていますので、それを使いましょう。
ただ、この考え方を理解してから使うようにしましょう。
意味も分からずこの関数を使うのは避けて下さい。

日足のインデックスを取得出来たら後はもう分かりますよね?読み飛ばしていなければ分かる筈ですw
取得した日足インデックスを使って、iHigh()関数で日足の高値を取得するだけです。

ちょっとここまでの作業をまとめましょう。
作業内容 詳細
目的 日足の高値ラインを表示するインジケータを作成する
状況 ・日足の高値ラインと時間軸を指定しているので、どんな時間軸チャートでも日足のデータを取得する必要がある
・時系列配列から取得出来るのは、始値・高値・安値・終値・オープン時間・tick出来高。
・時系列配列から値を取得するにはシフト(インデックス)を指定する必要がある。
・現在表示されているチャートのインデックスに対応した日足のインデックスはどれか?
分析 ・現在チャートのN番目のインデックスは、日足チャートの何番目のインデックスに対応するか?
・時間を用いて対応するインデックスを判断する
・現在チャートのN番目の日付時間を基準にして、日足のインデックスを全てチェックして対応する日付時間がヒットしたインデックスを取得する (iBarShift()関数で取得可能)
・取得した日足インデックスを使って、対応する日足の高値を取得する



iBarShift()関数について

もうiBarShift()関数がどんな機能なのかはなんとなく理解出来ていると思いますが、一応サンプルソースと共に説明します。

ソースコード:
//+------------------------------------------------------------------+
//|                               Test_GetTimeSeries_OtherSymbol.mq4 |
//|                                                             yuki |
//|                                      https://yukifx.web.fc2.com/ |
//+------------------------------------------------------------------+
#property copyright "yuki"
#property link      "https://yukifx.web.fc2.com/"
#property version   "1.00"
#property strict // strictは絶対に削除しない事

//+------------------------------------------------------------------+
//| スクリプトプログラムスタート
//+------------------------------------------------------------------+
void OnStart()
{
    int      get_index = -1;            // 取得インデックス
    datetime check_time;                // 現在チャートの時間

    check_time = Time[20];               // 現在チャートのオープン時間を設定
    
    get_index = iBarShift(              // 指定したオープン時間のバーシフト取得
                          Symbol(),     // 通貨ペア
                          PERIOD_D1,    // 時間軸
                          check_time,   // 日時
                          false         // 検索モード(曖昧検索)
                );


    if ( get_index >= 0 ) {              // インデックス取得出来た場合

        datetime get_time;

        get_time = iTime(               // オープン時間を取得
                         Symbol(),      // 通貨ペア
                         PERIOD_D1,     // 時間軸
                         get_index      // シフト
                );

        printf( "チェックする時間 = %s" , TimeToStr( check_time ) );
        printf( "取得インデックス = %d" , get_index );
        printf( "日足の時間       = %s" , TimeToStr( get_time ) );
    }

}


結果:
Test_iBarShift USDJPY,H1: チェックする時間 = 2020.11.30 20:00
Test_iBarShift USDJPY,H1: 取得インデックス = 1
Test_iBarShift USDJPY,H1: 日足の時間       = 2020.11.30 00:00


時系列配列

処理の内容を説明すると、
Time[]で現在チャートのインデックス20のオープン時間を取得し、
そのオープン時間を使ってiBarShift()関数で日足のインデックスを取得。
取得したインデックスを使ってiTime()関数で日足チャートのオープン時間をログ出力しています。

ソースコードに落とし込む

やるべき事が明確になったので、ここでようやくコーディング(ソースコードを書く)作業に入ります。
何度も言いますが、初心者は突然このコーディング作業から始める為、自分が何をすれば良いのかを理解していません。
初心者がソースコードを書けないのはMQL4の知識不足では無く、プログラミングにおける根本的な部分が抜け落ちているからだという理由が理解出来ましたでしょうか?
いわゆる「分からない事が分からない」という状態です。

上の「iBarShift()関数について」で殆どソースコードが出来上がってしまっているので、これを活用してインジケータを作成します。

ソースコード:
//+------------------------------------------------------------------+
//|                                               TestTS_DayHigh.mq4 |
//|                                                             yuki |
//|                                      https://yukifx.web.fc2.com/ |
//+------------------------------------------------------------------+
#property copyright "yuki"
#property link      "https://yukifx.web.fc2.com/"
#property version   "1.00"
#property strict // strictは絶対に削除しない事
#property indicator_chart_window // カスタムインジケータをチャートウインドウに表示する

// インジケータプロパティ設定
#property  indicator_buffers    1               // カスタムインジケータのバッファ数
#property  indicator_color1     clrWhite      // インジケータ1の色
#property  indicator_width1     1               // インジケータ1の太さ


// インジケータ表示用動的配列
double     _IndBuffer1[];                          // インジケータ1表示用動的配列

//+------------------------------------------------------------------+
//| OnInit(初期化)イベント
//+------------------------------------------------------------------+
int OnInit()
{
   SetIndexBuffer( 0, _IndBuffer1 );     // インジケータ1表示用動的配列をインジケータ1にバインドする

   return( INIT_SUCCEEDED );      // 戻り値:初期化成功
}

//+------------------------------------------------------------------+
//| OnCalculate(tick受信)イベント
//| カスタムインジケータ専用のイベント関数
//+------------------------------------------------------------------+
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[],   // Tick出来高
                const long     &volume[],        // Real出来高
                const int      &spread[])        // スプレッド
{

    int end_index = Bars;  // バー数取得

    for( int icount = 0 ; icount < end_index ; icount++ ) {

        int      get_index = -1;            // 取得インデックス
        datetime check_time;                // 現在チャートの時間

        check_time = Time[icount];               // 現在チャートのオープン時間を設定
    
        get_index = iBarShift(              // 指定したオープン時間のバーシフト取得
                              Symbol(),     // 通貨ペア
                              PERIOD_D1,    // 時間軸
                              check_time,   // 日時
                              false         // 検索モード(曖昧検索)
                    );


        if ( get_index >= 0 ) {              // インデックス取得出来た場合

            double get_high;

            get_high = iHigh(               // 高値を取得
                         Symbol(),      // 通貨ペア
                         PERIOD_D1,     // 時間軸
                         get_index      // シフト
                    );

            _IndBuffer1[icount] = get_high;

        }

    }

   return( rates_total ); // 戻り値設定:次回OnCalculate関数が呼ばれた時のprev_calculatedの値に渡される
}


時系列配列

1時間足のチャートに適用して、日足の高値が描画される事を確認しましょう。




スポンサーリンク
検索

↑の検索エンジンが表示されない人は、
↓の古い検索エンジンを使用して下さい。
カスタム検索
MQL4リファレンスツリー
スポンサーリンク


Copyright ©2015 MT4でEA自作しちゃお~ All Rights Reserved.


Top

inserted by FC2 system