Estratégia Contra a Tendência com Quoting
Visão Geral
StairsCountertrendStrategy é uma estratégia de negociação contra a tendência que abre posições contra uma tendência estabelecida de um comprimento específico, utilizando um mecanismo de quoting para uma entrada no mercado mais precisa.
Componentes Principais
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 da Estratégia
A estratégia permite personalizar os seguintes parâmetros:
- CandleDataType - tipo de vela com que trabalhar (predefinição 1 minuto)
- Length - número de velas consecutivas numa direção para identificar uma tendência (predefinição 5)
O parâmetro Length está disponível para otimização no intervalo de 2 a 10 com passo de 1.
Inicialização da Estratégia
No método OnStarted2, os contadores são reiniciados, a subscrição de velas é criada e a visualização é preparada:
protected override void OnStarted2(DateTime time)
{
// Reiniciar contadores no início
_bullLength = 0;
_bearLength = 0;
// Criar subscrição de velas
var subscription = SubscribeCandles(CandleDataType);
subscription
.Bind(ProcessCandle)
.Start();
// Configurar visualização no gráfico
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawOwnTrades(area);
}
base.OnStarted2(time);
}
Processamento de Velas
O método ProcessCandle é chamado para cada vela concluída e implementa a lógica de deteção da tendência e gestão do processador de quoting:
private void ProcessCandle(ICandleMessage candle)
{
if (candle.State != CandleStates.Finished)
return;
// Identificar vela bullish ou bearish
if (candle.OpenPrice < candle.ClosePrice)
{
_bullLength++;
_bearLength = 0;
this.AddInfoLog($"Candle de alta detetada. Sequência: {_bullLength}");
}
else if (candle.OpenPrice > candle.ClosePrice)
{
_bullLength = 0;
_bearLength++;
this.AddInfoLog($"Candle de baixa detetada. Sequência: {_bearLength}");
}
// Parar processador existente quando for necessária mudança de direção
if (_quotingProcessor != null)
{
// Verificar se o processador deve ser limpo (mudança de tendência ou posição)
var shouldClearProcessor = false;
// Necessário vender se houver tendência bullish e nenhuma posição curta
if (_bullLength >= Length && Position >= 0)
shouldClearProcessor = true;
// Necessário comprar se houver tendência bearish e nenhuma posição longa
else if (_bearLength >= Length && Position <= 0)
shouldClearProcessor = true;
if (shouldClearProcessor)
{
_quotingProcessor?.Dispose();
_quotingProcessor = null;
}
}
// Criar novo processador de quoting quando necessário
if (_quotingProcessor == null && IsFormedAndOnlineAndAllowTrading())
{
if (_bullLength >= Length && Position >= 0)
{
// Tendência bullish - abrir posição curta
CreateQuotingProcessor(Sides.Sell);
this.AddInfoLog($"A iniciar cotação de venda após {_bullLength} candles de alta");
}
else if (_bearLength >= Length && Position <= 0)
{
// Tendência bearish - abrir posição longa
CreateQuotingProcessor(Sides.Buy);
this.AddInfoLog($"A iniciar cotação de compra após {_bearLength} candles de baixa");
}
}
}
Criar Processador de Quoting
O método CreateQuotingProcessor cria um processador de quoting com a direção especificada:
private void CreateQuotingProcessor(Sides side)
{
// Criar comportamento para quoting de mercado
var behavior = new MarketQuotingBehavior(
0, // Sem desvio de preço
new Unit(0.1m, UnitTypes.Percent), // Usar 0,1% como desvio mínimo
MarketPriceTypes.Following // Seguir preço de mercado
);
// Criar processador de quoting
_quotingProcessor = new(
behavior,
Security,
Portfolio,
side,
Volume, // Volume de quoting
Volume, // Volume máximo da ordem
TimeSpan.Zero, // Sem tempo limite
this, // Strategy implementa ISubscriptionProvider
this, // Strategy implementa IMarketRuleContainer
this, // Strategy implementa ITransactionProvider
this, // Strategy implementa ITimeProvider
this, // Strategy implementa IMarketDataProvider
IsFormedAndOnlineAndAllowTrading, // Verificar permissão de negociação
true, // Usar preços do livro de ordens
true // Usar preço da última transação se o livro de ordens estiver vazio
)
{
Parent = this
};
// Subscrever eventos do processador
_quotingProcessor.OrderRegistered += order =>
this.AddInfoLog($"Ordem {order.TransactionId} registada ao preço {order.Price}");
_quotingProcessor.OrderFailed += fail =>
this.AddInfoLog($"Falha na ordem: {fail.Error.Message}");
_quotingProcessor.OwnTrade += trade =>
this.AddInfoLog($"Negócio executado: {trade.Trade.Volume} ao preço {trade.Trade.Price}");
_quotingProcessor.Finished += isOk =>
{
_quotingProcessor?.Dispose();
_quotingProcessor = null;
};
// Inicializar processador
_quotingProcessor.Start();
}
Lógica de Negociação
- Sinal de venda:
Lengthvelas bullish consecutivas (preço de fecho acima do preço de abertura) quando não existe posição curta - Sinal de compra:
Lengthvelas bearish consecutivas (preço de fecho abaixo do preço de abertura) quando não existe posição longa - O processador de quoting é usado para entrada no mercado, seguindo o preço de mercado
Funcionalidades
- A estratégia determina automaticamente os instrumentos com que trabalhar através do método
GetWorkingSecurities() - A estratégia trabalha apenas com velas concluídas
- O quoting é usado em vez de ordens de mercado para uma entrada no mercado mais eficiente
- A estratégia aplica uma abordagem contra a tendência, abrindo posições contra a tendência estabelecida
- É implementado registo detalhado dos principais eventos para depuração
- O processador de quoting é automaticamente limpo quando a direção da tendência muda ou quando os objetivos são atingidos
- A visualização de velas e transações no gráfico é suportada
- A otimização do parâmetro de comprimento da sequência é implementada para configuração da estratégia