Контртрендовая стратегия с котированием
Обзор
StairsCountertrendStrategy
- это контртрендовая торговая стратегия, которая открывает позиции против установившегося тренда определенной длины, используя механизм котирования для более точного входа в рынок.
Основные компоненты
public class StairsCountertrendStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleDataType;
private readonly StrategyParam<int> _length;
private QuotingProcessor _quotingProcessor;
private int _bullLength;
private int _bearLength;
}
Параметры стратегии
Стратегия позволяет настраивать следующие параметры:
- CandleDataType - тип свечей для работы (по умолчанию 1-минутные)
- Length - количество последовательных свечей одного направления для идентификации тренда (по умолчанию 5)
Параметр Length доступен для оптимизации в диапазоне от 2 до 10 с шагом 1.
Инициализация стратегии
В методе OnStarted обнуляются счетчики, создается подписка на свечи и готовится визуализация:
protected override void OnStarted(DateTimeOffset time)
{
// Сброс счетчиков на старте
_bullLength = 0;
_bearLength = 0;
// Создание подписки на свечи
var subscription = SubscribeCandles(CandleDataType);
subscription
.Bind(ProcessCandle)
.Start();
// Настройка визуализации на графике
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawOwnTrades(area);
}
base.OnStarted(time);
}
Обработка свечей
Метод ProcessCandle
вызывается для каждой завершенной свечи и реализует логику определения тренда и управления процессором котирования:
private void ProcessCandle(ICandleMessage candle)
{
if (candle.State != CandleStates.Finished)
return;
// Идентификация бычьей или медвежьей свечи
if (candle.OpenPrice < candle.ClosePrice)
{
_bullLength++;
_bearLength = 0;
this.AddInfoLog($"Bullish candle detected. Streak: {_bullLength}");
}
else if (candle.OpenPrice > candle.ClosePrice)
{
_bullLength = 0;
_bearLength++;
this.AddInfoLog($"Bearish candle detected. Streak: {_bearLength}");
}
// Остановка существующего процессора при необходимости смены направления
if (_quotingProcessor != null)
{
// Проверка необходимости очистки процессора (изменение тренда или позиции)
var shouldClearProcessor = false;
// Нужно продавать, если бычий тренд и нет короткой позиции
if (_bullLength >= Length && Position >= 0)
shouldClearProcessor = true;
// Нужно покупать, если медвежий тренд и нет длинной позиции
else if (_bearLength >= Length && Position <= 0)
shouldClearProcessor = true;
if (shouldClearProcessor)
{
_quotingProcessor?.Dispose();
_quotingProcessor = null;
}
}
// Создание нового процессора котирования при необходимости
if (_quotingProcessor == null && IsFormedAndOnlineAndAllowTrading())
{
if (_bullLength >= Length && Position >= 0)
{
// Бычий тренд - открываем короткую позицию
CreateQuotingProcessor(Sides.Sell);
this.AddInfoLog($"Starting SELL quoting after {_bullLength} bullish candles");
}
else if (_bearLength >= Length && Position <= 0)
{
// Медвежий тренд - открываем длинную позицию
CreateQuotingProcessor(Sides.Buy);
this.AddInfoLog($"Starting BUY quoting after {_bearLength} bearish candles");
}
}
}
Создание процессора котирования
Метод CreateQuotingProcessor
создает процессор котирования с указанным направлением:
private void CreateQuotingProcessor(Sides side)
{
// Создание поведения для рыночного котирования
var behavior = new MarketQuotingBehavior(
0, // Нет смещения цены
new Unit(0.1m, UnitTypes.Percent), // Используем 0.1% как минимальное отклонение
MarketPriceTypes.Following // Следование за рыночной ценой
);
// Создание процессора котирования
_quotingProcessor = new(
behavior,
Security,
Portfolio,
side,
Volume, // Объем котирования
Volume, // Максимальный объем заявки
TimeSpan.Zero, // Нет таймаута
this, // Стратегия реализует ISubscriptionProvider
this, // Стратегия реализует IMarketRuleContainer
this, // Стратегия реализует ITransactionProvider
this, // Стратегия реализует ITimeProvider
this, // Стратегия реализует IMarketDataProvider
IsFormedAndOnlineAndAllowTrading, // Проверка разрешения торговли
true, // Использовать цены стакана
true // Использовать цену последней сделки, если стакан пуст
)
{
Parent = this
};
// Подписка на события процессора
_quotingProcessor.OrderRegistered += order =>
this.AddInfoLog($"Order {order.TransactionId} registered at price {order.Price}");
_quotingProcessor.OrderFailed += fail =>
this.AddInfoLog($"Order failed: {fail.Error.Message}");
_quotingProcessor.OwnTrade += trade =>
this.AddInfoLog($"Trade executed: {trade.Trade.Volume} at {trade.Trade.Price}");
_quotingProcessor.Finished += isOk =>
{
_quotingProcessor?.Dispose();
_quotingProcessor = null;
};
// Инициализация процессора
_quotingProcessor.Start();
}
Логика торговли
- Сигнал на продажу:
Length
последовательных бычьих свечей (цена закрытия выше цены открытия) при отсутствии короткой позиции - Сигнал на покупку:
Length
последовательных медвежьих свечей (цена закрытия ниже цены открытия) при отсутствии длинной позиции - Для входа в рынок используется процессор котирования, который следует за рыночной ценой
Особенности
- Стратегия автоматически определяет инструменты для работы через метод
GetWorkingSecurities()
- Стратегия работает только с завершенными свечами
- Вместо рыночных ордеров используется котирование для более эффективного входа в рынок
- Применяется контртрендовый подход, открывая позиции против установившегося тренда
- Реализовано логирование основных событий для отладки
- Процессор котирования автоматически очищается при смене направления тренда или при достижении целей
- Поддерживается визуализация свечей и сделок на графике
- Реализована оптимизация параметра длины последовательности для настройки стратегии