Table of Contents

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

В 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 определяет режим торговли для стратегии. Возможные значения:

Это свойство можно настроить через параметры стратегии:

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)

Этот параметр позволяет указать минимальный уровень прав на торговлю, необходимый для конкретной операции:

  1. StrategyTradingModes.Full (значение по умолчанию) - возвращает true, только если стратегия находится в режиме полной торговли (TradingMode = StrategyTradingModes.Full). Используется для операций, которые могут увеличивать позицию.

  2. StrategyTradingModes.ReducePositionOnly - возвращает true, если стратегия находится в режиме полной торговли или в режиме только уменьшения позиции. Используется для операций закрытия или частичного закрытия позиции.

  3. 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;
}

См. также