Перейти к содержанию

Торговые операции сиБота

В этом руководстве мы подробно объясняем ключевые торговые операции, которые вы можете выполнять с помощью сиБота, разработанного через Algo API.

Вот некоторые из поддерживаемых операций для сиБотов:

  • Отправка рыночных ордеров.
  • Размещение отложенных ордеров.
  • Изменение отложенных ордеров и открытых позиций.
  • Закрытие позиций и отмена ордеров.
  • Подписка на торговые события (позиции, ордера и связанная активность).

Отправка рыночных ордеров

Рыночный ордер отправляется на торговый сервер при вызове метода ExecuteMarketOrder(). После создания нового сиБота вы можете добавить этот метод с несколькими определенными свойствами рыночного ордера (инструмент, объем, тейк-профит, стоп-лосс и т. д.). Приведенный ниже пример размещает рыночный ордер при запуске сиБота.

 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().

После сборки сиБота и добавления экземпляра вы увидите, что рыночный ордер с указанными параметрами был выполнен при запуске. Вкладки Позиции и Лог на панели Обзора сделок отображают соответствующую позицию и записи в логе.

Positions

Log

Размещение отложенных ордеров

cTrader поддерживает три типа отложенных ордеров, а именно стоп ордера, лимитные ордера и стоп-лимит ордера. Чтобы разместить отложенные ордера при запуске, вы можете заменить рыночный ордер следующими фрагментами кода в предыдущем примере сиБота.

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, появится окно Центра помощи, чтобы помочь вам.

Вы увидите следующие записи на панели Обзора сделок после успешной сборки и запуска сиБота.

Ордера

Log

Изменение отложенных ордеров и открытых позиций

Когда отложенные ордера размещены, они становятся доступными в вашей коллекции 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

После успешного выполнения различных типов ордеров для вашего счета будут открыты позиции. Все открытые позиции доступны в коллекции Positions вашего сиБота. Аналогично изменению отложенных ордеров в предыдущем примере, вы можете изменить открытую позицию. Поскольку рыночные ордера — самый быстрый способ открыть позиции, давайте добавим метод 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

Закрытие позиций и отмена ордеров

Ниже вы можете найти пример сиБота, который закрывает все открытые позиции и отменяет все отложенные ордера в пятницу в 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 позволяет разработчикам алгоритмов подписываться на торговые события и отслеживать торговую активность, независимо от того, были ли они инициированы сиБотом или вручную. Это достигается путем прослушивания событий, доступных в двух коллекциях, продемонстрированных ранее, Positions и PendingOrders.

Для позиций доступны три события:

  • 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")

Независимо от того, кто выполняет события Open, Modified и Closed — вы или сиБот, — алгоритм будет реагировать на них каждый раз с выводом сообщений, как показано в журнале ниже.

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")

При подписке на события, связанные с отложенными ордерами, сиБот будет реагировать как на ручную, так и на программную торговую активность.

Image title

Обзор

В заключение отметим, что cTrader предоставляет разработчикам алгоритмов впечатляющий арсенал торговых операций, которые могут выполняться сиБотами. Умело применяя их, вы можете реализовывать индивидуальные и сложные торговые стратегии.

Image title