A estratégia replica o assessor especialista do MetaTrader Exp_AbsolutelyNoLagLwma aplicando uma dupla média móvel ponderada (LWMA) aos dados de velas. A saída do indicador é codificada por cores: verde (2) para uma inclinação ascendente, cinza (1) para plano, e magenta (0) para uma inclinação descendente. As decisões de trading baseiam-se em transições entre esses estados de cor. A implementação no StockSharp usa a API de alto nível, assina velas de timeframe e envia ordens de mercado de acordo com a direção da tendência detectada.
Lógica de trading
Pipeline do indicador
Selecionar a série de preços desejada definida pelo parâmetro Tipo de preço.
Aplicar uma média móvel ponderada (LWMA) com o Comprimento LWMA configurado.
Suavizar o resultado com um segundo LWMA do mesmo comprimento.
Comparar o valor LWMA suavizado com o valor anterior para classificar a direção da inclinação:
2 (tendência de alta) – o valor atual é maior que o valor anterior.
1 (neutro) – o valor atual é igual ao valor anterior.
0 (tendência de baixa) – o valor atual é menor que o valor anterior.
Avaliação de sinais
Apenas velas completas são processadas. O parâmetro Barra de sinal desloca a avaliação do sinal para velas históricas (1 = vela terminada anterior, 2 = a vela antes dessa, etc.). A estratégia também lembra a cor da barra que precede a vela de sinal selecionada para evitar entradas duplicadas.
Transição altista: a vela de sinal selecionada é cor 2 e a vela anterior não é 2. Isso abre comprados (se habilitado) e fecha vendidos existentes.
Transição baixista: a vela de sinal selecionada é cor 0 e a vela anterior não é 0. Isso abre vendidos (se habilitado) e fecha comprados existentes.
Gestão de posições
As ordens são executadas com ordens de mercado. O volume solicitado é Volume + |Position| quando se inverte a direção para que a posição oposta seja fechada automaticamente.
Os sinais de saída podem ser alternados independentemente das entradas, permitindo comportamento somente de sinal ou somente de saída.
StartProtection() é ativado para engajar a lógica de proteção comum do StockSharp assim que a estratégia começa.
Parâmetros
Comprimento LWMA – comprimento dos dois LWMAs usados para suavização.
Tipo de preço – fonte de preço que alimenta o LWMA (fechamento, abertura, máximo, mínimo, mediano, típico, ponderado, simplificado, quarto, variações de seguimento de tendência, ou preço Demark).
Barra de sinal – número de velas terminadas atrás usadas para avaliação de sinais.
Habilitar entradas compradas – permite abrir posições compradas em transições altistas.
Habilitar entradas vendidas – permite abrir posições vendidas em transições baixistas.
Habilitar saídas compradas – fecha posições compradas quando o indicador se torna baixista.
Habilitar saídas vendidas – fecha posições vendidas quando o indicador se torna altista.
Tipo de vela – timeframe da assinatura de velas usada pelo indicador.
Volume (propriedade de Strategy incorporada) – tamanho de operação para novas entradas.
Notas
O timeframe padrão é 4 horas, correspondendo à configuração do assessor especialista original, mas pode ser ajustado através do parâmetro Tipo de vela.
Nenhuma ordem de take-profit ou stop-loss é colocada automaticamente; os usuários podem combinar a estratégia com os componentes de gerenciamento de risco do StockSharp, se necessário.
A portação em Python é intencionalmente omitida conforme solicitado.
namespace StockSharp.Samples.Strategies;
using System;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;
/// <summary>
/// Absolutely No Lag LWMA strategy (simplified).
/// Uses two EMAs of different periods to detect trend direction changes.
/// </summary>
public class AbsolutelyNoLagLwmaStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _fastPeriod;
private readonly StrategyParam<int> _slowPeriod;
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public int FastPeriod
{
get => _fastPeriod.Value;
set => _fastPeriod.Value = value;
}
public int SlowPeriod
{
get => _slowPeriod.Value;
set => _slowPeriod.Value = value;
}
public AbsolutelyNoLagLwmaStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame())
.SetDisplay("Candle Type", "Source candles", "General");
_fastPeriod = Param(nameof(FastPeriod), 9)
.SetGreaterThanZero()
.SetDisplay("Fast Period", "Fast EMA period", "Indicators");
_slowPeriod = Param(nameof(SlowPeriod), 21)
.SetGreaterThanZero()
.SetDisplay("Slow Period", "Slow EMA period", "Indicators");
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var fastEma = new ExponentialMovingAverage { Length = FastPeriod };
var slowEma = new ExponentialMovingAverage { Length = SlowPeriod };
decimal prevFast = 0, prevSlow = 0;
bool hasPrev = false;
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(fastEma, slowEma, (ICandleMessage candle, decimal fastValue, decimal slowValue) =>
{
if (candle.State != CandleStates.Finished)
return;
if (!hasPrev)
{
prevFast = fastValue;
prevSlow = slowValue;
hasPrev = true;
return;
}
if (!IsFormedAndOnlineAndAllowTrading())
{
prevFast = fastValue;
prevSlow = slowValue;
return;
}
if (prevFast <= prevSlow && fastValue > slowValue && Position <= 0)
{
BuyMarket();
}
else if (prevFast >= prevSlow && fastValue < slowValue && Position >= 0)
{
SellMarket();
}
prevFast = fastValue;
prevSlow = slowValue;
})
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, fastEma);
DrawIndicator(area, slowEma);
DrawOwnTrades(area);
}
}
}