GitHub で見る

MoStAsHaR15 ピボットライン戦略

概要

この戦略は、StockSharp の高レベル戦略 API を使用して、「MoStAsHaR15 FoReX - Pivot Line」MetaTrader 4 エキスパートを再現します。 ADX、EMA スプレッド、および MACD ヒストグラム (OsMA) からのモメンタム フィルターと組み合わせた元の日次フロアピボット マップが保持されます。日中ロジックは時間ごとのローソク足ストリームで動作しますが、2 番目のサブスクリプションは以前に完了した日次ローソク足を消費して、各決定の前にピボット ラダーを再構築します。

取引ロジック

  • ピボット計算 – 日次シリーズからの昨日の高値、安値、終値により、古典的なピボット (P)、3 つのレジスタンス レベル (R1 ~ R3)、3 つのサポート レベル (S1 ~ S3)、および 6 つの中間点 (M0 ~ M5) が生成されます。現在のろうそくの終値がこのはしごに対してチェックされ、周囲の範囲が検出されます。 M5 と R3 の間の領域を S3/M0 セグメントにリンクする、元の EA からの異常なマッピングは保持されます。
  • 距離フィルター – 現在のレンジを上限とするテイクプロフィット境界までの距離が MinimumDistancePips (デフォルトでは 14 ピップス) より大きい場合にのみトレードがトリガーされ、元の dif1/dif2 チェックが反映されます。
  • 長いエントリには、次のフィルタがすべて必要です。
    • ADX メインラインは AdxThreshold (20) を上回っており、+DI 成分は上昇しており、-DI よりも強いです。
    • 終値ベースの EMA は始値ベースの EMA よりも少なくとも EmaSpreadPips (5 ピップス) 上にあり、前のローソク足はすでに同じ強気の順序を持っていました。
    • MACD ヒストグラムは、前のローソク足と比較して増加しました (OsMA が上昇)。
  • 短いエントリーは、-DI の強さ、弱気な EMA スプレッド、および下降する MACD ヒストグラムを持つ長い分岐を反映しています。
  • いつでも許可されるネットポジションは 1 つだけです。注文は、BuyMarket()SellMarket() を使用して市場執行とともに送信されます。

ポジション管理

  • ストップロス – オプションで、エントリー価格の StopLossPips の下/上にあります。元の EA と同様に無効にするには、0 に設定します。
  • テイクプロフィット – 取引開始時に現在の価格範囲を区切るピボット境界 (サポートまたはレジスタンス) に固定されます。
  • トレーリングストップ – 価格がエントリーを超えて TrailingStopPips + TrailingStepPips を超えて前進すると、ストップは TrailingStopPips の距離を維持するためにトレーリングされます。トレーリングが有効な場合は常に、ステップ値は正のままでなければなりません。
  • ストップロス、トレーリングストップ、またはテイクプロフィットがローソク足内でタッチされた場合、ポジションはそのバーの評価に基づいてクローズされます。

Strategy Parameters

パラメータ 説明 デフォルト
HourlyCandleType 実行ロジックをフィードする日中のローソク足シリーズ。 1時間
DailyCandleType ピボット レベルの計算に使用される毎日のローソク足ストリーム。 1日
StopLossPips 初期のストップロス距離 (pips)。 0 はそれを無効にします。 20
TrailingStopPips トレーリングストップの距離 (pips)。 10
TrailingStepPips トレーリングストップが更新されるまでの最小移動量 (ピップ単位)。トレーリングが有効な場合は、0 より大きい必要があります。 5
MinimumDistancePips トレードに入る前の近くのピボット境界までの最小ピップ距離。 14
EmaSpreadPips 終値 EMA と始値 EMA の間の必須スプレッド。 5
AdxThreshold 信号をアクティブにする最小の ADX 読み取り値。 20
AdxPeriod ADX インジケーター期間。 14
EmaClosePeriod EMA の長さがローソク足の終値に適用されます。 5
EmaOpenPeriod EMA の長さがキャンドルの開口部に適用されます。 8
MacdFastPeriod MACD の高速 EMA 期間 (OsMA 分子)。 12
MacdSlowPeriod MACDのEMA期間が遅いです。 26
MacdSignalPeriod MACD の EMA 期間を信号で知らせます。 9

