cBotの高度な操作

導入

このガイドは、主にcBotコードサンプルの広範なリストを補完するものとして意図されています。

他のシンボルの取引

新しいインスタンスを作成する際に指定されたシンボルに加えて、複数のシンボルを取引するcBotを開発することができます。

これを可能にするのが、Symbolsで、これは取引アカウントで利用可能なすべてのシンボルのコレクションです。ループを使用してこれを反復するか、特定のシンボルを検索することができます。

複数のシンボルを正しく扱うためには、cBotが次の情報を知っている必要があります。

  • 最小/最大許容ボリューム
  • ボリュームステップ
  • ピップティックサイズ
  • ピップティックの値(アカウント預金通貨での1ピップ/ティックの金額)

このデータは、Symbolオブジェクトから学ぶことができます。以下のコードでは、名前が"GBPUSD"のシンボルを見つけ、その後、そのシンボルに対してマーケットオーダーを作成します。また、注文ボリュームとして最小許容ボリュームを使用します。

 1 2 3 4 5 6 7 8 910111213
  [Robot()]
  public class Sample_cBot : Robot
  {
      protected override void OnStart()
      {
          var symbol = Symbols.GetSymbol("GBPUSD");

          if (symbol is not null)
          {
              ExecuteMarketOrder(TradeType.Sell, symbol.Name, symbol.VolumeInUnitsMin);
          }
      }
  }

ピップをティックに変換する

cBotをコーディングする際、一部の変数値が単位で計算され、他の値がピップで計算されることから生じるバグに遭遇することがよくあります。

以下のSymbolExtensionsクラスでは、ピップをティックに変換する方法を紹介します。また、ピップを絶対価格値に追加する方法も示しています。

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
using System;
using cAlgo.API;
using cAlgo.API.Internals;
namespace Samples
{
    [Robot(AccessRights = AccessRights.None)]
    public class Sample : Robot
    {
        protected override void OnStart()
        {
            var spreadInPips = Symbol.NormalizePips(Symbol.ToPips(Symbol.Spread));

            Print(spreadInPips);

            var spreadInTicks = Math.Round(Symbol.ToTicks(Symbol.Spread));

            Print(spreadInTicks);

            /* Calculating a long position stop loss using the
            absolute price value. */
            var stopLossInPips = 60;

            /* We use 'NormalizePips' to avoid the 'invalid decimal places'
            error in case our stop loss value has too many decimals. */
            var stopLossInPrice = Symbol.Ask - (Symbol.NormalizePips(stopLossInPips) * Symbol.PipSize);

            Print(stopLossInPrice);
        }
    }

    public static class SymbolExtensions
    {
        /// <summary>
        /// Returns a symbol pip value
        /// </summary>
        /// <param name="symbol"></param>
        /// <returns>double</returns>
        public static double GetPip(this Symbol symbol)
        {
            return symbol.TickSize / symbol.PipSize * Math.Pow(10, symbol.Digits);
        }

        /// <summary>
        /// Returns a price value in terms of pips
        /// </summary>
        /// <param name="symbol"></param>
        /// <param name="price">The price level</param>
        /// <returns>double</returns>
        public static double ToPips(this Symbol symbol, double price)
        {
            return price * symbol.GetPip();
        }

        /// <summary>
        /// Returns a price value in terms of ticks
        /// </summary>
        /// <param name="symbol"></param>
        /// <param name="price">The price level</param>
        /// <returns>double</returns>
        public static double ToTicks(this Symbol symbol, double price)
        {
            return price * Math.Pow(10, symbol.Digits);
        }

        /// <summary>
        /// Rounds a price level to the number of symbol digits
        /// </summary>
        /// <param name="symbol">The symbol</param>
        /// <param name="price">The price level</param>
        /// <returns>double</returns>
        public static double Round(this Symbol symbol, double price)
        {
            return Math.Round(price, symbol.Digits);
        }

