La Estrategia UltraAbsolutelyNoLag LWMA replica las señales del experto MetaTrader Ultra Absolutely No Lag LWMA usando la API de alto nivel de StockSharp. La pila de indicadores evalúa una escalera de media móvil ponderada doble y mide cuántas etapas de suavizado apuntan hacia arriba o hacia abajo. Los conteos resultantes se suavizan nuevamente para generar un estado codificado por colores que impulsa la lógica de trading. La estrategia opcionalmente coloca órdenes protectoras de stop-loss y take-profit para cada nueva posición.
Pipeline del Indicador
Filtro LWMA doble – el precio aplicado (cierre por defecto) es procesado por dos medias móviles ponderadas consecutivas para eliminar el ruido.
Escalera de suavizado – la serie filtrada pasa a través de un conjunto configurable de medias móviles. Cada paso usa el método de suavizado seleccionado (Jurik por defecto) y una longitud que aumenta con un paso fijo.
Contador alcista/bajista – cada paso compara el valor actual con el valor anterior. Los pasos en alza contribuyen al contador alcista, los pasos en baja al contador bajista.
Suavizado final – los contadores alcistas y bajistas se suavizan nuevamente usando el método seleccionado. Estos dos valores forman el estado final del indicador.
La estrategia recrea la lógica de color del indicador original: los estados fuertemente alcistas producen códigos 7–8, los estados moderadamente alcistas 5–6, los estados fuertemente bajistas 1–2 y los estados moderadamente bajistas 3–4. Cero denota un estado indefinido.
Lógica de Trading
Cuando la barra más antigua reportó un código alcista (> 4) y la barra más reciente cambia a un código bajista (< 5 y distinto de cero), la estrategia cierra posiciones cortas abiertas y puede abrir una nueva posición larga.
Cuando la barra más antigua reportó un código bajista (< 5 y distinto de cero) y la barra más reciente cambia a un código alcista (> 4), la estrategia cierra posiciones largas abiertas y puede abrir una nueva posición corta.
Las órdenes de stop-loss y take-profit pueden registrarse automáticamente después de cada entrada cuando los offsets correspondientes son mayores que cero.
La evaluación usa las dos barras completadas anteriores del marco temporal del indicador, coincidiendo con el comportamiento del experto MetaTrader que trabaja en el cierre de barra.
Parámetros
Nombre
Descripción
CandleType
Tipo/marco temporal de vela usado para los cálculos del indicador.
BaseLength
Longitud del pre-filtro LWMA doble.
AppliedPriceMode
Precio aplicado (cierre, apertura, típico, DeMark, etc.) usado como entrada del indicador.
TrendMethod
Método de media móvil para la escalera de suavizado (Jurik, SMA, EMA, etc.).
StartLength
Longitud inicial de la escalera de suavizado.
StepSize
Paso agregado a la longitud de suavizado en cada etapa de la escalera.
StepsTotal
Número de etapas en la escalera de suavizado.
SmoothingMethod
Método usado para suavizar los contadores alcista/bajista.
SmoothingLength
Longitud de la etapa de suavizado final.
UpLevelPercent
Umbral de porcentaje que marca un estado fuertemente alcista.
DownLevelPercent
Umbral de porcentaje que marca un estado fuertemente bajista.
SignalBar
Índice de la barra usada para las señales de trading (1 = barra cerrada anterior).
AllowBuyOpen / AllowSellOpen
Habilitar apertura de posiciones largas/cortas.
AllowBuyClose / AllowSellClose
Habilitar cierre de posiciones largas/cortas existentes.
StopLossOffset
Distancia absoluta entre el precio de entrada y el stop-loss protector (0 deshabilita).
TakeProfitOffset
Distancia absoluta entre el precio de entrada y el take-profit (0 deshabilita).
Notas de Uso
Configurar el tipo de vela para que coincida con el marco temporal del indicador deseado (la versión MetaTrader usa H4 por defecto).
Ajustar los parámetros de la escalera si se necesitan reacciones más rápidas o lentas. Un StepsTotal más grande crea un indicador más suave pero más lento.
Dejar StopLossOffset y TakeProfitOffset en cero para deshabilitar las órdenes protectoras.
El mapeo del indicador usa medias móviles de StockSharp. Los métodos que no están disponibles en StockSharp recurren al suavizado Jurik o EMA.
La estrategia solo opera en velas terminadas para permanecer consistente con el experto 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);
}
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
class ultra_absolutely_no_lag_lwma_strategy(Strategy):
def __init__(self):
super(ultra_absolutely_no_lag_lwma_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(1))) \
.SetDisplay("Candle Type", "Candles", "General")
self._fast_length = self.Param("FastLength", 7) \
.SetDisplay("Fast Length", "Fast EMA period", "Indicators")
self._slow_length = self.Param("SlowLength", 21) \
.SetDisplay("Slow Length", "Slow EMA period", "Indicators")
self._prev_fast = 0.0
self._prev_slow = 0.0
self._has_prev = False
@property
def CandleType(self):
return self._candle_type.Value
@property
def FastLength(self):
return self._fast_length.Value
@property
def SlowLength(self):
return self._slow_length.Value
def OnReseted(self):
super(ultra_absolutely_no_lag_lwma_strategy, self).OnReseted()
self._prev_fast = 0.0
self._prev_slow = 0.0
self._has_prev = False
def OnStarted2(self, time):
super(ultra_absolutely_no_lag_lwma_strategy, self).OnStarted2(time)
self._prev_fast = 0.0
self._prev_slow = 0.0
self._has_prev = False
fast_ema = ExponentialMovingAverage()
fast_ema.Length = self.FastLength
slow_ema = ExponentialMovingAverage()
slow_ema.Length = self.SlowLength
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(fast_ema, slow_ema, self._on_process).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, fast_ema)
self.DrawIndicator(area, slow_ema)
self.DrawOwnTrades(area)
def _on_process(self, candle, fast_value, slow_value):
if candle.State != CandleStates.Finished:
return
fv = float(fast_value)
sv = float(slow_value)
if not self._has_prev:
self._prev_fast = fv
self._prev_slow = sv
self._has_prev = True
return
if self._prev_fast <= self._prev_slow and fv > sv and self.Position <= 0:
self.BuyMarket()
elif self._prev_fast >= self._prev_slow and fv < sv and self.Position >= 0:
self.SellMarket()
self._prev_fast = fv
self._prev_slow = sv
def CreateClone(self):
return ultra_absolutely_no_lag_lwma_strategy()