GitHub で見る

Fibonacci の潜在的なエントリーのリトレースメント戦略

概要

Fibonacci の潜在的エントリー リトレースメント戦略 は、MetaTrader のエキスパート EA_PUB_FibonacciPotentialEntries を再作成します。このアルゴリズムは、ライブのレベル 1 相場を待ち、手動で指定された Fibonacci リトレースメント レベル付近で 2 つの未決注文を配置します。共有利益目標に到達すると、戦略は各ポジションを 50% スケールアウトし、保護ストップを残りの数量の損益分岐点に移動します。

元のロジックのマッピング

  • エントリー注文 – 最良買値と最良売値の両方が利用可能になると、2 つの指値注文が発行されます。
    • 最初のオーダー: 50% リトレースメント (P50Level) に配置されます。ストップロスは、61% レベルの 3 スプレッド下 (強気モード) または上 (弱気モード) に固定されます。
    • 2 番目の注文: 61% のリトレースメント (P61Level) に配置され、61% と 100% レベルの中間点から 3 つのスプレッドを定義したストップロスが設定されます。
  • 方向バイアス – 元の bType 入力は MarketBias パラメータになります (買い指値の場合は Bull、売り指値の場合は Bear)。
  • リスク配分 – 最初の取引では常にポートフォリオの株式の 0.7% のリスクが伴います。 2 番目の取引は、RiskPercent の残りの部分 (max(RiskPercent - 0.7, 0)) を消費し、EA で使用される分割を維持します。
  • 出来高計算 – リスクは、商品の価格ステップ、ステップコスト、乗数とともに、Portfolio.CurrentValue (CurrentBalance および BeginValue へのフォールバックあり) を通じてポジションサイズに変換されます。
  • 部分的なテイクプロフィット – 価格が TargetLevel を超えると、約定した各取引は成行注文を送信して、オープンボリュームの半分を決済します。その後、逆指値注文は、EA の OrderClose + OrderModify シーケンスと一致する、記録されたエントリー価格に移動されます。

パラメーター

名前 説明
P50Level 50% Fibonacci リトレースメントに割り当てられた価格。
P61Level 61.8% Fibonacci リトレースメントに割り当てられた価格。
P100Level 100% Fibonacci リトレースメントに割り当てられた価格 (中間ストップに使用)。
TargetLevel 両方の取引で共通の利益目標。
RiskPercent 総リスク予算 (資本に対する割合で表します) (0.7 以上である必要があります)。
MarketBias 長いキャンペーン (Bull) または短いキャンペーン (Bear) を選択します。

実行の詳細

  1. SubscribeLevel1() 経由でレベル 1 の見積もりを購読し、プラスの買値/売値を待ちます。
  2. スプレッド、ストップレベル、ポジションサイズを計算します。オーダーは実行ごとに 1 回送信され、その後は自動的に再作成されません (MQL エキスパートと同じ動作)。
  3. 約定すると、この戦略は平均エントリー価格を記録し、適切な逆指値注文を発注し、レッグごとのオープンボリュームを追跡します。
  4. 市場が TargetLevel を超えて印刷すると、この戦略はレッグごとに 1 つの部分クローズ成行注文を送信し、その後、ストップを残りの数量の損益分岐点に移動します。
  5. 逆指値注文は、ボリュームが残っていない場合、または戦略が停止した場合にキャンセルされます。

注意事項と制限事項

  • ポジションサイズが変更されるたびにストップロスが再生成されます。ブローカーがストップ注文を拒否した場合は、コネクタの権限を確認し、それに応じて取引所固有の設定を調整します。
  • テイクプロフィットは未決注文として登録されません。代わりに、アルゴリズムは価格レベルを監視し、リアルタイムでエグジットを管理することにより、EA を反映します。
  • 注文は 1 回だけ作成されるため、パラメータ変更後に戦略を再開して保留中の注文を更新します (MetaTrader ワークフローと同じ)。
namespace StockSharp.Samples.Strategies;

using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;

/// <summary>
/// Fibonacci Retracement Entries strategy: EMA trend with Fibonacci retracement levels.
/// Buys on retracement to 61.8% in uptrend, sells on retracement to 38.2% in downtrend.
/// </summary>
public class FibonacciPotentialEntriesRetracementStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _emaPeriod;
	private readonly StrategyParam<int> _lookback;
	private readonly StrategyParam<int> _signalCooldownCandles;

	private decimal _high;
	private decimal _low;
	private int _barCount;
	private int _candlesSinceTrade;

	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
	public int EmaPeriod { get => _emaPeriod.Value; set => _emaPeriod.Value = value; }
	public int Lookback { get => _lookback.Value; set => _lookback.Value = value; }
	public int SignalCooldownCandles { get => _signalCooldownCandles.Value; set => _signalCooldownCandles.Value = value; }

	public FibonacciPotentialEntriesRetracementStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(30).TimeFrame())
			.SetDisplay("Candle Type", "Candle timeframe", "General");
		_emaPeriod = Param(nameof(EmaPeriod), 50)
			.SetGreaterThanZero()
			.SetDisplay("EMA Period", "EMA period", "Indicators");
		_lookback = Param(nameof(Lookback), 50)
			.SetGreaterThanZero()
			.SetDisplay("Lookback", "Lookback for high/low", "General");
		_signalCooldownCandles = Param(nameof(SignalCooldownCandles), 6)
			.SetGreaterThanZero()
			.SetDisplay("Signal Cooldown", "Bars to wait between trades", "Trading");
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_high = 0;
		_low = decimal.MaxValue;
		_barCount = 0;
		_candlesSinceTrade = SignalCooldownCandles;
	}

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_high = 0;
		_low = decimal.MaxValue;
		_barCount = 0;
		_candlesSinceTrade = SignalCooldownCandles;
		var ema = new ExponentialMovingAverage { Length = EmaPeriod };
		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(ema, ProcessCandle).Start();
	}

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

		if (_candlesSinceTrade < SignalCooldownCandles)
			_candlesSinceTrade++;

		if (candle.HighPrice > _high) _high = candle.HighPrice;
		if (candle.LowPrice < _low) _low = candle.LowPrice;
		_barCount++;

		if (_barCount < 20) return;

		var range = _high - _low;
		if (range <= 0) return;

		var close = candle.ClosePrice;
		var fib618 = _high - range * 0.618m;
		var fib382 = _high - range * 0.382m;
		if (close > emaValue && close <= fib618 && Position <= 0 && _candlesSinceTrade >= SignalCooldownCandles)
		{
			BuyMarket();
			_candlesSinceTrade = 0;
		}
		else if (close < emaValue && close >= fib382 && Position >= 0 && _candlesSinceTrade >= SignalCooldownCandles)
		{
			SellMarket();
			_candlesSinceTrade = 0;
		}
	}
}