跳转至

可自定义参数类型

由于 C# 是一种强类型语言,因此在声明 cBot、指标和插件中的变量和类属性时,必须指定数据类型。 相比之下,Python 是动态类型语言,因此变量类型会自动推断。 然而,在使用 cTrader API 开发 cBot 时,为了保持两种语言之间的一致性,保留了相同的概念类型。

cTrader Algo API 不允许所有数据类型用作可自定义参数,因此算法开发者必须仔细理解并导航支持的类型。

注意

Python cBot、指标和插件使用在其 .cs 文件 中声明的可自定义参数。

参数用例和 UI

cTrader 仅支持以下参数类型,其关键用例和相关 UI 元素反映在下表中。

C# Python 用例 UI 元素
int int 订单交易量、柱数、周期数等。 数字输入字段(带步进器)
double float 价格值、订单交易量等。 数字输入字段(带步进器)
string str 自定义消息、仓位标签等。 文本输入字段
bool bool 保护机制、允许交易、允许电子邮件等。 下拉是/否
DataSeries api.DataSeries 市场价格来源等。 下拉列表
TimeFrame api.TimeFrame 选择的时间周期等。 周期选择器
enum Enum 图表绘图对齐、个人风险水平等。 下拉列表
Color Color 图表绘图、技术分析工具的颜色、自定义元素等。 颜色选择器
DateTime DateTime 获取算法时区中的强类型日期和时间 日期和时间选择器
DateOnly DateOnly 获取强类型日期 日期选择器
TimeSpan TimeSpan 获取强类型时间间隔或一天中的时间 时间选择器
Symbol Symbol 获取强类型单一符号 符号选择器
Symbol[] Symbol[] 获取强类型多个符号的数组 多符号选择器
Enum[] Enum[] 获取强类型多个 Enum 类型值的数组 多枚举值选择器
TimeFrame[] TimeFrame[] 获取强类型多个 TimeFrame 值的数组 多周期选择器

警告

如果您使用的是旧版本的 cTrader 或 Algo API,可能无法使用上述某些参数类型。

例如,cTrader UI 将 C# 的 booldoubleint 和 Python 的 boolfloatint 类型反映如下。

Image title

接下来的三个示例展示了 C# 的 DataSeries、自定义 enumstring 和 Python 的 api.DataSeriesEnumstr 数据类型(我们也在本指南中提供了完整代码)。

DataSeries

Enum

String

如下所示,C# 的 Color 和 Python 的 Color 参数类型由颜色选择器表示。

Image title

最后,C# 的 TimeFrame 和 Python 的 api.TimeFrame 数据的 UI 反映了 交易 应用程序中交易图表可用的周期选项。

Image title

cBot 示例

在以下 cBot 中,仓位标签是 C# 的 string 和 Python 的 str 参数。

 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
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 NewcBot2 : Robot
    {
        [Parameter(DefaultValue = "my label")]
        public string PositionLabel { get; set; }

        protected override void OnStart()
        {
            ExecuteMarketOrder(TradeType.Buy, "XAGUSD", 1000, PositionLabel);
        }

        protected override void OnStop()
        {
            var positionToFind = Positions.Find(PositionLabel);
            positionToFind.Close();
        }
    }
}

注意

Python cBot 使用在其 .cs 文件 中声明的可自定义参数。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
import clr

clr.AddReference("cAlgo.API")

from cAlgo.API import *
from robot_wrapper import *


class NewcBot2():
    def on_start(self):
        api.ExecuteMarketOrder(TradeType.Buy, "XAGUSD", 1000, api.PositionLabel)

    def on_stop(self):
        position_to_find = api.Positions.Find(api.PositionLabel)
        if position_to_find is not None:
            position_to_find.Close()

