跳转至

如何将手动交易策略自动化

自动化或算法交易相比手动交易具有多项优势:

  • 自动化系统消除了情绪化决策,并以更高的精确度、速度和效率执行交易。
  • 算法能够一致地实施高级交易策略,同时可靠地执行风险管理措施。
  • 算法能够使用历史数据进行策略回测,并同时在多个资产和市场中进行多样化交易。

cTrader Algo API 使交易者能够将复杂的手动策略自动化,从而充分利用算法交易的诸多优势。 在本文及其附带的视频中,您将学习如何将复杂的手动策略自动化,并将一系列操作转化为算法。

识别手动策略模式

为了开发算法,假设我们手动交易锤子形态以进行多头入场,交易吊颈形态以进行空头入场。

锤子形态出现在下跌趋势中,预示着潜在的看涨反转。 锤子形态用于识别买入入场。

吊颈形态出现在上涨趋势中,预示着潜在的看跌反转。 吊颈形态用于识别卖出入场。

开发 cBot 以交易手动策略

在 cTrader Algo 中,让我们创建一个实现上一节所述策略的算法。

点击 cBot 选项卡下的 新建 按钮。 在名称字段中输入 Patterns Strategy,然后点击 创建

OnBarClosed() 方法中,我们实现了策略的逻辑。 我们的入场必须满足以下两个条件:

  • 收盘价与最高价匹配。
  • 蜡烛大小至少是蜡烛实体的五倍。

我们首先定义 VolumeStopLossTakeProfit 参数。

1
2
3
4
5
6
7
8
[Parameter(DefaultValue = 1000)]
public double Volume { get; set; }

[Parameter(DefaultValue = 10)]
public double StopLoss { get; set; }

[Parameter(DefaultValue = 10)]
public double TakeProfit { get; set; }

然后我们编写代码片段,在满足条件时执行买入交易。

1
2
3
4
5
if (Bars.Last(0).Close == Bars.Last(0).High &&
            (Bars.Last(0).Close - Bars.Last(0).Open) < (Bars.Last(0).Close - Bars.Last(0).Low) * 0.2)
{
    ExecuteMarketOrder(TradeType.Buy, SymbolName, Volume, InstanceId, StopLoss, TakeProfit);
}
1
2
3
bar = api.Bars.Last(0)
if bar.Close == bar.High and (bar.Close - bar.Open) < (bar.Close - bar.Low) * 0.2:
    api.ExecuteMarketOrder(TradeType.Buy, api.SymbolName, api.Volume, api.InstanceId, api.StopLoss, api.TakeProfit)

在相反的情况下,以下是我们的卖出入场必须满足的条件:

  • 收盘价与最低价匹配。
  • 蜡烛大小至少是蜡烛实体的五倍。

同样,我们编写代码片段,在满足条件时执行卖出交易。

1
2
3
4
5
if (Bars.Last(0).Close == Bars.Last(0).Low &&
                (Bars.Last(0).Open - Bars.Last(0).Close) < (Bars.Last(0).High - Bars.Last(0).Close) * 0.2)
{
    ExecuteMarketOrder(TradeType.Sell, SymbolName, Volume, InstanceId, StopLoss, TakeProfit);
}
1
2
if bar.Close == bar.Low and (bar.Open - bar.Close) < (bar.High - bar.Close) * 0.2:
    api.ExecuteMarketOrder(TradeType.Sell, api.SymbolName, api.Volume, api.InstanceId, api.StopLoss, api.TakeProfit)

您可以复制以下完整代码:

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

namespace cAlgo.Robots
{
    [Robot(AccessRights = AccessRights.None, AddIndicators = true)]
    public class PatternsStrategy : Robot
    {
        [Parameter(DefaultValue = 1000)]
        public double Volume { get; set; }

        [Parameter(DefaultValue = 10)]
        public double StopLoss { get; set; }

        [Parameter(DefaultValue = 10)]
        public double TakeProfit { get; set; }

        protected override void OnStart()
        {

        }

        protected override void OnBarClosed()
        {
            if (Bars.Last(0).Close == Bars.Last(0).High &&
            (Bars.Last(0).Close - Bars.Last(0).Open) < (Bars.Last(0).Close - Bars.Last(0).Low) * 0.2)
            {
                ExecuteMarketOrder(TradeType.Buy, SymbolName, Volume, InstanceId, StopLoss, TakeProfit);
            }

            if (Bars.Last(0).Close == Bars.Last(0).Low &&
            (Bars.Last(0).Open - Bars.Last(0).Close) < (Bars.Last(0).High - Bars.Last(0).Close) * 0.2)
            {
                ExecuteMarketOrder(TradeType.Sell, SymbolName, Volume, InstanceId, StopLoss, TakeProfit);
            }

        }

        protected override void OnStop()
        {

        }
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
import clr
clr.AddReference("cAlgo.API")
from cAlgo.API import *
from robot_wrapper import *

class PatternsStrategy():
    def on_start(self):
        pass

    def on_bar_closed(self):
        bar = api.Bars.Last(0)

        if bar.Close == bar.High and (bar.Close - bar.Open) < (bar.Close - bar.Low) * 0.2:
            api.ExecuteMarketOrder(TradeType.Buy, api.SymbolName, api.Volume, api.InstanceId, api.StopLoss, api.TakeProfit)

        if bar.Close == bar.Low and (bar.Open - bar.Close) < (bar.High - bar.Close) * 0.2:
            api.ExecuteMarketOrder(TradeType.Sell, api.SymbolName, api.Volume, api.InstanceId, api.StopLoss, api.TakeProfit)

