見出し画像

cTrader用の米ドルインデックス(DXY)(U.S. Dollar Index)を表示するインジケーター

はじめに

cTrader用の米ドルインデックス(DXY)を探している人向けのノート。

米ドルインデックス(DXY)はドルストの取引で必須となる指標だが、cTrader用の米ドルインデックス(DXY)を表示するインジケーターは恐らくデフォルトでは付属していない。フォーラムを見ても次の画像のようなソースコードのないものしか見つからなかったのではないだろうか?

どちらもローカルファイルへのアクセスを求められた。オープンソースでもなく有名なフリーソフトでもなく販売元もよく分からないようなプログラムにローカルファイルへのアクセスは許可したくない。フォーラムにはソースコードが記載されたインジケータの投稿もあったが作りがいまいちだ。そこで筆者は自作する事にした。


米ドルインデックス(DXY)を表示するインジケータの紹介

上が筆者が書いたインジケータ。インベスティングドットコムと比較して正しい事が確認できる。画像で太く黄色で目立つようにしてあるのがDXY。緑と赤は平均値の先行スパンと遅行スパン。

インベスティングドットコム

米ドルインデックス(DXY)を表示するインジケータのソースコード

一部黒塗り 黒塗り解除は100円
各通貨ペアのBarを取得しDXYを計算する
言葉にすると簡単だがゼロから調べて書くと1時間は余裕でかかる

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using cAlgo.API;
using cAlgo.API.Collections;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;

namespace cAlgo
{
    [Indicator(IsOverlay = false, AutoRescale = true, AccessRights = AccessRights.None)]
    public class InUSDollarIndexDXY : Indicator
    {
    	// 自動で上下を反転させる 反転させる通貨ペアがAutoFlipUpsideDownCurrencyPairsに含まれている場合
        [Parameter("Auto Flip Enable", Group = "Auto Flip Upside Down", DefaultValue = true)]
        public bool AutoFlipUpsideDown { get; set; }

    // 自動で上下を反転させる通貨ペア
        [Parameter("Exclusion Currency Pairs", Group = "Auto Flip Upside Down", DefaultValue = "USDJPY USDCAD USDCHF")]
        public string AutoFlipUpsideDownCurrencyPairs { get; set; }

        // 指定したタイムフレーム(CustomTimeFrame)を使う場合はtrue
        // インスタンスのタイムフレームを使う場合はfalse
        [Parameter("Use Custom TimeFrame", Group = "DXY", DefaultValue = false)]
        public bool UseCustomTimeFrame { get; set; }

        // インスタンスのタイムフレームとは別のタイムフレームを使用する時に使う
        [Parameter("Custom TimeFrame", Group = "DXY", DefaultValue = "Hour")]
        public TimeFrame CustomTimeFrame { get; set; }

        // 通貨ペアの読み込みが多いため全てのバーに対して計算すると時間がかかる
        // 最新のバーから何日以内のバーまで計算するか指定する
        // cBotからこのインジケータを読み込んで利用する場合は1で十分
        [Parameter("DXY Periods(Days)", Group = "DXY", DefaultValue = 5, MinValue = 1)]
        public int DXYPeriodsDays { get; set; }

        // 先行スパンの平均値を求めるバー本数
        [Parameter("Average Fast Periods", Group = "DXY", DefaultValue = 10, MaxValue = 1000, MinValue = 1, Step = 1)]
        public int FastPeriods { get; set; }

        // 遅効スパンの平均値を求めるバー本数
        [Parameter("Average Slow Periods", Group = "DXY", DefaultValue = 20, MaxValue = 1000, MinValue = 1, Step = 1)]
        public int SlowPeriods { get; set; }

        [Output("DXY", LineColor = "Blue")]
        public IndicatorDataSeries DXY { get; set; }

        [Output("Fast", LineColor = "Green")]
        public IndicatorDataSeries Fast { get; set; }

        [Output("Slow", LineColor = "Red")]
        public IndicatorDataSeries Slow { get; set; }

        private Dictionary<string, double> _DXYCurrencyPairs;
        private Dictionary<string, Bars> _CurrencyPairsBars;

        private TimeZoneInfo _est;
        private bool _flipUpsideDown = false;