C# 的 DataSeriesintbool 和 Python 的 api.DataSeriesintbool 数据类型在以下算法中进行了示例。

 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
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
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class SamplecBotReferenceSMA : Robot
    {
        [Parameter("Source")]
        public DataSeries Source { get; set; }

        [Parameter("SMA Period", DefaultValue = 14)]
        public int SmaPeriod { get; set; }

        [Parameter("Enable Trade", DefaultValue = true)]
        public bool EnableTrade { get; set; }

        private SimpleMovingAverage sma;

        protected override void OnStart()
        {
            sma = Indicators.SimpleMovingAverage(Source, SmaPeriod);
        }

        protected override void OnTick()
        {
            double currentSMA = sma.Result.LastValue;
            double currentPrice = Symbol.Bid;

            if (EnableTrade)
            {
                if (currentPrice > currentSMA)
                {
                    ExecuteMarketOrder(TradeType.Buy, Symbol, 1000, "Buy Order");
                }
                else if (currentPrice < currentSMA)
                {
                    ExecuteMarketOrder(TradeType.Sell, Symbol, 1000, "Sell Order");
                }
            }

            Print("Current Price: {0}, Current SMA: {1}", currentPrice, currentSMA);
        }
    }
}

注意

Python cBot 使用在其 .cs 文件 中声明的可自定义参数。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import clr

clr.AddReference("cAlgo.API")

from cAlgo.API import *
from robot_wrapper import *


class SamplecBotReferenceSMA():
    def on_start(self):
        self.sma = api.Indicators.SimpleMovingAverage(api.Source, api.SmaPeriod)

    def on_tick(self):
        currentSMA = self.sma.Result.LastValue
        currentPrice = api.Symbol.Bid

        if api.EnableTrade:
            if currentPrice > currentSMA:
                api.ExecuteMarketOrder(TradeType.Buy, api.Symbol, 1000, "Buy Order")
            elif currentPrice < currentSMA:
                api.ExecuteMarketOrder(TradeType.Sell, api.Symbol, 1000, "Sell Order")

        api.Print("Current Price: {0}, Current SMA: {1}".format(currentPrice, currentSMA))

此 cBot 使用 Color 作为参数来定义图表区域中的文本可视化:

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

        protected override void OnBar() 
        {
            Chart.DrawStaticText("static", "cBot running!", VerticalAlignment.Center, HorizontalAlignment.Left, TextColor);
        }
    }
}

在以下示例中,C# 的 double 和 Python 的 float 数据类型用作输入订单交易量的参数。 cBot 在连续三个红色柱后执行买入市价单。

 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
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
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class RedBarsBot : Robot
    {
        [Parameter("Order Volume (Lots)", DefaultValue = 0.1)]
        public double OrderVolume { get; set; }

        private int redBarsCount = 0;

        protected override void OnBar()
        {
            if (IsRedBar())
            {
                redBarsCount++;
                if (redBarsCount == 3)
                {
                    PlaceMarketOrder(TradeType.Buy);
                    redBarsCount = 0;
                }
            }
            else
            {
                redBarsCount = 0;
            }
        }

        private bool IsRedBar()
        {
            var currentBar = MarketSeries.Close.Last(1);
            var previousBar = MarketSeries.Close.Last(2);

            return currentBar < previousBar;
        }

        private void PlaceMarketOrder(TradeType tradeType)
        {
            var symbol = Symbol;
            var volume = Symbol.QuantityToVolume(OrderVolume);

            ExecuteMarketOrder(tradeType, symbol, volume);
        }
    }
}

注意

Python cBot 使用在其 .cs 文件 中声明的可自定义参数。

 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
import clr

clr.AddReference("cAlgo.API")

from cAlgo.API import *
from robot_wrapper import *

class RedBarsBot():
    def __init__(self):
        self.redBarsCount = 0

    def on_bar(self):
        if self.is_red_bar():
            self.redBarsCount += 1
            if self.redBarsCount == 3:
                self.place_market_order(TradeType.Buy)
                self.redBarsCount = 0
        else:
            self.redBarsCount = 0

    def is_red_bar(self):
        currentBar = api.MarketSeries.Close.Last(1)
        previousBar = api.MarketSeries.Close.Last(2)
        return currentBar < previousBar

    def place_market_order(self, tradeType):
        symbol = api.Symbol
        volume = api.Symbol.QuantityToVolume(api.OrderVolume)
        api.ExecuteMarketOrder(tradeType, symbol, volume)

在以下示例中,DateTimeDateOnlyTimeSpan 数据类型用作参数。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
using System;
using cAlgo.API;