    def on_stop(self):
        pass

要构建 cBot,请按 Ctrl+B 或点击 构建

要回测 cBot,我们首先添加一个实例。 选择 本地 选项,指定您喜欢的参数,然后点击 添加实例 按钮。

然后我们导航到 回测 选项卡,指定回测操作的时间段并开始回测。

回测过程完成后,我们可以检查交易。 您将看到在每个交易入场之前,入场条件均已满足。

随着策略的成功自动化,我们可以使用 cBot 代表我们进行交易。

实施 RSI 反转策略

在我们的第二个示例中,我们希望实施基于相对强弱指数 (RSI) 指标反转的策略。 在该策略中,我们入场时预期 RSI 会反转其方向,并遵循以下规则:

  • 当 RSI 值低于 RSI 买入阈值时,我们入场买入。
  • 当 RSI 值高于 RSI 卖出阈值时,我们入场卖出。

让我们创建一个新的 cBot,输入 RSI Reversal Strategy 作为其名称,然后点击 创建

代码编辑器出现后,将 System.Linq 添加到代码顶部作为引用。

1
using System.Linq;

让我们添加两个参数,以便在运行 cBot 之前修改阈值。

1
2
3
4
5
[Parameter(DefaultValue = 30)]
public int BuyLevel { get; set; }

[Parameter(DefaultValue = 70)]
public int SellLevel { get; set; }

我们声明并初始化我们的相对强弱指标。

1
2
3
4
5
6
private RelativeStrengthIndex _rsi;

protected override void OnStart()
{
    _rsi = Indicators.RelativeStrengthIndex(Bars.ClosePrices, 14);
}
1
2
3
class RSIReversalStrategy():
    def on_start(self):
        self._rsi = api.Indicators.RelativeStrengthIndex(api.Bars.ClosePrices, 14)

然后我们实现定义交易逻辑的条件。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
protected override void OnBarClosed()
{

    if (_rsi.Result.LastValue < BuyLevel)
    {
        if (Positions.Count == 0)
            ExecuteMarketOrder(TradeType.Buy, SymbolName, 1000);
        foreach (var position in Positions.Where(p => p.TradeType == TradeType.Sell))
        {
            position.Close();
        }

    }
    else if (_rsi.Result.LastValue > SellLevel)
    {
        if (Positions.Count == 0)
            ExecuteMarketOrder(TradeType.Sell, SymbolName, 1000);
        foreach (var position in Positions.Where(p => p.TradeType == TradeType.Buy))
        {
            position.Close();
        }
    }

}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
def on_bar_closed(self):
    rsi_value = self._rsi.Result.LastValue

    if rsi_value < api.BuyLevel:
        if api.Positions.Count == 0:
            api.ExecuteMarketOrder(TradeType.Buy, api.SymbolName, 1000)
        for position in api.Positions:
            if position.TradeType == TradeType.Sell:
                position.Close()

    elif rsi_value > api.SellLevel:
        if api.Positions.Count == 0:
            api.ExecuteMarketOrder(TradeType.Sell, api.SymbolName, 1000)
        for position in api.Positions:
            if position.TradeType == TradeType.Buy:
                position.Close()

您可以复制以下完整代码:

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

namespace cAlgo.Robots
{
    [Robot(AccessRights = AccessRights.None, AddIndicators = true)]
    public class RSIReversalStrategy : Robot
    {
        [Parameter(DefaultValue = 30)]
        public int BuyLevel { get; set; }

        [Parameter(DefaultValue = 70)]
        public int SellLevel { get; set; }

        private RelativeStrengthIndex _rsi;

        protected override void OnStart()
        {
            _rsi = Indicators.RelativeStrengthIndex(Bars.ClosePrices, 14);
        }

        protected override void OnBarClosed()
        {

            if (_rsi.Result.LastValue < BuyLevel)
            {
                if (Positions.Count == 0)
                    ExecuteMarketOrder(TradeType.Buy, SymbolName, 1000);
                foreach (var position in Positions.Where(p => p.TradeType == TradeType.Sell))
                {
                    position.Close();
                }

            }
            else if (_rsi.Result.LastValue > SellLevel)
            {
                if (Positions.Count == 0)
                    ExecuteMarketOrder(TradeType.Sell, SymbolName, 1000);
                foreach (var position in Positions.Where(p => p.TradeType == TradeType.Buy))
                {
                    position.Close();
                }
            }

        }

        protected override void OnStop()
        {

        }
    }
}
 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
import clr
clr.AddReference("cAlgo.API")
from cAlgo.API import *
from robot_wrapper import *

class RSIReversalStrategy():
    def on_start(self):
        self._rsi = api.Indicators.RelativeStrengthIndex(api.Bars.ClosePrices, 14)

    def on_bar_closed(self):
        rsi_value = self._rsi.Result.LastValue

        if rsi_value < api.BuyLevel:
            if api.Positions.Count == 0:
                api.ExecuteMarketOrder(TradeType.Buy, api.SymbolName, 1000)
            for position in api.Positions:
                if position.TradeType == TradeType.Sell:
                    position.Close()

        elif rsi_value > api.SellLevel:
            if api.Positions.Count == 0:
                api.ExecuteMarketOrder(TradeType.Sell, api.SymbolName, 1000)
            for position in api.Positions:
                if position.TradeType == TradeType.Buy:
                    position.Close()

    def on_stop(self):
        pass

让我们构建我们的策略,添加一个实例并对其进行回测,就像我们对上一个策略所做的那样。

我们可以再次检查和审查一些交易,以查看在交易入场之前入场条件是否满足。

本文展示了如何识别手动策略并将其转换为自动化策略,从而实现算法交易操作。

Image title