GitHub で見る

UltraAbsolutelyNoLag LWMA戦略

概要

UltraAbsolutelyNoLag LWMA戦略は、StockSharpの高レベルAPIを使用してMetaTraderエキスパート「Ultra Absolutely No Lag LWMA」のシグナルを複製します。インジケータースタックはダブル加重移動平均ラダーを評価し、何段のスムージングが上向きまたは下向きを指しているかを計測します。得られたカウントは再度スムージングされ、トレードロジックを駆動する色分けされた状態を生成します。戦略は各新規ポジションに対してオプションで保護的なストップロスとテイクプロフィット注文を配置します。

インジケーターパイプライン

  1. ダブルLWMAフィルター – 適用価格(デフォルトでは終値)がノイズを除去するために2つの連続した加重移動平均で処理されます。
  2. スムージングラダー – フィルタリングされた系列は設定可能なセットの移動平均を通過します。各ステップは選択されたスムージング方法(デフォルトではJurik)と固定ステップで増加する長さを使用します。
  3. 強気/弱気カウンター – 各ステップは現在の値を前の値と比較します。上昇ステップは強気カウンターに、下降ステップは弱気カウンターに貢献します。
  4. 最終スムージング – 強気と弱気のカウンターは選択した方法で再度スムージングされます。これら2つの値がインジケーターの最終状態を形成します。

戦略は元のインジケーターのカラーロジックを再現します:強い強気状態はコード7〜8を生成し、中程度の強気状態は5〜6、強い弱気状態は1〜2、中程度の弱気状態は3〜4を生成します。ゼロは未定義の状態を示します。

トレードロジック

  • 古いバーが強気コード(> 4)を報告し、最新バーが弱気コード(< 5かつゼロ以外)に切り替わると、戦略はオープンしているショートポジションを閉じて新しいロングポジションを開けます。
  • 古いバーが弱気コード(< 5かつゼロ以外)を報告し、最新バーが強気コード(> 4)に切り替わると、戦略はオープンしているロングポジションを閉じて新しいショートポジションを開けます。
  • 対応するオフセットがゼロより大きい場合、各エントリー後にストップロスとテイクプロフィット注文を自動的に登録できます。

評価はインジケーター時間軸の前2つの完成したバーを使用し、バー終値で動作するMetaTraderエキスパートの動作と一致します。

パラメーター

名前 説明
CandleType インジケーター計算に使用されるキャンドルタイプ/時間軸。
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で無効化)。

使用上の注記

  1. キャンドルタイプを希望するインジケーター時間軸に合わせて設定(MetaTraderバージョンはデフォルトでH4を使用)。
  2. より速いまたは遅い反応が必要な場合はラダーパラメーターを調整。StepsTotalを大きくするとよりスムーズだが遅いインジケーターになります。
  3. 保護注文を無効化するにはStopLossOffsetTakeProfitOffsetをゼロのままにします。
  4. インジケーターマッピングはStockSharpの移動平均を使用します。StockSharpで利用できない方法はJurikまたはEMAスムージングにフォールバックします。
  5. 戦略は元のエキスパートと一致するように完成したキャンドルのみで取引します。
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);
		}
	}
}