Estrategia de contratendencia con quoting
Descripción general
StairsCountertrendStrategy es una estrategia de trading de contratendencia que abre posiciones contra una tendencia establecida de una longitud específica, usando un mecanismo de quoting para una entrada más precisa en el mercado.
Componentes principales
public class StairsCountertrendStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleDataType;
private readonly StrategyParam<int> _length;
private QuotingProcessor _quotingProcessor;
private int _bullLength;
private int _bearLength;
}
Parámetros de estrategia
La estrategia permite personalizar los siguientes parámetros:
- CandleDataType - tipo de vela con el que trabajar (predeterminado 1 minuto)
- Length - número de velas consecutivas en una dirección para identificar una tendencia (predeterminado 5)
El parámetro Length está disponible para optimización en el rango de 2 a 10 con un paso de 1.
Inicialización de la estrategia
En el método OnStarted2, se restablecen los contadores, se crea la suscripción a velas y se prepara la visualización:
protected override void OnStarted2(DateTime time)
{
// Restablecer contadores al inicio
_bullLength = 0;
_bearLength = 0;
// Crear suscripción a velas
var subscription = SubscribeCandles(CandleDataType);
subscription
.Bind(ProcessCandle)
.Start();
// Configurar visualización en el gráfico
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawOwnTrades(area);
}
base.OnStarted2(time);
}
Procesamiento de velas
El método ProcessCandle se llama para cada vela completada e implementa la lógica de detección de tendencia y gestión del procesador de quoting:
private void ProcessCandle(ICandleMessage candle)
{
if (candle.State != CandleStates.Finished)
return;
// Identificar vela alcista o bajista
if (candle.OpenPrice < candle.ClosePrice)
{
_bullLength++;
_bearLength = 0;
this.AddInfoLog($"Vela alcista detectada. Racha: {_bullLength}");
}
else if (candle.OpenPrice > candle.ClosePrice)
{
_bullLength = 0;
_bearLength++;
this.AddInfoLog($"Vela bajista detectada. Racha: {_bearLength}");
}
// Detener el procesador existente cuando se requiere cambio de dirección
if (_quotingProcessor != null)
{
// Comprobar si el procesador debe limpiarse (cambio de tendencia o posición)
var shouldClearProcessor = false;
// Hay que vender si hay tendencia alcista y no hay posición corta
if (_bullLength >= Length && Position >= 0)
shouldClearProcessor = true;
// Hay que comprar si hay tendencia bajista y no hay posición larga
else if (_bearLength >= Length && Position <= 0)
shouldClearProcessor = true;
if (shouldClearProcessor)
{
_quotingProcessor?.Dispose();
_quotingProcessor = null;
}
}
// Crear nuevo procesador de quoting cuando sea necesario
if (_quotingProcessor == null && IsFormedAndOnlineAndAllowTrading())
{
if (_bullLength >= Length && Position >= 0)
{
// Tendencia alcista - abrir posición corta
CreateQuotingProcessor(Sides.Sell);
this.AddInfoLog($"Iniciando quoting de venta tras {_bullLength} velas alcistas");
}
else if (_bearLength >= Length && Position <= 0)
{
// Tendencia bajista - abrir posición larga
CreateQuotingProcessor(Sides.Buy);
this.AddInfoLog($"Iniciando quoting de compra tras {_bearLength} velas bajistas");
}
}
}
Crear procesador de quoting
El método CreateQuotingProcessor crea un procesador de quoting con la dirección especificada:
private void CreateQuotingProcessor(Sides side)
{
// Crear comportamiento para quoting de mercado
var behavior = new MarketQuotingBehavior(
0, // Sin desplazamiento de precio
new Unit(0.1m, UnitTypes.Percent), // Usar 0.1% como desviación mínima
MarketPriceTypes.Following // Seguir el precio de mercado
);
// Crear procesador de quoting
_quotingProcessor = new(
behavior,
Security,
Portfolio,
side,
Volume, // Volumen de quoting
Volume, // Volumen máximo de orden
TimeSpan.Zero, // Sin timeout
this, // Strategy implementa ISubscriptionProvider
this, // Strategy implementa IMarketRuleContainer
this, // Strategy implementa ITransactionProvider
this, // Strategy implementa ITimeProvider
this, // Strategy implementa IMarketDataProvider
IsFormedAndOnlineAndAllowTrading, // Comprobar permiso de trading
true, // Usar precios del libro de órdenes
true // Usar precio de la última operación si el libro de órdenes está vacío
)
{
Parent = this
};
// Suscribirse a eventos del procesador
_quotingProcessor.OrderRegistered += order =>
this.AddInfoLog($"Orden {order.TransactionId} registrada al precio {order.Price}");
_quotingProcessor.OrderFailed += fail =>
this.AddInfoLog($"Error de orden: {fail.Error.Message}");
_quotingProcessor.OwnTrade += trade =>
this.AddInfoLog($"Operación ejecutada: {trade.Trade.Volume} a {trade.Trade.Price}");
_quotingProcessor.Finished += isOk =>
{
_quotingProcessor?.Dispose();
_quotingProcessor = null;
};
// Inicializar procesador
_quotingProcessor.Start();
}
Lógica de trading
- Señal de venta:
Lengthvelas alcistas consecutivas (precio de cierre por encima del precio de apertura) cuando no hay posición corta - Señal de compra:
Lengthvelas bajistas consecutivas (precio de cierre por debajo del precio de apertura) cuando no hay posición larga - Se usa un procesador de quoting para la entrada al mercado, siguiendo el precio de mercado
Características
- La estrategia determina automáticamente los instrumentos con los que trabajar mediante el método
GetWorkingSecurities() - La estrategia solo trabaja con velas completadas
- Se usa quoting en lugar de órdenes de mercado para una entrada al mercado más eficiente
- La estrategia aplica un enfoque de contratendencia, abriendo posiciones contra la tendencia establecida
- Se implementa logging detallado de los eventos principales para depuración
- El procesador de quoting se limpia automáticamente cuando cambia la dirección de tendencia o se alcanzan objetivos
- Se admite visualización de velas y operaciones en el gráfico
- Se implementa optimización del parámetro de longitud de secuencia para la configuración de la estrategia