GitHub で見る

ColorXPWMA Digit マルチ時間軸戦略

概要

この戦略は、MetaTrader 5のエキスパートアドバイザー Exp_ColorXPWMA_Digit_NN3_MMRec をStockSharpの高レベルAPIに変換します。元のロボットは、ColorXPWMA移動平均のデジタル着色を分析することで異なる時間軸で取引する3つの独立したモジュールを運営します。StockSharpポートは同じ動作を維持します:各モジュールは独自のローソク足シリーズを監視し、インジケーターが色を変えるとポジションをクローズし、オプションで検出された方向に新しいトレードを開きます。

デフォルト設定はMT5テンプレートに従います:

モジュール 時間軸 ストップロス(ポイント) テイクプロフィット(ポイント)
A 8時間 3000 10000
B 4時間 2000 6000
C 1時間 1000 3000

各モジュールは専用のブールパラメーターを通じてロングおよびショートのエントリーまたはエグジットで有効または無効にできます。実装はモジュールごとに個別のポジション追跡を維持するため、同時ロングとショートのトレードが他の時間軸のボリューム計算に干渉することなく共存できます。

ColorXPWMA Digit インジケーター

ColorXPWMA DigitインジケーターはMT5のカスタムインジケーターをエミュレートします。完成した各ローソク足についてアルゴリズムは:

  1. 選択した適用価格の冪乗加重平均を構築します(PeriodPower)。
  2. 選択した移動平均で値を平滑化します(SmoothMethodsSmoothLength)。
  3. 結果を設定された小数点以下の桁数に丸めます(Digit)。
  4. カラーコードを割り当てます:平滑化値が増加すると 2、減少すると 0、それ以外の場合は前の色を再利用します。

SignalBar はどの履歴バーを検査するかを制御します。値 0 は最新の閉じたローソク足を使用し、値 1 は前のローソク足を使用します。監視されたバーが前のバーで異なった後に色 2 に変わると買い機会が現れます。色が前のバーで異なった後に 0 になると売り機会が生成されます。

平滑化手法は次のようにStockSharpインジケーターにマッピングされます:

  • Sma, Ema, Smma, Lwma, Jjma → 対応するStockSharpの移動平均。
  • T3 → 内部Tillson T3実装。
  • Vidya → Chandeモメンタムオシレーターによって駆動される内部VIDYA実装。
  • Ama → Kaufman適応移動平均。
  • サポートされていないオプション(JurXParabolic)はエキゾチックなスムーザーが利用できない場合の元のテンプレートの動作に一致する単純移動平均にフォールバックします。

トレード管理と資金管理

各モジュールについて戦略は2つの独立した仮想ポジション(ロングとショート)を維持します。モジュールがクローズシグナルを受け取ると、戦略はその仮想ポジションの残りのボリュームに等しい成行注文を送信します。反対ポジションがまだ開いている間は開始注文が無視されます。

ポジションサイジングはMT5の資金管理ヘルパーをコピーします:

  • NormalMM は基本ボリュームを定義します。
  • SmallMM は最近のトレードがその方向について最後の TotalTrigger トレード内で少なくとも LossTrigger の損失を記録した場合、基本ボリュームを置き換えます。

ロジックはロングとショートのシーケンスに対して別々に評価されます。モジュールが仮想ポジションを完全にクローズするときに平均約定価格からトレード結果が計算されます。

リスク管理は価格ポイントでMT5のストップを反映します:

  • ロングポジションが開いていてローソク足の安値が entry - StopLoss * PriceStep を横切ると、ロングポジションが即座にクローズされます。
  • ローソク足の高値が entry + TakeProfit * PriceStep に触れると利益が確定されます。
  • ルールはショートに対して反転されます(保護のための entry + StopLoss、目標のための entry - TakeProfit)。

パラメーター

すべてのパラメーターは StrategyParam<T> オブジェクトを通じて公開され、StockSharpのデザイナーから最適化できます。モジュールごとにグループ化されています(A、B、C)。次の表は任意のモジュール X の設定を一覧します:

