The Ultra Absolutely No Lag LWMA Strategy replicates the signals of the Ultra Absolutely No Lag LWMA MetaTrader expert using the StockSharp high-level API. The indicator stack evaluates a double weighted moving average ladder and measures how many smoothing stages point upward or downward. The resulting counts are smoothed again to generate a color-coded state that drives the trading logic. The strategy optionally places protective stop-loss and take-profit orders for every new position.
Indicator Pipeline
Double LWMA filter – the applied price (close by default) is processed by two consecutive weighted moving averages to remove noise.
Smoothing ladder – the filtered series passes through a configurable set of moving averages. Each step uses the selected smoothing method (Jurik by default) and a length that increases by a fixed step.
Bull/Bear counter – every step compares the current value with the previous value. Rising steps contribute to the bullish counter, falling steps to the bearish counter.
Final smoothing – the bullish and bearish counters are smoothed again using the selected method. These two values form the final state of the indicator.
The strategy re-creates the color logic of the original indicator: strong bullish states produce codes 7–8, neutral bullish states 5–6, strong bearish states 1–2 and neutral bearish states 3–4. Zero denotes an undefined state.
Trading Logic
When the older bar reported a bullish code (> 4) and the most recent bar switches to a bearish code (< 5 and non-zero), the strategy closes open short positions and can open a new long position.
When the older bar reported a bearish code (< 5 and non-zero) and the most recent bar switches to a bullish code (> 4), the strategy closes open long positions and can open a new short position.
Stop-loss and take-profit orders can be registered automatically after each entry when the corresponding offsets are greater than zero.
The evaluation uses the previous two completed bars from the indicator time frame, matching the behaviour of the MetaTrader expert that works on bar close.
Parameters
Name
Description
CandleType
Candle type/time frame used for the indicator calculations.
BaseLength
Length of the double LWMA pre-filter.
AppliedPriceMode
Applied price (close, open, typical, DeMark, etc.) used as indicator input.
TrendMethod
Moving average method for the smoothing ladder (Jurik, SMA, EMA, etc.).
StartLength
Initial length of the smoothing ladder.
StepSize
Step added to the smoothing length on each ladder stage.
StepsTotal
Number of stages in the smoothing ladder.
SmoothingMethod
Method used to smooth the bull/bear counters.
SmoothingLength
Length of the final smoothing stage.
UpLevelPercent
Percentage threshold that marks a strong bullish state.
DownLevelPercent
Percentage threshold that marks a strong bearish state.
SignalBar
Index of the bar used for trading signals (1 = previous closed bar).
AllowBuyOpen / AllowSellOpen
Enable opening long/short positions.
AllowBuyClose / AllowSellClose
Enable closing existing long/short positions.
StopLossOffset
Absolute distance between entry price and the protective stop-loss (0 disables).
TakeProfitOffset
Absolute distance between entry price and the take-profit (0 disables).
Usage Notes
Configure the candle type to match the desired indicator time frame (the MetaTrader version uses H4 by default).
Adjust ladder parameters if you need faster or slower reactions. A larger StepsTotal creates a smoother but slower indicator.
Leave StopLossOffset and TakeProfitOffset at zero to disable protective orders.
The indicator mapping uses StockSharp moving averages. Methods that are not available in StockSharp fall back to Jurik or EMA smoothing.
The strategy only trades on finished candles to remain consistent with the original expert.
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()