        /// <summary>
        /// Initialize
        /// </summary>
        protected override void Initialize()
        {
            Print("Info:InUSDollarIndexDXY TimeZone.Id = {0}", TimeZone.Id);
            Print("Info:InUSDollarIndexDXY TimeZone.DisplayName = {0}", TimeZone.DisplayName);
            _est = TimeZoneInfo.FindSystemTimeZoneById(TimeZone.Id);

            TimeFrame timeFrame = (UseCustomTimeFrame) ? CustomTimeFrame : TimeFrame;
            Print("Info:InUSDollarIndexDXY TimeFrame = {0}", timeFrame);

            if (AutoFlipUpsideDown)
            {
                _flipUpsideDown = !AutoFlipUpsideDownCurrencyPairs.Contains(SymbolName);
            }

            _DXYCurrencyPairs = new Dictionary<string, double>{
                {"EURUSD", -0.576},
                {"USDJPY", 0.136},
                {"GBPUSD", -0.119},
                {"USDCAD", 0.091},
                {"USDSEK", 0.042},
                {"USDCHF", 0.036},
            };

            _CurrencyPairsBars = new Dictionary<string, Bars> { };
            Print($"Info:InUSDollarIndexDXY Bars({timeFrame})の読み込み開始");
            foreach (var pair in _DXYCurrencyPairs)
            {
                //Print($"Info:InUSDollarIndexDXY {pair.Key}のBars({timeFrame})の読み込み開始");
                _CurrencyPairsBars.Add(pair.Key, MarketData.GetBars(timeFrame, pair.Key));
                //Print($"Info:InUSDollarIndexDXY {pair.Key}のBars({timeFrame})の読み込み終了");
            }
            Print($"Info:InUSDollarIndexDXY Bars({timeFrame})の読み込み終了");
        }

        /// <summary>
        /// Calculate
        /// </summary>
        public override void Calculate(int index)
        {
            // This code exists to limit the amount of computation.
            if (Bars.OpenTimes[index] < Time.AddDays(-1 * DXYPeriodsDays))
            {
                return;
            }

            double? d = GetDXYByBarIndex(index);
            if (d != null)
            {
                DXY[index] = (double)d;
            }

            //----------------------------------------------------------------

            double sumFast = 0.0;
            bool sumFastError = false;
            for (int i = Math.Max(0, index - FastPeriods + 1); i <= index; i++)
            {
                d = GetDXYByBarIndex(i);
                if (d == null)
                {
                    sumFastError = true;
                    break;
                }
                sumFast += (double)d;
            }
            if (! sumFastError)
            {
                Fast[index] = sumFast / FastPeriods;
            }

            //----------------------------------------------------------------

            double sumSlow = 0.0;
            bool sumSlowError = false;
            for (int i = Math.Max(0, index - SlowPeriods + 1); i <= index; i++)
            {
                d = GetDXYByBarIndex(i);
                if (d == null)
                {
                    sumSlowError = true;
                    break;
                }
                sumSlow += (double)d;
            }
            if (! sumSlowError)
            {
                Slow[index] = sumSlow / SlowPeriods;
            }
        }

        /// <summary>
        /// 引数indexの時のDXYを計算して取得する
        /// </summary>
        /// <returns>引数indexの時のDXY</returns>
        private double? GetDXYByBarIndex(int index)
        {
            // 念のため
            if (index < 0)
            {
                return null;
            }

            DateTime time = Bars.OpenTimes[index];

            // 取得できなかった時に0001/01/01が返ってくるようなので
            if (time.Year == 1)
            {
                Print($"Bars.OpenTimes[{index}]の日時が[0001/01/01 00:00:00]のためスキップ");
                return null;
            }

            double d = 50.14348112;

            foreach (var pair in _DXYCurrencyPairs)
            {
                double? close = ■■■■■■■■■■■■■■■■■■■■■■■■■■■■;
                if (close == null)
                {
                    Print($"Error:InUSDollarIndexDXY ■■■■■■■■■■■■■■■■■■■■");
                    return null;
                }

                d *= Math.Pow((double)close, pair.Value);
            }

            if (_flipUpsideDown)
            {
                d *= -1;
            }

            return d;
        }

        /// <summary>
        /// ■■■■■■■■■■■■■■■■■■■■■■■■
        /// </summary>
        /// <returns>■■■■■■■■■■■■■■■■■■■■■■■■■■■■■</returns>
        private double? >■■■■■■■(■■ ■■), ■■■■ ■■)
        {
            // cBotからインジケータを利用する時に■■■■■■■■■■■■■■■■■■■■■■変換
            DateTime ■■ = ■■■■■■■■■■■■■■■■■■■■■■;

            // Barsから■■■■■■■■取得する。■■■■■■■■■■■■
            int ■■■ = ■■■■■■■■■■■■■■■■■■■■■■;

            if (■■■ == -1)
            {
                Print($"Info:InUSDollarIndexDXY ■■■■■■■■■■■■■■■■■■■■■■■■■");

                // ■■■■■■■■■■■■■■■■■■■■■■■■■■■■
                // ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
                int count = 999;
                while (0 < count && ■■■ == -1)
                {
                    count = ■■■■■■■■■■■■■;
                    ■■■ = ■■■■■■■■■■■■■■■■■■■■■■;
                }

                // When data could not be obtained
                if (■■■ == -1)
                {
                    Print($"Error:InUSDollarIndexDXY ■■■■■■■■■■■■■■■■■■■■■■■■");
                    return null;
                }
                Print($"Info:InUSDollarIndexDXY ■■■■■■■■■■■■■■■■■■■■■■■■");
            }

            return ■■■[■■■].Close;
        }
    }
}