パラメーター 説明
X_CandleType サブスクライブするローソク足シリーズ(上記のデフォルト時間軸)。
X_Period, X_Power 基本XPWMA値を構築するために使用する冪乗加重ウィンドウ。
X_SmoothMethod, X_SmoothLength, X_SmoothPhase 加重価格に適用されるスムーザー。SmoothPhase はMT5 JJMAユーザーとの互換性のために保持されています。
X_AppliedPrice 価格ソース(close、open、high、low、median、typical、weighted、simple、quarter、TrendFollow、DeMark)。
X_Digit 平滑化値に適用される丸め精度。
X_SignalBar シグナル評価に使用する履歴バー。
X_BuyMagic, X_SellMagic トレーサビリティのために保持(注文コメント内で使用)。
X_BuyTotalTrigger, X_BuyLossTrigger ロングサイドの資金管理の閾値。
X_SellTotalTrigger, X_SellLossTrigger ショートサイドの資金管理の閾値。
X_SmallMM, X_NormalMM 資金管理ルールで使用するボリューム。
X_MarginMode, X_Deviation 機能同等性のために保持された予約フィールド;StockSharpの注文を変更しません。
X_StopLoss, X_TakeProfit モジュールの仮想ポジションに適用される価格ステップでの距離。
X_BuyOpen, X_SellOpen, X_SellClose, X_BuyClose モジュールアクションの権限スイッチ。

注意事項

  • 各成行注文は A|BuyOpenB|SellClose などで注釈が付けられているため、約定をそのモジュールまで追跡できます。
  • 戦略は完成したローソク足のみで動作するため、高レベルAPIが自動的に提供するMT5の IsNewBar 保護を再現します。
  • 複数のモジュールが同じバーでトリガーされると、そのボリュームはモジュールごとの仮想ポジションバッファーを使用して順次処理されます。
using System;
using System.Collections.Generic;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// ColorXPWMA Digit Multi-Timeframe strategy. Uses WMA crossover.
/// </summary>
public class ColorXpWmaDigitMultiTimeframeStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _fastPeriod;
	private readonly StrategyParam<int> _slowPeriod;

	private decimal? _prevFast;
	private decimal? _prevSlow;

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

	public int FastPeriod
	{
		get => _fastPeriod.Value;
		set => _fastPeriod.Value = value;
	}

	public int SlowPeriod
	{
		get => _slowPeriod.Value;
		set => _slowPeriod.Value = value;
	}

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

		_fastPeriod = Param(nameof(FastPeriod), 8)
			.SetGreaterThanZero()
			.SetDisplay("Fast WMA", "Fast WMA period", "Indicators");

		_slowPeriod = Param(nameof(SlowPeriod), 25)
			.SetGreaterThanZero()
			.SetDisplay("Slow WMA", "Slow WMA period", "Indicators");
	}

	public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
	{
		return [(Security, CandleType)];
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_prevFast = null;
		_prevSlow = null;
	}

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

		_prevFast = null;
		_prevSlow = null;

		var fast = new ExponentialMovingAverage { Length = FastPeriod };
		var slow = new ExponentialMovingAverage { Length = SlowPeriod };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(fast, slow, ProcessCandle)
			.Start();

		var area = CreateChartArea();
		if (area != null)
		{
			DrawCandles(area, subscription);
			DrawIndicator(area, fast);
			DrawIndicator(area, slow);
			DrawOwnTrades(area);
		}
	}

	private void ProcessCandle(ICandleMessage candle, decimal fastVal, decimal slowVal)
	{
		if (candle.State != CandleStates.Finished)
			return;

		if (!IsFormedAndOnlineAndAllowTrading())
		{
			_prevFast = fastVal;
			_prevSlow = slowVal;
			return;
		}

		if (_prevFast == null || _prevSlow == null)
		{
			_prevFast = fastVal;
			_prevSlow = slowVal;
			return;
		}

		var prevAbove = _prevFast.Value > _prevSlow.Value;
		var currAbove = fastVal > slowVal;

		_prevFast = fastVal;
		_prevSlow = slowVal;

		if (!prevAbove && currAbove && Position <= 0)
		{
			if (Position < 0)
				BuyMarket();
			BuyMarket();
		}
		else if (prevAbove && !currAbove && Position >= 0)
		{
			if (Position > 0)
				SellMarket();
			SellMarket();
		}
	}
}