Торговые операции в стратегиях
В StockSharp класс Strategy предоставляет различные способы работы с заявками для максимального удобства при реализации торговых стратегий.
Способы выставления заявок
Существует несколько способов выставления заявок в стратегиях StockSharp:
1. Использование высокоуровневых методов
Самый простой способ — использование встроенных методов, которые создают и регистрируют заявку за один вызов:
// Покупка по рыночной цене
BuyMarket(volume);
// Продажа по рыночной цене
SellMarket(volume);
// Покупка по лимитной цене
BuyLimit(price, volume);
// Продажа по лимитной цене
SellLimit(price, volume);
// Закрытие текущей позиции по рыночной цене
ClosePosition();
Эти методы обеспечивают максимальную простоту и читаемость кода. Они автоматически:
- Создают объект заявки с указанными параметрами
- Заполняют необходимые поля (инструмент, портфель и т.д.)
- Регистрируют заявку в торговой системе
2. Использование CreateOrder + RegisterOrder
Более гибкий подход заключается в раздельном создании и регистрации заявок:
// Создаем объект заявки
var order = CreateOrder(Sides.Buy, price, volume);
// Дополнительная настройка заявки
order.Comment = "My special order";
order.TimeInForce = TimeInForce.MatchOrCancel;
// Регистрация заявки
RegisterOrder(order);
Метод CreateOrder создает инициализированный объект заявки, который затем можно дополнительно настроить перед регистрацией.
3. Прямое создание и регистрация заявки
Для максимального контроля можно создать объект заявки напрямую и зарегистрировать его:
// Создаем объект заявки напрямую
var order = new Order
{
Security = Security,
Portfolio = Portfolio,
Side = Sides.Buy,
Type = OrderTypes.Limit,
Price = price,
Volume = volume,
Comment = "Custom order"
};
// Регистрация заявки
RegisterOrder(order);
Подробнее о работе с заявками можно узнать в разделе Заявки.
Обработка событий заявок
После регистрации заявки важно отслеживать её состояние. Для этого в стратегии можно:
1. Использовать обработчики событий
// Подписка на событие изменения заявки
OrderChanged += OnOrderChanged;
// Подписка на событие исполнения заявки
OrderRegisterFailed += OnOrderRegisterFailed;
private void OnOrderChanged(Order order)
{
if (order.State == OrderStates.Done)
{
// Заявка исполнена - выполняем соответствующую логику
}
}
private void OnOrderRegisterFailed(OrderFail fail)
{
// Обработка ошибки регистрации заявки
LogError($"Ошибка регистрации заявки: {fail.Error}");
}
2. Использовать правила для заявок
Более мощный подход — использование правил для заявок:
// Создаем заявку
var order = BuyLimit(price, volume);
// Создаем правило, которое сработает при исполнении заявки
order
.WhenMatched(this)
.Do(() => {
// Действия после исполнения заявки
LogInfo($"Заявка {order.TransactionId} исполнена");
// Например, выставляем стоп-заявку
var stopOrder = SellLimit(price * 0.95, volume);
})
.Apply(this);
// Правило для обработки ошибки регистрации
order
.WhenRegisterFailed(this)
.Do(fail => {
LogError($"Ошибка регистрации заявки: {fail.Error}");
// Возможно, повторная попытка с другими параметрами
})
.Apply(this);
Подробные примеры использования правил с заявками можно найти в разделе Примеры правил на заявки.
Управление позицией
Стратегия также предоставляет методы для управления позицией:
// Получение текущей позиции
decimal currentPosition = Position;
// Закрытие текущей позиции
ClosePosition();
// Защита позиции через стоп-лосс и тейк-профит
StartProtection(
takeProfit: new Unit(50, UnitTypes.Absolute), // тейк-профит
stopLoss: new Unit(20, UnitTypes.Absolute), // стоп-лосс
isStopTrailing: true, // трейлинг стоп
useMarketOrders: true // использовать рыночные заявки
);
Пример использования торговых операций в стратегии
Состояние стратегии перед торговлей
Перед выполнением торговых операций важно убедиться, что стратегия находится в корректном состоянии. StockSharp предоставляет несколько свойств и методов для проверки готовности стратегии:
Свойство IsFormed
Свойство IsFormed указывает, сформированы ли (прогреты) все индикаторы, используемые в стратегии. По умолчанию проверяет, чтобы все индикаторы, добавленные в коллекцию Indicators, были в состоянии IIndicator.IsFormed = true
.
Подробнее о работе с индикаторами в стратегии можно прочитать в разделе Индикаторы в стратегии.
Свойство IsOnline
Свойство IsOnline показывает, находится ли стратегия в режиме реального времени. Оно становится true
только когда стратегия запущена и все её подписки на маркет-данные перешли в состояние SubscriptionStates.Online.
Более подробно о подписках на маркет-данные в стратегиях можно узнать в разделе Подписки на маркет-данные в стратегиях.
Свойство TradingMode
Свойство TradingMode определяет режим торговли для стратегии. Возможные значения:
- StrategyTradingModes.Full - разрешены все торговые операции (режим по умолчанию)
- StrategyTradingModes.Disabled - торговля полностью запрещена
- StrategyTradingModes.CancelOrdersOnly - разрешено только снятие заявок
- StrategyTradingModes.ReducePositionOnly - разрешены только операции по уменьшению позиции
Это свойство можно настроить через параметры стратегии:
public SmaStrategy()
{
_tradingMode = Param(nameof(TradingMode), StrategyTradingModes.Full)
.SetDisplay("Режим торговли", "Разрешенные торговые операции", "Основные настройки");
}
Вспомогательные методы проверки состояния
Для удобной проверки готовности стратегии к торговле, StockSharp предоставляет вспомогательные методы:
IsFormedAndOnline() - проверяет, что стратегия находится в состоянии
IsFormed = true
иIsOnline = true
IsFormedAndOnlineAndAllowTrading(StrategyTradingModes) - проверяет, что стратегия сформирована, находится в онлайн-режиме и имеет необходимые права на торговлю
Метод IsFormedAndOnlineAndAllowTrading
принимает опциональный параметр required
типа StrategyTradingModes:
public bool IsFormedAndOnlineAndAllowTrading(StrategyTradingModes required = StrategyTradingModes.Full)
Этот параметр позволяет указать минимальный уровень прав на торговлю, необходимый для конкретной операции:
StrategyTradingModes.Full (значение по умолчанию) - возвращает
true
, только если стратегия находится в режиме полной торговли (TradingMode = StrategyTradingModes.Full
). Используется для операций, которые могут увеличивать позицию.StrategyTradingModes.ReducePositionOnly - возвращает
true
, если стратегия находится в режиме полной торговли или в режиме только уменьшения позиции. Используется для операций закрытия или частичного закрытия позиции.StrategyTradingModes.CancelOrdersOnly - возвращает
true
при любом активном режиме торговли (кромеDisabled
). Используется для операций отмены заявок.
Это позволяет избирательно разрешать или запрещать различные торговые операции в зависимости от текущего режима торговли:
// Для выставления новой заявки, увеличивающей позицию, требуется полный режим торговли
if (IsFormedAndOnlineAndAllowTrading(StrategyTradingModes.Full))
{
// Можем выставлять любые заявки
RegisterOrder(CreateOrder(Sides.Buy, price, volume));
}
// Для закрытия позиции достаточно режима уменьшения позиции
else if (IsFormedAndOnlineAndAllowTrading(StrategyTradingModes.ReducePositionOnly) && Position != 0)
{
// Можем только закрывать позицию
ClosePosition();
}
// Для снятия активных заявок достаточно режима снятия заявок
else if (IsFormedAndOnlineAndAllowTrading(StrategyTradingModes.CancelOrdersOnly))
{
// Можем только снимать заявки
CancelActiveOrders();
}
Таким образом, данный метод позволяет реализовать безопасный механизм контроля доступа к торговым функциям, при котором более критичные операции (например, открытие новых позиций) требуют более высокого уровня прав, а менее критичные (снятие заявок) выполняются даже при ограниченном режиме торговли.
Хорошей практикой является использование этих методов перед выполнением торговых операций:
private void ProcessCandle(ICandleMessage candle)
{
// Проверка, сформирована ли стратегия и в онлайн-режиме ли она,
// и разрешена ли торговля
if (!IsFormedAndOnlineAndAllowTrading())
return;
// Торговая логика
// ...
}
Ниже приведен пример, демонстрирующий различные способы выставления заявок в стратегии и обработку их исполнения:
protected override void OnStarted(DateTimeOffset time)
{
base.OnStarted(time);
// Подписка на свечи
var subscription = new Subscription(
DataType.TimeFrame(TimeSpan.FromMinutes(5)),
Security);
// Создание правила для обработки свечей
Connector
.WhenCandlesFinished(subscription)
.Do(ProcessCandle)
.Apply(this);
Connector.Subscribe(subscription);
}
private void ProcessCandle(ICandleMessage candle)
{
// Проверка готовности стратегии к торговле
if (!this.IsFormedAndOnlineAndAllowTrading())
return;
// Пример торговой логики на основе цены закрытия
if (candle.ClosePrice > _previousClose * 1.01)
{
// Вариант 1: Использование высокоуровневого метода
var order = BuyLimit(candle.ClosePrice, Volume);
// Создаем правило для обработки исполнения заявки
order
.WhenMatched(this)
.Do(() => {
// При исполнении заявки выставляем стоп-лосс и тейк-профит
StartProtection(
takeProfit: new Unit(50, UnitTypes.Absolute),
stopLoss: new Unit(20, UnitTypes.Absolute)
);
})
.Apply(this);
}
else if (candle.ClosePrice < _previousClose * 0.99)
{
// Вариант 2: Раздельное создание и регистрация
var order = CreateOrder(Sides.Sell, candle.ClosePrice, Volume);
RegisterOrder(order);
// Альтернативный способ обработки через событие
OrderChanged += (o) => {
if (o == order && o.State == OrderStates.Done)
{
// Действия после исполнения
}
};
}
_previousClose = candle.ClosePrice;
}