首页
/
策略示例
在 GitHub 上查看
Ultra Absolutely No Lag LWMA 策略
概览
Ultra Absolutely No Lag LWMA 策略 使用 StockSharp 高级 API 重现同名 MetaTrader 专家的信号。指标链对价格进行双重加权移动平均平滑,然后通过一组长度逐步增加的平滑器来统计向上与向下的阶段数量。最后的统计值再次平滑并转换成颜色状态,用于驱动交易逻辑。策略可在进场后自动下达止损和止盈保护单。
指标流程
双 LWMA 过滤 :默认对收盘价执行两次加权移动平均,过滤短期噪声。
阶梯式平滑器 :将过滤后的数据输入到可配置数量的平滑器,每个阶段的周期在 StartLength 基础上增加固定步长,默认使用 Jurik 平滑。
多头/空头计数 :比较每个阶段当前值与上一个值,向上则计入多头,向下则计入空头。
最终平滑 :对多头和空头计数再次平滑,得到最终的指标状态。
策略复刻原始指标的颜色逻辑:强势多头输出代码 7–8,普通多头输出 5–6,强势空头输出 1–2,普通空头输出 3–4,0 表示尚未形成的状态。
交易规则
当较旧的柱子产生多头代码(> 4),而最近柱子切换到空头代码(< 5 且不为 0)时,策略先平掉空头头寸,并可开立新的多头。
当较旧的柱子产生空头代码(< 5 且不为 0),而最近柱子切换到多头代码(> 4)时,策略先平掉多头头寸,并可开立新的空头。
如果设置了 StopLossOffset 或 TakeProfitOffset,每次进场都会注册对应的保护单。
策略始终使用指示周期内最近的两个已完成 K 线,与原始专家在收盘价触发信号的逻辑保持一致。
参数
参数
说明
CandleType
指标计算所使用的K线类型/周期。
BaseLength
双重 LWMA 过滤的周期。
AppliedPriceMode
输入价格类型(收盘价、开盘价、典型价、DeMark 等)。
TrendMethod
阶梯平滑器的均线类型(Jurik、SMA、EMA 等)。
StartLength
阶梯平滑器的初始周期。
StepSize
每个阶梯在上一周期基础上增加的步长。
StepsTotal
阶梯平滑器的阶段数量。
SmoothingMethod
对多空计数进行二次平滑时使用的均线类型。
SmoothingLength
最终平滑的周期。
UpLevelPercent
标记强势多头的百分比阈值。
DownLevelPercent
标记强势空头的百分比阈值。
SignalBar
用于发出信号的柱索引(1 表示前一根已完成的柱)。
AllowBuyOpen / AllowSellOpen
是否允许开立多头/空头仓位。
AllowBuyClose / AllowSellClose
是否允许平掉多头/空头仓位。
StopLossOffset
止损距离(绝对价格,0 表示不下达止损)。
TakeProfitOffset
止盈距离(绝对价格,0 表示不下达止盈)。
使用说明
将 CandleType 设置为期望的指标周期(原版默认使用 4 小时)。
调整 StepsTotal、StartLength 和 StepSize 可以改变指标响应速度;阶段越多越平滑但滞后越大。
将 StopLossOffset 和 TakeProfitOffset 设为 0 可禁用保护单。
某些 MetaTrader 平滑方法在 StockSharp 中没有直接对应项,本策略使用 Jurik 或 EMA 作为替代。
策略只在完成的 K 线上操作,以避免与原始版本出现偏差。
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()