GitHub で見る

FXF ファストインファストアウト戦略

概要

FXF ファスト イン ファスト アウト 戦略は、元の MetaTrader 4 エキスパート アドバイザーを StockSharp の高レベル戦略に変換するボラティリティ主導のブレイクアウト システムです。大きなローソク足の設定可能な時間枠を監視し、スプレッドを測定し、即座の勢いの継続をキャッチしようとする保留中のストップ注文を配置することで対応します。このロジックはシグナル生成に完成したローソク足のみを使用し、相場 (レベル 1 データ) はスプレッド フィルター、注文の発注、およびトレーリング ストップの管理に使用されます。

現在のローソク足がボラティリティのしきい値を超えて拡大すると、戦略はローソク足の始値と比較して中間価格を評価します。仲値が始値を上回って終了した場合、買いストップは最良売値の上に配置されます。それを下回って終了した場合、最高入札価格の下に売りストップが置かれます。保護的なストップロスとテイクプロフィットのレベルが未決注文に付加され、オプションのトレーリングロジックにより、オープンポジションが約定された後に保護されます。資金管理では、ポートフォリオの価値とストップ距離に基づいて注文のサイズを動的に設定できます。

取引ロジック

  • シグナル検出 – 終了したローソク足ごとに、戦略は価格ステップで表されるローソク足の範囲が VolatilitySizePoints を超えているかどうかをチェックします。範囲が十分に大きい場合は、最新の最良買値/売値スナップショットを使用して中間価格を計算します。
  • 方向性バイアス – ローソク足の始値を上回る中間価格は強気のバイアス (買いストップ注文) を生成し、始値を下回る中間価格は弱気のバイアス (売りストップ注文) を生成します。仲値が始値に等しい場合、またはボラティリティ要件が満たされていない場合、注文は出されません。
  • スプレッドフィルター – 相場は継続的に監視されます。未決注文は、現在のスプレッドが MaxSpreadPoints を下回っている場合にのみ作成されます。スプレッドがその制限を超えて拡大した場合、スプレッドが許容レベルに戻るまで、既存の未決注文はすべてキャンセルされます。
  • 未決注文の管理 – バーごとにアクティブにできる未決注文は 1 つだけです。各注文は最良見積から EnterOffsetPoints だけオフセットされます。ストップロスとテイクプロフィットの距離はポイントで定義され、自動的に価格に変換されます。
  • リスク管理UseMoneyManagement を有効にすると、商品ステップ価格を使用して、ポートフォリオ値、リスク割合、ストップロス距離から注文量が決定されます。それ以外の場合は、デフォルトの Volume プロパティが使用されます。
  • トレーリング ストップEnableTrailing が true の場合、ストラテジーは TrailingStopPoints に現在のスプレッドを加えたアクティブ ポジションの内部トレーリング ストップを維持します。市場価格がトレーリングストップを越えた場合、ポジションは市場でクローズされます。

パラメーター

パラメータ 説明
EnterOffsetPoints 最良気配と保留中の逆指値注文価格の間の価格ステップの距離。
MaxSpreadPoints 最大許容スプレッド (価格ステップ単位)。この制限を超えるスプレッドは、新しいエントリーをブロックし、アクティブな未決注文をキャンセルします。
TakeProfitPoints 未決注文に適用される価格ステップの利食い距離。テイクプロフィット配置をスキップするには、ゼロに設定します。
StopLossPoints 価格ステップのストップロス距離。資金管理のサイジングに必要です。ストップロスの配置を無効にするには、ゼロに設定します。
VolatilitySizePoints 新しいブレイクアウトシグナルを生成するために必要なローソク足の最小範囲(価格ステップ単位)。
EnableTrailing オープンポジションのトレーリングストップロジックを有効または無効にします。
TrailingStopPoints 価格ステップにおける基本トレーリング距離。実際のトレーリングレベルには、元の EA の動作を模倣するための現在のスプレッドも含まれています。
UseMoneyManagement RiskPercent 値を使用してポートフォリオベースのポジションサイジングを有効にします。
RiskPercent 資金管理がアクティブな場合に使用される取引ごとのリスクの割合。
MaxOrdersPerBar 単一バー中に許可される未決注文の最大数。通常、元の Expert Advisor をミラーリングするには 1 に設定します。
CandleType シグナルの計算に使用されるローソク足の時間枠。デフォルトは 15 分です。

注文ワークフロー

  1. 検出 – ボラティリティ基準を満たす完成したローソクは、望ましい取引方向を設定します。
  2. 検証 – 相場が利用可能であり、取引が許可されている必要があり、オープンポジションが存在してはならず、他のアクティブな注文が存在してはいけません。
  3. 配置 – この戦略は、計算されたオフセットで買いストップまたは売りストップを配置し、ストップロスとテイクプロフィットのレベルを付加します。
  4. トレーリングとエグジット – 注文が約定した後、トレーリングモジュールは最新の相場を監視します。トレーリングレベルを突破すると、成行注文でポジションがクローズされます。テイクプロフィット注文とストップロス注文は、ブローカーまたはシミュレーターによる自動執行のためにポジションに付加されたままになります。

注意事項

  • この戦略が正しく動作するには、キャンドル データ サブスクリプションとレベル 1 データ サブスクリプションの両方が必要です。
  • ストップロスパラメータまたはセキュリティメタデータ(価格ステップまたはステップ価格)が利用できない場合、リスクベースのサイジングは設定された Volume に戻ります。
  • トレーリングストップは、MetaTrader の動作と一致するようにマーケットイグジットを通じて内部で管理され、さまざまな執行場所間での互換性が確保されます。
namespace StockSharp.Samples.Strategies;

using System;

using Ecng.Common;

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

/// <summary>
/// Fast In Fast Out scalping strategy: quick entry/exit using EMA and RSI.
/// </summary>
public class FxfFastInFastOutStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _emaPeriod;
	private readonly StrategyParam<int> _rsiPeriod;

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

	public int EmaPeriod
	{
		get => _emaPeriod.Value;
		set => _emaPeriod.Value = value;
	}

	public int RsiPeriod
	{
		get => _rsiPeriod.Value;
		set => _rsiPeriod.Value = value;
	}

	public FxfFastInFastOutStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(30).TimeFrame())
			.SetDisplay("Candle Type", "Candle timeframe", "General");

		_emaPeriod = Param(nameof(EmaPeriod), 10)
			.SetGreaterThanZero()
			.SetDisplay("EMA Period", "EMA period", "Indicators");

		_rsiPeriod = Param(nameof(RsiPeriod), 7)
			.SetGreaterThanZero()
			.SetDisplay("RSI Period", "RSI period", "Indicators");
	}

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

		var ema = new ExponentialMovingAverage { Length = EmaPeriod };
		var rsi = new RelativeStrengthIndex { Length = RsiPeriod };

		decimal? prevRsi = null;

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(ema, rsi, (candle, emaVal, rsiVal) =>
			{
				if (candle.State != CandleStates.Finished)
					return;

				if (!IsFormedAndOnlineAndAllowTrading())
					return;

				var close = candle.ClosePrice;

				if (prevRsi.HasValue)
				{
					if (prevRsi.Value <= 50 && rsiVal > 50 && close > emaVal && Position <= 0)
						BuyMarket();
					else if (prevRsi.Value >= 50 && rsiVal < 50 && close < emaVal && Position >= 0)
						SellMarket();
				}

				prevRsi = rsiVal;
			})
			.Start();

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