読者です 読者をやめる 読者になる 読者になる

FXボーグ | テクニカル実験室

テクニカル分析を使った自動売買プログラムの開発に挑戦!

スポンサーリンク

NinjaTrader8で複数の時間足を同時に扱う。

NinjaTrader

NinjaTrader8では複数の時間足を同時に扱うことができるようです。(ヘルプガイドより)
こちらのヘルプガイドを参考に前回のインジケーターをMTF化してみました。

MTF版カスケード・インジケーター。

f:id:fxborg:20160728072418p:plain

5分足チャート(USDJPY)に5分足と15分足のトレンドを表示しています。

 他のタイムフレームを追加する

インジケーターに他の時間足を追加するには「AddDataSeries」で行います。

protected override void OnStateChange()
{
    if (State == State.Configure)
    {
       //15分足を追加する例
       AddDataSeries(BarsPeriodType.Minute, 15);
        //1時間足を追加する例
       AddDataSeries(BarsPeriodType.Minute, 60);
       // 日足を追加する例
        AddDataSeries(BarsPeriodType.Day, 1);
        // 他通貨を追加する例 
        AddDataSeries("EURUSD", BarsPeriodType.Day, 1); 
    }
}

 OnStateChange イベントでState.Configure時に設定します。他通貨なども呼び出せます。

時間足バッファを作成する

 NinjaTraderでは複数の時間足に同期されたバッファを同時に扱うことができます。
「時間足に同期されたバッファ」というのは長いので「時間足バッファ」と呼ぶことにします。  

 // 2つのSeries<T>オブジェクトを定義
private Series<double> primarySeries;
private Series<double> secondarySeries;
private EMA                   ema20;
protected override void OnStateChange()
{
    if (State == State.Configure)
    {
        // 15分足のオブジェクトを追加
        AddDataSeries(BarsPeriodType.Minute, 15);
    }
    else if (State == State.Historical)
    {
       // 通常のSeries<T>オブジェクト
       primarySeries = new Series<double>(this);

       // 15分足と同期されたSeries<T>オブジェクト .
       // コンストラクタにBarsArray[1]を渡している。
       secondarySeries = new Series<double>(BarsArray[1]));

       // 組み込みのインジケーターも時間足ごとに作れます。   
       ema20 = EMA(BarsArray[1], 20);

    }

}

 時間足バッファはState.Historical 時(*1)に作成します。

Series<T>のコンストラクタに 任意の Bars オブジェクトを渡すことで、そのオブジェクトに同期したバッファが作られます。

OnBarUpdateイベントのMTF化

複数の時間足を追加するとOnBarUpdateイベントの発生回数が多くなります。
たとえば1分足と3分足を追加した場合、3分足の更新イベントでは2回イベントが発生します。

また1分足のみ更新された時の3分足バッファの最新値は、最後の更新データになります。

f:id:fxborg:20160728113919p:plain

更新イベントがたくさん発生するのですが、混乱しないように BarsInProgress プロパティで、どの時間足のイベントかを判定できるようになっています。

protected override void OnBarUpdate()
{
    if (BarsInProgress == 0)
    {

       // このCloseは デフォルトタイムフレームの価格データを参照。
        if (Close[0] > Close[1]) 
        {

           // do something...
        }
    } 
    else if (BarsInProgress == 1) 
    {

       // このCloseは BarsArray[1]の価格データを参照。
         if(Close[0] > Close[1])

         {
           // do something...
         }
    } 

}

また複数の時間足の価格データを同時に参照することも可能です。
Closes(sに注目)で他の時間足の終値にアクセスできます。
その他に Closes、Highs、Lows、Medians、Opens、Typicals 等も使えます。

protected override void OnBarUpdate()
{
    // Closes[ 0 ] はデフォルトタイムフレームの価格データ
    if(Closes[0][0] > Closes[0][0])
    {
        //Closes[ 1 ]は BarsArray[1]の価格データ
        if(Closes[1][0] > Closes[1][0])
        {
            // Do Something...
        }
    }
}

 実際のコード

OnStateChange()

f:id:fxborg:20160728140505p:plain

OnBarUpdate()

f:id:fxborg:20160728135128p:plain

上位足でトレンドを判定し、メインの時間足バッファにコピーしています。PlotBrushes[0][0] でヒストグラムの色を変更していますが、これはMTFと関係ありません。

最後に

今回はNinjaTrader8 で作ったインジケーターをMTF化してみました。各タイムフレームの更新イベントをすべて受け取るという仕様なので、ちょっと混乱するかと思いましたが、修正箇所はさほど多くありませんでした。

ソースはこちらからどうぞ

Indicators/CascadeMTF.cs



*1:ここはヒストリカルデータを処理しているときに実行されます。リアルタイムの場合は1度だけ、バックテストの場合では各テスト毎に1回実行されます。