namespace cAlgo.Robots;

[Robot(AccessRights = AccessRights.None)]
public class TimeParameters : Robot
{
    [Parameter("DateTime Parameter", MinValue = "1970-01-01T00:00:00", MaxValue = "2025-11-01T00:00:00", DefaultValue = "2025-01-01T10:00:00")]
    public DateTime DateTimeParameter { get; set; }

    [Parameter("DateOnly Parameter", MinValue = "1970-01-01", MaxValue = "2025-11-01", DefaultValue = "2025-01-01")]
    public DateOnly DateOnlyParameter { get; set; }

    [Parameter("TimeSpan Parameter", MinValue = "00:00:00", MaxValue = "23:59:59", DefaultValue = "04:10:20")]
    public TimeSpan TimeSpanParameter { get; set; }

    protected override void OnStart()
    {
        Print($"DateTimeParameter: {DateTimeParameter:o}");
        Print($"DateOnlyParameter: {DateOnlyParameter:o}");
        Print($"TimeSpanParameter: {TimeSpanParameter}");
    }
}

注意

Python cBot 使用在其 .cs 文件 中声明的可自定义参数。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
using System;
using cAlgo.API;

namespace cAlgo.Robots;

[Robot(AccessRights = AccessRights.None)]
public class TimeParameters : Robot
{
    [Parameter("DateTime Parameter", MinValue = "1970-01-01T00:00:00", MaxValue = "2025-11-01T00:00:00", DefaultValue = "2025-01-01T10:00:00")]
    public DateTime DateTimeParameter { get; set; }

    [Parameter("DateOnly Parameter", MinValue = "1970-01-01", MaxValue = "2025-11-01", DefaultValue = "2025-01-01")]
    public DateOnly DateOnlyParameter { get; set; }

    [Parameter("TimeSpan Parameter", MinValue = "00:00:00", MaxValue = "23:59:59", DefaultValue = "04:10:20")]
    public TimeSpan TimeSpanParameter { get; set; }
}
在 Python cBot 中使用参数:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
import clr

clr.AddReference("cAlgo.API")

# Import cAlgo API types
from cAlgo.API import *

# Import trading wrapper functions
from robot_wrapper import *

class TimeParameters():
    def on_start(self):
        print(f"DateTimeParameter: {api.DateTimeParameter}")
        print(f"DateOnlyParameter: {api.DateOnlyParameter}")
        print(f"TimeSpanParameter: {api.TimeSpanParameter}")

注意

DateTime 参数值会自动从用户的平台时区转换为算法时区,无需手动转换。

在以下示例中,Symbol 数据类型用作参数。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
using System;
using cAlgo.API;
using cAlgo.API.Internals;

namespace cAlgo.Robots;

[Robot(AccessRights = AccessRights.None)]
public class SymbolParameterTest : Robot
{
    [Parameter("Symbol Parameter", DefaultValue = "EURUSD")]
    public Symbol SymbolParameter { get; set; }

    protected override void OnStart()
    {
        Print($"Symbol Bid Price is: {SymbolParameter.Bid}");
    }
}

注意

Python cBot 使用在其 .cs 文件 中声明的可自定义参数。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
using System;
using cAlgo.API;
using cAlgo.API.Internals;

namespace cAlgo.Robots;

[Robot(AccessRights = AccessRights.None)]
public class SymbolParameterTest : Robot
{
    [Parameter("Symbol Parameter", DefaultValue = "EURUSD")]
    public Symbol SymbolParameter { get; set; }
}
在 Python cBot 中使用参数:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
import clr

clr.AddReference("cAlgo.API")

# Import cAlgo API types
from cAlgo.API import *

# Import trading wrapper functions
from robot_wrapper import *

class SymbolParameterTest():
    def on_start(self):
        print(f"Symbol Bid Price is: {api.SymbolParameter.Bid}")

在以下示例中,我们使用了多 EnumSymbolTimeFrame 参数类型,它们由 C# 数组类型表示。

 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
using System;
    using cAlgo.API;
using cAlgo.API.Internals;
using System.Linq;

namespace cAlgo.Robots;

