跳转至

cBot 交易操作

在本指南中,我们详细解释了您可以使用通过 Algo API 开发的 cBot 执行的关键交易操作。

以下是 cBot 支持的一些操作:

  • 发送市价单。
  • 下达挂单。
  • 修改挂单和未平仓头寸。
  • 平仓和取消订单。
  • 订阅交易事件(头寸、订单和相关活动)。

发送市价单

当调用 ExecuteMarketOrder() 方法时,市价单将被发送到交易服务器。 在创建新的 cBot 后,您可以添加此方法并定义市价单的几个属性(交易品种、交易量、止盈、止损等)。 以下示例在 cBot 启动时下达市价单。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
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 TradeOperations : Robot
    {
        protected override void OnStart()
        {
            ExecuteMarketOrder(TradeType.Buy, SymbolName, 1000, "", 10, 10, "", false);
        }       
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
import clr

clr.AddReference("cAlgo.API")

from cAlgo.API import *
from robot_wrapper import *

class TradeOperations():
    def on_start(self):
        api.ExecuteMarketOrder(TradeType.Buy, api.SymbolName, 1000, "", 10, 10, "", False)

提示

在示例中,故意未定义几个订单参数 ""。 请查看 参考 以获取所有 ExecuteMarketOrder() 参数的签名和顺序。

在构建 cBot 并添加实例后,您将看到在启动时执行了具有指定参数的市价单。 交易看板中的 头寸日志 选项卡显示了相应的头寸和日志条目。

Positions

Log

下达挂单

cTrader 支持三种类型的挂单,即止损单、限价单和止损限价单。 要在启动时下达挂单,您可以在之前的 cBot 示例中用以下代码片段替换市价单。

1
2
3
PlaceStopOrder(TradeType.Buy, SymbolName, 1000, Symbol.Ask + (Symbol.PipSize * 10), "", 10, 10, null, "", false);
PlaceLimitOrder(TradeType.Buy, SymbolName, 1000, Symbol.Ask - (Symbol.PipSize * 10), "", 10, 10, null, "", false);
PlaceStopLimitOrder(TradeType.Buy, SymbolName, 1000, Symbol.Ask + (Symbol.PipSize * 10), 2, "", 10, 10, null, "", false);
1
2
3
api.PlaceStopOrder(TradeType.Buy, api.SymbolName, 1000, api.Symbol.Ask + (api.Symbol.PipSize * 10), "", 10, 10, None, "", False)
api.PlaceLimitOrder(TradeType.Buy, api.SymbolName, 1000, api.Symbol.Ask - (api.Symbol.PipSize * 10), "", 10, 10, None, "", False)
api.PlaceStopLimitOrder(TradeType.Buy, api.SymbolName, 1000, api.Symbol.Ask + (api.Symbol.PipSize * 10), 2, "", 10, 10, None, "", False)

提示

要快速检查方法的参数,请开始键入方法名称和左括号。 您将看到一个带有附加信息的 IntelliSense 弹出窗口。

Image title

提示

如果您在 cTrader Algo 中单击方法/参数并按 F1,代码窗口右侧的帮助面板将显示匹配的搜索结果。 如果文本光标停留在代码窗口之外并按 F1,则会出现 帮助中心 窗口以协助您。

成功构建并运行 cBot 后,您将在 交易看板 面板中看到以下记录。

Orders

Log

修改挂单和持仓

当挂单被放置后,它们会出现在您的 cBot 的 PendingOrders 集合中。 通过这个集合,您可以访问和修改它们。 现有的挂单可以通过调整其止损水平来进行修改,如下所示。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
protected override void OnStart()
{
    PlaceStopOrder(TradeType.Buy, SymbolName, 1000, Symbol.Ask + (Symbol.PipSize * 10), "", 10, 10, null, "", false);
    PlaceLimitOrder(TradeType.Buy, SymbolName, 1000, Symbol.Ask - (Symbol.PipSize * 10), "", 10, 10, null, "", false);
    PlaceStopLimitOrder(TradeType.Buy, SymbolName, 1000, Symbol.Ask + (Symbol.PipSize * 10), 2, "", 10, 10, null, "", false);

    foreach(var order in PendingOrders.Where(p => p.SymbolName == SymbolName))
    {
        order.ModifyStopLossPips(20);
    }
}     
1
2
3
4
5
6
7
8
def on_start(self):
    api.PlaceStopOrder(TradeType.Buy, api.SymbolName, 1000, api.Symbol.Ask + (api.Symbol.PipSize * 10), "", 10, 10, None, "", False)
    api.PlaceLimitOrder(TradeType.Buy, api.SymbolName, 1000, api.Symbol.Ask - (api.Symbol.PipSize * 10), "", 10, 10, None, "", False)
    api.PlaceStopLimitOrder(TradeType.Buy, api.SymbolName, 1000, api.Symbol.Ask + (api.Symbol.PipSize * 10), 2, "", 10, 10, None, "", False)

    for order in api.PendingOrders:
        if order.SymbolName == api.SymbolName:
            order.ModifyStopLossPips(20)

日志 选项卡中的交易观察面板显示,三个挂单在放置后立即被成功修改。

Image title

在不同类型的订单成功执行后,您的账户将会开仓。 所有持仓都可以在您的 cBot 的 Positions 集合中找到。 与前面示例中修改挂单类似,您可以修改持仓。 由于市价单是开仓最快的方式,让我们在本指南的第一个 cBot 中添加带有持仓修改操作的 OnBar() 方法。

1
2
3
4
5
6
7
protected override void OnBar()
{
    foreach(var position in Positions.Where(p => p.SymbolName == SymbolName))
    {
        position.ModifyTakeProfitPips(20);
    }
}
1
2
3
4
def on_bar(self):
    for position in api.Positions:
        if position.SymbolName == api.SymbolName:
            position.ModifyTakeProfitPips(20)

如日志所示,持仓在第一个打开的柱上被修改。

Image title

平仓和取消订单

您可以在下面找到一个 cBot 示例,它在周五 11:00 (UTC) 时调用 OnTick() 方法,平掉所有持仓并取消所有挂单。

 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
namespace cAlgo.Robots
{
    [Robot(AccessRights = AccessRights.None)]
    public class TradeOperations : Robot
    {
        protected override void OnStart()
        {
            ExecuteMarketOrder(TradeType.Buy, SymbolName, 1000, "", 10, 10, "", false);
            PlaceStopOrder(TradeType.Buy, SymbolName, 1000, Symbol.Ask + (Symbol.PipSize * 10), "", 10, 10, null, "", false);
        }  

        protected override void OnTick()
        {
            if(Server.Time.DayOfWeek == DayOfWeek.Friday && Server.Time.Hour >= 11)
            {
                foreach(var position in Positions.Where(p => p.SymbolName == SymbolName))
                {
                    position.Close();    
                }

                foreach(var order in PendingOrders.Where(p => p.SymbolName == SymbolName))
                {
                    order.Cancel();
                }
            }
        }
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
import clr
clr.AddReference("cAlgo.API")
from cAlgo.API import *
from robot_wrapper import *

class TradeOperations():
    def on_start(self):
        api.ExecuteMarketOrder(TradeType.Buy, api.SymbolName, 1000, "", 10, 10, "", False)
        api.PlaceStopOrder(TradeType.Buy, api.SymbolName, 1000, api.Symbol.Ask + (api.Symbol.PipSize * 10), "", 10, 10, None, "", False)

    def on_tick(self):
        # Friday == 5 (Sunday=0)
        if api.Server.Time.DayOfWeek == 5 and api.Server.Time.Hour >= 11:
            for position in api.Positions:
                if position.SymbolName == api.SymbolName:
                    position.Close()
            for order in api.PendingOrders:
                if order.SymbolName == api.SymbolName:
                    order.Cancel()

Image title

订阅交易事件

cTrader 允许算法开发者订阅交易事件并监控交易活动,无论这些活动是由 cBot 还是手动发起的。 这是通过监听前面演示的两个集合 PositionsPendingOrders 中的事件来实现的。

持仓有三个可用的事件:

  • Open
  • Modified
  • Closed

它们分别在您开仓、修改和关闭账户中的持仓时触发。

在下面的代码片段中,这三个事件在 OnStart() 方法中声明,并分配了要调用的方法。 这些将自动为我们创建代码签名。 随后,Print() 语句被添加到每个事件方法中。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
protected override void OnStart()
{
    Positions.Opened += Positions_Opened;
    Positions.Modified += Positions_Modified;
    Positions.Closed += Positions_Closed;                    
}  

private void Positions_Opened(PositionOpenedEventArgs obj)
{
    Print("Position with ID " + obj.Position.Id + " was opened");
}

private void Positions_Modified(PositionModifiedEventArgs obj)
{
    Print("Position with ID " + obj.Position.Id + " was modified");
}

private void Positions_Closed(PositionClosedEventArgs obj)
{
    Print("Position with ID " + obj.Position.Id + " was closed");
}   
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
def on_start(self):
    api.Positions.Opened += self.positions_opened
    api.Positions.Modified += self.positions_modified
    api.Positions.Closed += self.positions_closed

def positions_opened(self, obj):
    api.Print("Position with ID " + str(obj.Position.Id) + " was opened")

def positions_modified(self, obj):
    api.Print("Position with ID " + str(obj.Position.Id) + " was modified")

def positions_closed(self, obj):
    api.Print("Position with ID " + str(obj.Position.Id) + " was closed")

无论是您还是 cBot 执行 OpenModifiedClosed 事件,算法每次都会通过打印消息来响应,如下面的日志所示。

Image title

同样,您可以订阅与挂单相关的事件。 挂单有四个可用的事件:

  • Created
  • Modified
  • Filled
  • Cancelled

这四个事件在 OnStart() 方法中声明,事件处理程序如下所示。

 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
protected override void OnStart()
{
    PendingOrders.Created += PendingOrders_Created;
    PendingOrders.Modified += PendingOrders_Modified;
    PendingOrders.Filled += PendingOrders_Filled;
    PendingOrders.Cancelled += PendingOrders_Cancelled;
}

private void PendingOrders_Created(PendingOrderCreatedEventArgs obj)
{
    Print("Pending order with ID " + obj.PendingOrder.Id + " was created");
}

private void PendingOrders_Modified(PendingOrderModifiedEventArgs obj)
{
    Print("Pending order with ID " + obj.PendingOrder.Id + " was modified");
}

private void PendingOrders_Filled(PendingOrderFilledEventArgs obj)
{
    Print("Pending order with ID " + obj.PendingOrder.Id + " was filled");
}

private void PendingOrders_Cancelled(PendingOrderCancelledEventArgs obj)
{
    Print("Pending order with ID " + obj.PendingOrder.Id + " was cancelled");
}       
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
def on_start(self):
    api.PendingOrders.Created += self.pending_orders_created
    api.PendingOrders.Modified += self.pending_orders_modified
    api.PendingOrders.Filled += self.pending_orders_filled
    api.PendingOrders.Cancelled += self.pending_orders_cancelled

def pending_orders_created(self, obj):
    api.Print("Pending order with ID " + str(obj.PendingOrder.Id) + " was created")

def pending_orders_modified(self, obj):
    api.Print("Pending order with ID " + str(obj.PendingOrder.Id) + " was modified")

def pending_orders_filled(self, obj):
    api.Print("Pending order with ID " + str(obj.PendingOrder.Id) + " was filled")

def pending_orders_cancelled(self, obj):
    api.Print("Pending order with ID " + str(obj.PendingOrder.Id) + " was cancelled")

如果订阅了与挂单相关的事件,cBot 将对手动和程序化的交易活动做出反应。

Image title

摘要

总之,cTrader 为算法开发者提供了丰富的交易操作工具,这些操作可以由 cBot 执行。 通过熟练应用这些工具,您可以追求定制化和复杂的交易策略。

Image title