        /// <summary>
        /// Normalize x Pips amount decimal places to something that can be used as a stop loss or take profit for an order.
        /// For example if symbol is EURUSD and you pass to this method 10.456775 it will return back 10.5
        /// </summary>
        /// <param name="symbol">The symbol</param>
        /// <param name="pips">The amount of Pips</param>
        /// <returns>double</returns>
        public static double NormalizePips(this Symbol symbol, double pips)
        {
            var currentPrice = Convert.ToDecimal(symbol.Bid);

            var pipSize = Convert.ToDecimal(symbol.PipSize);

            var pipsDecimal = Convert.ToDecimal(pips);

            var pipsAddedToCurrentPrice = Math.Round((pipsDecimal * pipSize) + currentPrice, symbol.Digits);

            var tickSize = Convert.ToDecimal(symbol.TickSize);

            var result = (pipsAddedToCurrentPrice - currentPrice) * tickSize / pipSize * Convert.ToDecimal(Math.Pow(10, symbol.Digits));

            return decimal.ToDouble(result);
        }
    }
}

過去の取引データの利用

cBotをコーディングする際、自分のアカウント履歴にアクセスすることができます。これにより、過去の取引を反復処理し、それらのデータを様々な目的に使用することが可能です。

以下のコードスニペットは、過去のすべての取引とその取引データを含む.CSVファイルを作成します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
using System;
using cAlgo.API;
using System.Text;
using System.IO;
namespace Samples
{
    /* We provide the access rights required for
    reading and writing in locally stored files. */
    [Robot(AccessRights = AccessRights.FullAccess)]
    public class Sample : Robot
    {
        protected override void OnStart()
        {
            var stringBuilder = new StringBuilder();

            _ = stringBuilder.AppendLine($"PositionId,TradeType,SymbolName,VolumeInUnits,EntryTime,EntryPrice,ClosingTime,ClosingPrice,NetProfit,Balance");

            // All trades are inside the 'History' collection
            foreach (var trade in History)
            {
                _ = stringBuilder.AppendLine($"{trade.PositionId},{trade.TradeType},{trade.SymbolName},{trade.VolumeInUnits},{trade.EntryTime:o},{trade.EntryPrice},{trade.ClosingTime:o},{trade.ClosingPrice},{trade.NetProfit},{trade.Balance}");
            }

            // We will save the CSV file on our desktop
            var desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);

            var filePath = Path.Combine(desktopPath, $"{Account.Number}_History.csv");

            File.WriteAllText(filePath, stringBuilder.ToString());
        }
    }
}

ロットをユニットに変換する

cTraderのアルゴリズムはデフォルトでボリュームをロットではなくユニットで計算します。しかし、場合によってはロットで作業する方が便利であり、馴染みがあるかもしれません。

ロットをユニットに変換するには、Symbol.QuantityToVolumeUnits()メソッドを使用することができます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
using System;
using cAlgo.API;
using System.Text;
using System.IO;
namespace Samples
{
    [Robot(AccessRights = AccessRights.None)]
    public class Sample : Robot
    {
        protected override void OnStart()
        {
            var lots = 2.5;

            var volumeInUnits = Symbol.QuantityToVolumeInUnits(lots);

            ExecuteMarketOrder(TradeType.Sell, SymbolName, volumeInUnits);
        }
    }
}

また、Symbol.VolumeInUnitsToQuantity()メソッドを使用して、ユニットをロットに変換することもできます。

色の扱い方

cBotは、さまざまな操作を実行する際にカスタムカラーを使用できます(例:トレーディングチャートにテキストを表示する場合)。カスタマイズ可能なパラメータとして色を追加するには、以下のコードをパラメータ宣言に追加します。

1
2
[Parameter("Color", DefaultValue = "#f54242")]
public Color DrawingColor { get; set; }

このようなパラメータのDefaultValueを定義する際に、16進数のカラーコードや色の名前("red"など)を使用できることに注意してください。

色のパラメータがどのように機能するかを示すために、cBotを作成します。開始すると、このcBotは動作しているトレーディングチャートにテキストを書き込みます。このテキストの色はTextColorパラメータを介してカスタマイズ可能です。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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(AccessRights = AccessRights.None)]
    public class SampleColorcBot : Robot
    {
        [Parameter("Text Color", DefaultValue = "red")]
        public Color TextColor { get; set; }

        protected override void OnStart()
        {
            var staticText = Chart.DrawStaticText("static", "Sample text to demonstrate how color works", VerticalAlignment.Center, HorizontalAlignment.Center, TextColor);

        }

    }
}
目次

このページについて