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

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

スポンサーリンク

【cTrader】1分足を使って上位足の標準偏差・歪度・尖度を求める。

こちらのブログのOne-Passアルゴリズムを使用して、1分足の終値を使用した基本的な統計量を計算するインジケーター(cAlgo版)を作ってみました。

f:id:fxborg:20170226225253p:plain(EURUSD15分足)

  1. ・上段・・・ボリンジャーバンド(平均と ±2.0標準偏差 )
  2. ・下段・・・歪度(青ライン)、尖度(赤ライン)

1分足データに基づいて1時間足の20バー期間の統計情報を表示します。

 【概要】

マルチタイムフレームを使ったインジケータです。例として15分足チャートを表示し、上位足には1時間足を指定したと仮定します。

  • ①15分足が完成したタイミングで、1分足の15本の終値から以下の各値を計算します。
    (データ数、平均、偏差平方和、偏差三乗和、偏差四乗和)
  • ②1時間足の計算バッファに①で求めた結果をマージします。
  • ③1時間足が完成したタイミングで、1時間足の計算バッファーのデータを指定期間分マージします。
  • ④最後に③でマージしたデータから標準偏差、歪度、尖度を求めます。

【プログラム】

主要な部分のみを抜き出してみました。

    public class RunningSkewKurt : Indicator
    {
        ...省略...
        private MarketSeries M1;
        private MarketSeries HTF;
        private DateTime barTime;

        Queue <runningstats> StatsQ;
        private RunningStats htfStats;

        private int prevIndexHtf = -1;
        private int prevIndex = -1;

        protected override void Initialize()
        {
            StatsQ = new Queue<runningstats>();
            //---   
            prevIndex = -1;
            prevIndexHtf = -1;
            barTime = new DateTime(0);
            HTF = MarketData.GetSeries(TF);
            M1 = MarketData.GetSeries(TimeFrame.Minute);
            htfStats = new RunningStats();
        }

        public override void Calculate(int index)
        {
            LVL0[index] = 0;
            if (barTime == M1.OpenTime.LastValue)   return;
            barTime = MarketSeries.OpenTime.LastValue;
            // 1分のバーインデックスを取得する。
            // GetIndexByExactTime(時間) は、時刻からバーインデックスを取得する関数。
            int prev = M1.OpenTime.GetIndexByExactTime(MarketSeries.OpenTime.Last(1));
            int next = M1.OpenTime.GetIndexByExactTime(barTime);
            if (prev == -1 || next == -1)  return;
            // RunningStatsクラスは、平均、偏差平方和、偏差三乗和、偏差四乗和を計算し、
            // 標準偏差、歪度、尖度を計算するクラス。また、計算結果のマージも行える。
            RunningStats tempStats = new RunningStats();
            // 1分足データの統計情報をオンラインで計算する。
            for (int i = prev; i < next; i++)
            {
                tempStats.Push(M1.Close[i]);
            }
            // 上位足の計算結果とマージする。
            htfStats = htfStats + tempStats;
            tempStats = null;

            //上位の時間足の更新と重なったとき
            int newIndexHtf = HTF.OpenTime.GetIndexByTime(barTime);
            if (prevIndexHtf != newIndexHtf)
            {
                // 上位足の計算結果をリングバッファに追加する。
                StatsQ.Enqueue(new RunningStats((long)htfStats.n, htfStats.M1, htfStats.M2, htfStats.M3, htfStats.M4));
                // 指定期間以上バッファがたまったら、
                if (StatsQ.Count > Period)
                {
                    while (StatsQ.Count > Period)
                        StatsQ.Dequeue();
                    // 合計用のRunningStatsクラスを用意。
                    RunningStats totalStats = new RunningStats();
                    // 上位足指定期間分の計算結果をマージする。
                    foreach (RunningStats stats in StatsQ)
                    {
                        totalStats = totalStats + stats;
                    }
                    //上位足指定期間分の統計情報を求める。
                    double ma = totalStats.Mean();  //平均
                    double sd = totalStats.StdDev();//標準偏差
                    double skew = totalStats.Skewness();//歪度
                    double kurt = totalStats.Kurtosis();//尖度
                    totalStats = null;
                    for (int j = prevIndex; j < index; j++)
                    {
                        SKEW[j] = skew;
                        KURT[j] = kurt;
                    }
                }
                prevIndex = index;
                prevIndexHtf = newIndexHtf;
                htfStats.Clear();
            }
        }
    }

 

 最後に

One-Passアルゴリズムを使用して、1分足を使用した標準偏差などの統計情報を表示するインジケーターを作ってみました。このほかに回帰分析もOne-Passアルゴリズムで出来そうなので試してみたいところです。

それから、ブローカー版のcAlgoだと土日は別タイムフレームの価格情報を取得できない仕様みたいです。作業が滞るのでとりあえずパブリックベーター版を使ってやりすごしました。

その他にもいろいろハマりましたが、なんとかcAlgoの扱い方が解ってきました。

こちらからどうぞ
Indicators/RunningBB.cs
Indicators/RunningSkewKurt.cs