GitHub で見る

Fortrader 10 ピップス戦略

概要

Fortrader 10 Pips 戦略 は、MetaTrader 4 エキスパート アドバイザー 10pips.mq4 の StockSharp 移植です (戦略 ID 8074)。ロボットは同時に 1 つのロングポジションと 1 つのショートポジションをオープンしたままにします。各レッグは、シンボルポイントで測定される固定のテイクプロフィット、ストップロス、およびトレーリングストップの距離を使用します。

この変換により、StockSharp の高レベルの API 内のヘッジ動作が再作成されます。戦略が開始されるとすぐに、市場買い注文と市場売り注文が送信されます。保護命令がレッグを閉じると、戦略は即座に同じ方向に新しい命令を開き、2 つの対立するポジションを常に維持します。

パラメーター

名前 説明
Take Profit Buy ロングレッグのテイクプロフィット距離(ポイント単位)。
Stop Loss Buy ロングレッグのストップロス距離 (ポイント単位)。
Trailing Stop Buy ロングレッグのトレーリングストップ距離 (ポイント単位)。末尾を無効にするには、ゼロに設定します。
Take Profit Sell ショートレッグのテイクプロフィット距離(ポイント単位)。
Stop Loss Sell ショートレッグのストップロス距離(ポイント単位)。
Trailing Stop Sell ショートレッグのトレーリングストップ距離 (ポイント単位)。末尾を無効にするには、ゼロに設定します。
Volume すべての成行注文のロット単位のボリューム。

すべての距離に商品の PriceStep を掛けて、ポイントから絶対価格値に変換します。各パラメータは StrategyParam<T> を通じて公開されるため、GUI を介して戦略を調整または最適化できます。

取引ロジック

  1. スタートアップOnStarted はレベル 1 データをサブスクライブして、現在の最高入札価格と最高売値を追跡します。この戦略は、1 つの市場買い注文と 1 つの市場売り注文をただちに送信します。
  2. 保護注文 – 各エントリー約定後 (OnNewMyTrade)、距離がゼロより大きい場合、戦略は関連するストップロス注文とテイクプロフィット注文を作成します。注文は最も近い価格ステップに四捨五入されます。
  3. リエントリー – ストップロスまたはテイクプロフィット注文が実行されると、クローズされたレッグが新しい成行注文で即座に再開されるため、双方向のエクスポージャーが持続します。
  4. トレーリング ストップ – レベル 1 の更新により UpdateTrailingStops がトリガーされ、現在の買値/売値がエントリー価格から設定されたトレーリング ディスタンスを超えた場合にストップロス注文が調整されます。このロジックは元の EA を反映しています。つまり、利益がトレーリング距離を超えるとトレーリングが開始され、ストップは利益の方向にのみ移動します。

実装メモ

  • 元の MT4 コードは、最初の買い注文と売り注文の間に 10 秒待機しました。 StockSharp ではこのような遅延は必要ないため、両方の注文がすぐに送信されます。
  • StockSharp はデフォルトでネット ポジションを使用するため、実際のヘッジは反対のポジションをサポートするブローカー/コネクターに依存する場合があります。この戦略は各レッグを個別に追跡し、終了するたびにそれらを再確立します。
  • StartProtection() は、フレームワーク設定で構成されている場合、グローバル リスク保護がアクティブになるように、OnStarted 中に 1 回呼び出されます。

使用のヒント

  • ヘッジ動作が必要な場合は、選択したコネクタがロングとショートの同時ポジションをサポートしていることを確認してください。
  • 対応するレッグのトレーリングを無効にするには、トレーリング距離をゼロに設定します。
  • 取引されるシンボルと時間枠に合わせて履歴データのリスク パラメーター (Take ProfitStop LossTrailing Stop) を最適化します。
using System;

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

namespace StockSharp.Samples.Strategies;

public class Fortrader10PipsStrategy : Strategy
{
	private readonly StrategyParam<int> _fastPeriod;
	private readonly StrategyParam<int> _slowPeriod;
	private readonly StrategyParam<DataType> _candleType;

	private decimal _prevFast; private decimal _prevSlow; private bool _hasPrev;

	public int FastPeriod { get => _fastPeriod.Value; set => _fastPeriod.Value = value; }
	public int SlowPeriod { get => _slowPeriod.Value; set => _slowPeriod.Value = value; }
	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }

	public Fortrader10PipsStrategy()
	{
		_fastPeriod = Param(nameof(FastPeriod), 7).SetDisplay("Fast EMA", "Fast EMA period", "Indicators");
		_slowPeriod = Param(nameof(SlowPeriod), 21).SetDisplay("Slow EMA", "Slow EMA period", "Indicators");
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame()).SetDisplay("Candle Type", "Candle timeframe", "General");
	}

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_hasPrev = false;
		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 (_prevFast <= _prevSlow && fast > slow && Position <= 0)
		{ if (Position < 0) BuyMarket(); BuyMarket(); }
		else if (_prevFast >= _prevSlow && fast < slow && Position >= 0)
		{ if (Position > 0) SellMarket(); SellMarket(); }
		_prevFast = fast; _prevSlow = slow;
	}

	protected override void OnReseted()
	{
		base.OnReseted();
		_prevFast = 0;
		_prevSlow = 0;
		_hasPrev = false;
	}
}