GitHub で見る

XDeMarker Histogram Vol Direct戦略

この戦略はStockSharpの高レベルAPIを使用してMetaTrader 5のエキスパートExp_XDeMarker_Histogram_Vol_Directを複製します。選択したボリュームストリームによってXDeMarkerオシレーターを乗算し、同じ移動平均でオシレーターとボリュームの両方をスムーズにし、結果を設定可能な上限/下限レベルと比較します。スムーズ化されたヒストグラムが連続するバー間で方向を変えると取引決定が行われます。

インジケーターロジック

  1. 選択した時間軸でクラシックなXDeMarkerオシレーターを計算します。
  2. 完成した各ローソク足のティック数または実際のボリュームでオシレーターをスケールします。
  3. 選択した移動平均タイプでヒストグラムとボリュームの両方をスムーズ化します。
  4. スムーズ化されたボリュームを設定されたレベル乗数で乗算して4つの動的バンドを取得します。
  5. ヒストグラムの方向(上昇または下降)を検出します。方向が反転すると、戦略は対応する方向に新しいポジションを開き、反対のトレードもクローズします。

スムージング方法は単純、指数、スムーズ化(RMA/SMMA)、加重移動平均をサポートします。元のライブラリのエキゾチックフィルター(JJMA、JurX、ParMA、T3、VIDYA、AMA)はこのポートでは利用できません。

トレードルール

  • ロングエントリーAllow Long Entry = trueのとき有効。前のバーの方向が「上」で最後のバーが「下」に切り替わった場合、戦略はVolumeロットのロングポジションを目指します。
  • ショートエントリーAllow Short Entry = trueのとき有効。前のバーが「下」で最新のバーが「上」に向かうときにトリガーされます。
  • ロングエグジットAllow Long Exit = trueのとき有効。前のバーの方向が「下」の場合、同じバーで新しいショートエントリーが発火しない限りポジションを解消します。
  • ショートエグジットAllow Short Exit = trueのとき有効。前のバーの方向が「上」のときに活性化されます。

シグナルは完成した各ローソク足につき1回評価されます。StockSharp実装は元の1バー遅延を維持します;Signal Barパラメータは参照用として存在しますが、1以外の値は警告付きで無視されます。

パラメータ

パラメータ 説明
Candle Type インジケーター用ローソク足を構築するために使用する時間軸。
DeMarker Period ベースXDeMarkerオシレーターのルックバック期間。
Volume Source ティック数と実際の取引ボリュームの間から選択。
High Level 2 / High Level 1 上部バンドを形成するためにスムーズ化されたボリュームに適用される乗数。
Low Level 1 / Low Level 2 下部バンドの乗数。
Smoothing Method ヒストグラムとボリュームの両方に適用される移動平均タイプ。
Smoothing Length スムージングウィンドウの長さ。
Smoothing Phase 互換性プレースホルダー(使用されませんが同等性のために保持)。
Signal Bar 履歴オフセット、エキスパートと同様に1に固定。
Allow Long/Short Entry それぞれの方向でのポジション開設を有効にします。
Allow Long/Short Exit 既存のトレードの自動クローズを有効にします。

実装に関する注意事項

  • XDeMarkerHistogramVolDirectIndicatorクラスはMT5インジケーターバッファーを再現し、複雑なインジケーター値を通じてスムーズ化されたヒストグラム、バンド、方向フラグを公開します。
  • 新しいターゲットエクスポージャーが必要な場合、戦略は現在のポジションを目的のレベル(Volume-Volumeまたはフラット)に移動させる単一の成行注文を送信します。これは元のMQL5コードの順次クローズ/オープン呼び出しを模倣し、注文を重複させません。
  • チャートレンダリングは、チャートエリアが利用可能な場合にローソク足、カスタムインジケーター、実行されたトレードを自動的にプロットします。
using System;
using System.Collections.Generic;

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

namespace StockSharp.Samples.Strategies;

public class XDeMarkerHistogramVolDirectStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _period;
	private decimal? _prevDm;

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

	public XDeMarkerHistogramVolDirectStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame()).SetDisplay("Candle Type", "Timeframe", "General");
		_period = Param(nameof(Period), 14).SetGreaterThanZero().SetDisplay("DeMarker Period", "DeMarker lookback", "Indicators");
	}

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

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

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_prevDm = null;
		var dm = new DeMarker { Length = Period };
		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(dm, ProcessCandle).Start();
		var area = CreateChartArea();
		if (area != null) { DrawCandles(area, subscription); DrawOwnTrades(area); }
	}

	private void ProcessCandle(ICandleMessage candle, decimal dmVal)
	{
		if (candle.State != CandleStates.Finished) return;
		if (!IsFormedAndOnlineAndAllowTrading()) { _prevDm = dmVal; return; }
		if (_prevDm == null) { _prevDm = dmVal; return; }
		if (_prevDm.Value < 0.45m && dmVal >= 0.55m && Position <= 0) { if (Position < 0) BuyMarket(); BuyMarket(); }
		else if (_prevDm.Value > 0.55m && dmVal <= 0.45m && Position >= 0) { if (Position > 0) SellMarket(); SellMarket(); }
		_prevDm = dmVal;
	}
}