変換メモ

  • インジケーター値は完成したキャンドルでのみ評価され、ローリング コレクションは保存されません。状態はリポジトリ ガイドラインごとにスカラー フィールドを通じて管理されます。
  • Pips は、証券の PriceStep と小数精度から導出されます。小数点以下 3 桁または 5 桁で引用されたシンボルは、MetaTrader と同様に「ミニ pip」規則を使用します。
  • M5→R3 領域のテイクプロフィット マッピングは、ソース コードへの忠実性を保つために、意図的に S3/M0 ペアにフォールバックします。
  • プロジェクトの指示に従って、戦略内のすべてのコメントは英語のままです。

使用のヒント

  • 特に非標準の日次ロールオーバーがある市場の場合は、商品の取引セッションに合わせてローソクの種類を調整します。
  • このロジックでは閉じたローソク足のストップとターゲットを評価するため、速い市場ではティックレベルの MetaTrader の約定と比較して追加のスリッページが発生する可能性があります。
  • 異なるボラティリティ体制の資産に戦略を適用する場合は、MinimumDistancePipsEmaSpreadPips を調整することを検討してください。
using System;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// MoStAsHaR15 Pivot Line strategy - EMA crossover with ADX trend filter.
/// Buys when fast EMA crosses above slow EMA and ADX confirms trend.
/// Sells when fast EMA crosses below slow EMA and ADX confirms trend.
/// </summary>
public class MoStAsHaR15PivotLineStrategy : Strategy
{
	private readonly StrategyParam<int> _fastPeriod;
	private readonly StrategyParam<int> _slowPeriod;
	private readonly StrategyParam<int> _adxPeriod;
	private readonly StrategyParam<decimal> _adxThreshold;
	private readonly StrategyParam<int> _cooldownCandles;
	private readonly StrategyParam<DataType> _candleType;

	private decimal _prevFast;
	private decimal _prevSlow;
	private bool _hasPrev;
	private int _cooldownRemaining;

	public int FastPeriod { get => _fastPeriod.Value; set => _fastPeriod.Value = value; }
	public int SlowPeriod { get => _slowPeriod.Value; set => _slowPeriod.Value = value; }
	public int AdxPeriod { get => _adxPeriod.Value; set => _adxPeriod.Value = value; }
	public decimal AdxThreshold { get => _adxThreshold.Value; set => _adxThreshold.Value = value; }
	public int CooldownCandles { get => _cooldownCandles.Value; set => _cooldownCandles.Value = value; }
	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }

	public MoStAsHaR15PivotLineStrategy()
	{
		_fastPeriod = Param(nameof(FastPeriod), 20)
			.SetDisplay("Fast EMA", "Fast EMA period", "Indicators");
		_slowPeriod = Param(nameof(SlowPeriod), 100)
			.SetDisplay("Slow EMA", "Slow EMA period", "Indicators");
		_adxPeriod = Param(nameof(AdxPeriod), 14)
			.SetDisplay("ADX Period", "ADX lookback", "Indicators");
		_adxThreshold = Param(nameof(AdxThreshold), 20m)
			.SetDisplay("ADX Threshold", "Min ADX for trending", "Levels");
		_cooldownCandles = Param(nameof(CooldownCandles), 100)
			.SetDisplay("Cooldown", "Candles between signals", "General");
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
			.SetDisplay("Candle Type", "Candle timeframe", "General");
	}

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

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_prevFast = 0;
		_prevSlow = 0;
		_hasPrev = false;
		_cooldownRemaining = 0;

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

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

	private void ProcessCandle(ICandleMessage candle, decimal fast, decimal slow)
	{
		if (candle.State != CandleStates.Finished) return;
		if (!_hasPrev) { _prevFast = fast; _prevSlow = slow; _hasPrev = true; return; }

		if (_cooldownRemaining > 0)
		{
			_cooldownRemaining--;
			_prevFast = fast;
			_prevSlow = slow;
			return;
		}

		if (_prevFast <= _prevSlow && fast > slow && Position <= 0)
		{
			if (Position < 0) BuyMarket();
			BuyMarket();
			_cooldownRemaining = CooldownCandles;
		}
		else if (_prevFast >= _prevSlow && fast < slow && Position >= 0)
		{
			if (Position > 0) SellMarket();
			SellMarket();
			_cooldownRemaining = CooldownCandles;
		}
		_prevFast = fast; _prevSlow = slow;
	}
}