Ver no GitHub

Estratégia UltraAbsolutelyNoLag LWMA

Visão Geral

A Estratégia UltraAbsolutelyNoLag LWMA replica os sinais do especialista MetaTrader Ultra Absolutely No Lag LWMA usando a API de alto nível do StockSharp. A pilha de indicadores avalia uma escada de média móvel ponderada dupla e mede quantas etapas de suavização apontam para cima ou para baixo. As contagens resultantes são suavizadas novamente para gerar um estado codificado por cores que impulsiona a lógica de trading. A estratégia opcionalmente coloca ordens de proteção de stop-loss e take-profit para cada nova posição.

Pipeline do Indicador

  1. Filtro LWMA duplo – o preço aplicado (fechamento por padrão) é processado por duas médias móveis ponderadas consecutivas para remover ruído.
  2. Escada de suavização – a série filtrada passa por um conjunto configurável de médias móveis. Cada passo usa o método de suavização selecionado (Jurik por padrão) e um comprimento que aumenta com um passo fixo.
  3. Contador alta/baixa – cada passo compara o valor atual com o valor anterior. Passos em alta contribuem para o contador de alta, passos em baixa para o contador de baixa.
  4. Suavização final – os contadores de alta e baixa são suavizados novamente usando o método selecionado. Esses dois valores formam o estado final do indicador.

A estratégia recria a lógica de cores do indicador original: estados fortemente de alta produzem códigos 7–8, estados moderadamente de alta 5–6, estados fortemente de baixa 1–2 e estados moderadamente de baixa 3–4. Zero denota um estado indefinido.

Lógica de Trading

  • Quando a barra mais antiga reportou um código de alta (> 4) e a barra mais recente muda para um código de baixa (< 5 e diferente de zero), a estratégia fecha posições vendidas abertas e pode abrir uma nova posição comprada.
  • Quando a barra mais antiga reportou um código de baixa (< 5 e diferente de zero) e a barra mais recente muda para um código de alta (> 4), a estratégia fecha posições compradas abertas e pode abrir uma nova posição vendida.
  • Ordens de stop-loss e take-profit podem ser registradas automaticamente após cada entrada quando os offsets correspondentes são maiores que zero.

A avaliação usa as duas barras completadas anteriores do período do indicador, correspondendo ao comportamento do especialista MetaTrader que trabalha no fechamento da barra.

Parâmetros

Nome Descrição
CandleType Tipo/período de vela usado para os cálculos do indicador.
BaseLength Comprimento do pré-filtro LWMA duplo.
AppliedPriceMode Preço aplicado (fechamento, abertura, típico, DeMark, etc.) usado como entrada do indicador.
TrendMethod Método de média móvel para a escada de suavização (Jurik, SMA, EMA, etc.).
StartLength Comprimento inicial da escada de suavização.
StepSize Passo adicionado ao comprimento de suavização em cada estágio da escada.
StepsTotal Número de estágios na escada de suavização.
SmoothingMethod Método usado para suavizar os contadores de alta/baixa.
SmoothingLength Comprimento do estágio de suavização final.
UpLevelPercent Limiar de porcentagem que marca um estado fortemente de alta.
DownLevelPercent Limiar de porcentagem que marca um estado fortemente de baixa.
SignalBar Índice da barra usada para sinais de trading (1 = barra fechada anterior).
AllowBuyOpen / AllowSellOpen Habilitar abertura de posições compradas/vendidas.
AllowBuyClose / AllowSellClose Habilitar fechamento de posições compradas/vendidas existentes.
StopLossOffset Distância absoluta entre o preço de entrada e o stop-loss protetor (0 desabilita).
TakeProfitOffset Distância absoluta entre o preço de entrada e o take-profit (0 desabilita).

Notas de Uso

  1. Configurar o tipo de vela para corresponder ao período do indicador desejado (a versão MetaTrader usa H4 por padrão).
  2. Ajustar os parâmetros da escada se reações mais rápidas ou lentas forem necessárias. Um StepsTotal maior cria um indicador mais suave mas mais lento.
  3. Deixar StopLossOffset e TakeProfitOffset em zero para desabilitar ordens protetoras.
  4. O mapeamento do indicador usa médias móveis do StockSharp. Métodos não disponíveis no StockSharp recorrem à suavização Jurik ou EMA.
  5. A estratégia só opera em velas terminadas para permanecer consistente com o especialista original.
using System;
using System.Collections.Generic;

using Ecng.Common;

using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;

namespace StockSharp.Samples.Strategies;

/// <summary>
/// Ultra Absolutely No Lag LWMA strategy (simplified). Uses EMA crossover
/// as a trend-following proxy for the original multi-stage LWMA ladder.
/// </summary>
public class UltraAbsolutelyNoLagLwmaStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _fastLength;
	private readonly StrategyParam<int> _slowLength;

	public DataType CandleType
	{
		get => _candleType.Value;
		set => _candleType.Value = value;
	}

	public int FastLength
	{
		get => _fastLength.Value;
		set => _fastLength.Value = value;
	}

	public int SlowLength
	{
		get => _slowLength.Value;
		set => _slowLength.Value = value;
	}

	public UltraAbsolutelyNoLagLwmaStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame())
			.SetDisplay("Candle Type", "Candles", "General");

		_fastLength = Param(nameof(FastLength), 7)
			.SetGreaterThanZero()
			.SetDisplay("Fast Length", "Fast EMA period", "Indicators");

		_slowLength = Param(nameof(SlowLength), 21)
			.SetGreaterThanZero()
			.SetDisplay("Slow Length", "Slow EMA period", "Indicators");
	}

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);

		var fastEma = new ExponentialMovingAverage { Length = FastLength };
		var slowEma = new ExponentialMovingAverage { Length = SlowLength };

		decimal prevFast = 0, prevSlow = 0;
		var 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);
		}
	}
}