[Robot(AccessRights = AccessRights.None)]
public class MultiValueParametersTest : Robot
{
    [Parameter(DefaultValue = "EURUSD,GBPUSD")]
    public Symbol[] SymbolsParameter { get; set; }

    [Parameter(DefaultValue = "Sell")]
    public TradeType[] TradeTypesParameter { get; set; }

    [Parameter(DefaultValue = "Daily,Hour")]
    public TimeFrame[] TimeFramesParameter { get; set; }

    protected override void OnStart()
    {
        Print($"Selected symbols are: {string.Join(", ", SymbolsParameter.Select(symbol => symbol.Name))}");
        Print($"Selected trade types are: {string.Join(", ", TradeTypesParameter.Select(tradeType => tradeType.ToString()))}");
        Print($"Selected time frames are: {string.Join(", ", TimeFramesParameter.Select(timeFrame => timeFrame.ToString()))}");
    }
}

注意

Python cBot 使用在其 .cs 文件 中声明的可自定义参数。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
using System;
using cAlgo.API;
using cAlgo.API.Internals;

namespace cAlgo.Robots;

[Robot(AccessRights = AccessRights.None)]
public class MultiValueParametersTest : Robot
{
    [Parameter(DefaultValue = "EURUSD,GBPUSD")]
    public Symbol[] SymbolsParameter { get; set; }

    [Parameter(DefaultValue = "Sell")]
    public TradeType[] TradeTypesParameter { get; set; }

    [Parameter(DefaultValue = "Daily,Hour")]
    public TimeFrame[] TimeFramesParameter { get; set; }
}
在 Python cBot 中使用参数:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
import clr

clr.AddReference("cAlgo.API")

# Import cAlgo API types
from cAlgo.API import *

# Import trading wrapper functions
from robot_wrapper import *

class MultiValueParametersTest():
    def on_start(self):
        print(f"Selected symbols are: {[symbol.Name for symbol in api.SymbolsParameter]}")
        print(f"Selected trade types are: {[str(tradeType) for tradeType in api.TradeTypesParameter]}")
        print(f"Selected time frames are: {[str(timeFrame) for timeFrame in api.TimeFramesParameter]}")

指标示例

以下指标代码展示了如何使用 TimeFrame 参数:

 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
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(AccessRights = AccessRights.None)]
    public class NewIndicator4 : Indicator
    {
        private Bars _hourlyTimeFrameBars;
        private Bars _targetTimeFrameBars;

        [Parameter("Chosen Time Frame")]
        public TimeFrame TargetTimeFrame { get; set; }

        [Output("Main")]
        public IndicatorDataSeries Result { get; set; }

        protected override void Initialize()
        {
            _hourlyTimeFrameBars = MarketData.GetBars(TimeFrame.Hour);
            _targetTimeFrameBars = MarketData.GetBars(TargetTimeFrame);
        }

        public override void Calculate(int index)
        {
            Result[index] = _hourlyTimeFrameBars.HighPrices[index] - _targetTimeFrameBars.HighPrices[index];
        }
    }
}

有一个有趣的(色盲测试)指标,提供 enum 颜色视觉选项(例如,正常、色盲和灰度),供用户确定图表上绘制的水平线的颜色。

 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
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
{

    public enum ColorVision
    {
        Normal,
        Colorblind,
        Greyscale
    }

    [Indicator(AccessRights = AccessRights.None)]
    public class ColorblindTest : Indicator
    {

        [Parameter("Color Vision", DefaultValue = ColorVision.Normal)]
        public ColorVision ColorVision { get; set; }

        public override void Calculate(int index) {}

        protected override void Initialize()
        {

            Color lineColor = Color.Green;

            switch (ColorVision) 
            {
                case ColorVision.Normal:
                    lineColor = Color.Red;
                    break;
                case ColorVision.Colorblind:
                    lineColor = Color.Yellow;
                    break;
                case ColorVision.Greyscale:
                    lineColor = Color.White;
                    break;

            }

            var trendLine = Chart.DrawHorizontalLine("line", Bars.HighPrices.Maximum(10), lineColor);
        }

    }

}

总结一下,通过为声明的变量和类属性选择正确的数据类型,您将能够创建可以处理甚至非标准任务的 cBot 和指标。

Image title