米ドルインデックス(DXY)を利用したcBotのサンプルソースコード

まずインジケータのソースコードをコピペしてインジケータを自作する。次に自作インジケーターを使用可能にするため、上部バーのManage Referencesをクリックし、インジケータにチェックを入れる

米ドルインデックス(DXY)を利用したEURUSDの売買サンプル。先行スパンと遅効スパンがクロスした時にオーダーを出すものにマーチンゲールを加えたもの

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using cAlgo.API;
using cAlgo.API.Collections;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.TokyoStandardTime, AccessRights = AccessRights.None)]
    public class SampleDXYTrading : Robot
    {
        [Parameter("TakeProfit", Group = "Proc", DefaultValue = 15, MinValue = 5, Step = 1)]
        public int TakeProfit { get; set; }

        [Parameter("StopLoss", Group = "Proc", DefaultValue = 25, MinValue = 5, Step = 1)]
        public int StopLoss { get; set; }

        [Parameter("Martingale", Group = "Proc", DefaultValue = false)]
        public bool EnableMartingale { get; set; }

        [Parameter("Use DXY TimeFrame", Group = "DXY", DefaultValue = false)]
        public bool UseDXYTimeFrame { get; set; }

        [Parameter("DXY TimeFrame", Group = "DXY", DefaultValue = "Minutes")]
        public TimeFrame DXYTimeFrame { get; set; }

        [Parameter("Average Fast Periods", Group = "DXY", DefaultValue = 5, MaxValue = 1000, MinValue = 1, Step = 1)]
        public int FastPeriods { get; set; }

        [Parameter("Average Slow Periods", Group = "DXY", DefaultValue = 25, MaxValue = 1000, MinValue = 1, Step = 1)]
        public int SlowPeriods { get; set; }

        private const string _label = "SampleDXYTrading";
        private Symbol _s;
        private InUSDollarIndexDXY _dxy;
        private int _magnification = 1;

        protected override void OnStart()
        {
            Print("SampleDXYTrading TimeZone.DisplayName = {0}", TimeZone.DisplayName);

            _s = Symbols.GetSymbol("EURUSD");
            _dxy = Indicators.GetIndicator<InUSDollarIndexDXY>(UseDXYTimeFrame, DXYTimeFrame, 1, FastPeriods, SlowPeriods);
            if (EnableMartingale)
            {
                Positions.Closed += OnPositionsClosed;
            }
        }

        protected override void OnTick()
        {
            if (_dxy.Fast.Last(1) < _dxy.Slow.Last(1) && _dxy.Fast.Last(0) > _dxy.Slow.Last(0))
            {
                if (Positions.Find(_label, _s.Name) == null)
                {
                    ExecuteMarketOrder(TradeType.Sell, _s.Name, _s.VolumeInUnitsMin * _magnification, _label, StopLoss, TakeProfit);
                }
            }

            if (_dxy.Fast.Last(1) > _dxy.Slow.Last(1) && _dxy.Fast.Last(0) < _dxy.Slow.Last(0))
            {
                if (Positions.Find(_label, _s.Name) == null)
                {
                    ExecuteMarketOrder(TradeType.Buy, _s.Name, _s.VolumeInUnitsMin * _magnification, _label, StopLoss, TakeProfit);
                }
            }
        }

        protected virtual void OnPositionsClosed(PositionClosedEventArgs args)
        {
            var position = args.Position;
            if (_label != position.Label)
            {
                return;
            }

            if (0 < position.NetProfit)
            {
                _magnification = 1;
                return;
            }

            _magnification *= 2;
        }
    }
}

米ドルインデックス(DXY)を表示するインジケータのソースコード完全版

100円です

※筆者が提供するのはインジケーターのソースコードのみです。FXで勝てるという保証は提供していません。このインジケーターを使用したことでトラブルや損失、損害が発生しても、なんら責任を負うものではありません。

ここから先は

8,229字

¥ 100

この記事が気に入ったらチップで応援してみませんか?