GitHub で見る

一攫千金のGBPセッションリバーサル戦略

概要

Get Rich or Die Trying GBP Strategy は、MetaTrader 4 エキスパート アドバイザー「Get Rich or Die Trying GBP」を StockSharp の高レベル API に移植した高頻度平均回帰システムです。このロジックは、分足のローソク足の短いローリング履歴を監視し、最新のローソク足が予想方向に反してほぼ終了した 1 日の事前定義された 2 つの時間帯付近で取引を開始します。このアプローチは、ロンドンとニューヨークのセッションが重なった直後の素早いリトレースメントを捉えようとします。

取引ロジック

  1. この戦略は、デフォルトで 1 分ローソク足をサブスクライブします (ローソク足のタイプはカスタマイズできます)。
  2. 最後に ルックバック して完了したキャンドルのローリング ウィンドウが維持されます。各キャンドルは次のように分類されます。
    • +1 終値が始値(弱気のローソク足)を下回った場合。
    • -1 終値が始値を上回った場合 (強気ローソク足)。
    • 0 キャンドルが中立の場合。
  3. これらの分類の累積合計は、取引の方向を決定するために使用されます。
    • プラスの合計は、弱気のローソク足が優勢であり、戦略がロングエントリーの準備をしていることを意味します。
    • マイナスの合計は、強気のローソク足が優勢であり、戦略が ショート エントリーの準備をしていることを意味します。
  4. 注文は、現在のサーバー時間が次の 2 つの目標時間のいずれかに一致する時間後の最初の EntryWindowMinutes 分間にのみ行うことができます。
    • FirstEntryHour + HourShift (デフォルト: GMT+2 修正後のロンドン午前 0 時)。
    • SecondEntryHour + HourShift (デフォルト: ニューヨークの閉店時間と重なるサーバー時間の 21:00)。
  5. オープンなポジションがなく、すべての条件が満たされている場合、ストラテジーは固定ロット サイズまたは資金管理ブロックから計算された動的サイズのいずれかを使用して成行注文を送信します。
  6. ポジションにいる間、この戦略は 3 つの独立した出口ルールを適用します。
    • 部分テイクプロフィットは、終値がPartialTakeProfitPoints価格に有利に移動すると取引を終了します。
    • ハードストップロスは、価格が取引に対して StopLossPoints 価格ステップを移動したときにトリガーされます。
    • トレーリング ストップは、市場がTrailingStopPointsの価格ステップを超えた後に、エントリー以降の最高高値 (ロングの場合) または最低安値 (ショートの場合) を使用して利益を確定します。
  7. TakeProfitPoints 価格ステップに等しい最終テイクプロフィットレベルもセーフティネットとして監視されます。

パラメーター

パラメータ デフォルト 説明
TakeProfitPoints 100 トレーリングロジックの後に監視される最大利益距離 (価格ステップ単位)。
PartialTakeProfitPoints 40 元の EA の早期手仕舞いを再現するプライマリテイクプロフィットディスタンス(価格ステップ単位)。
StopLossPoints 100 ストップロス距離 (価格ステップ単位)。
TrailingStopPoints 30 トレーリングストップ距離 (価格ステップ単位)。
FixedVolume 1 資金管理が無効になっている場合のロット単位の基本注文量。
UseMoneyManagement 口座価値と設定されたリスクに基づいて動的なポジションサイジングを可能にします。
RiskPercent 10 資金管理がアクティブな場合の、取引ごとのポートフォリオ価値のリスクに対する割合。
Lookback 18 強気/弱気カウントに使用される完成したローソク足の数。
FirstEntryHour 22 時間シフト修正前の最初の取引時間。
SecondEntryHour 19 時間シフト修正前の 2 番目の取引時間。
HourShift 2 タイムゾーン修正は両方の取引時間に適用されます。
EntryWindowMinutes 5 エントリーウィンドウの幅 (予選時間の開始からの分単位)。
CandleType 1分間の時間枠 購読するキャンドルの種類。他の周期的なキャンドル タイプに置き換えることができます。

資金管理

UseMoneyManagement が有効な場合、この戦略は、設定された StopLossPoints よりも現在のポートフォリオ値の RiskPercent をリスクにさらして注文量を推定します。計算では、商品のロットステップと取引所準拠を維持するための最小量が考慮されます。

使用上の注意

  • 取引ウィンドウは、受信ローソクの交換/サーバー時間を使用して評価されます。 FirstEntryHour + HourShiftSecondEntryHour + HourShift が目的のセッション境界と一致するように、HourShift を調整します。
  • ノイズの多い決定を避けるために、Lookback は 1 より大きいままにする必要があります。値を増やすと、反応が遅くなりますが、センチメントの測定がスムーズになります。
  • 保護ロジックは完成したキャンドルに依存します。バー内の精度が必要な場合は、それに応じてローソク足の期間を短縮します。
  • 元の MQL エキスパートは複数のポジションを同時に許可していました。このポートは、StockSharp のベスト プラクティスに合わせて、公開ポジションを単一のオープン ポジションに制限します。

制限事項

  • トレーリングストップは仮想であり、価格がトレーリングしきい値を超えた後、次に終了したローソク足で市場の出口を送信することによって実行されます。
  • 資金管理のサイジングは、Security.StepPrice が 1 つの価格ステップの金銭的価値を正しく表すことを前提としています。ライブ取引の前に、各商品のこのマッピングを検証してください。

要件

  • StockSharp の高レベルの API 環境 (AlgoTrading ソリューション)。
  • 取引されたポンド商品の履歴およびリアルタイムの分足ローソク足。

参考資料

  • 元の MetaTrader 4 専門アドバイザー: MQL/7690/Get_rich_or_die_trying_any_gbp.mq4
using System;
using System.Collections.Generic;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// Get Rich GBP Session Reversal strategy - RSI mean reversion with EMA trend filter.
/// Buys when RSI crosses below oversold while price is above EMA (bullish dip).
/// Sells when RSI crosses above overbought while price is below EMA (bearish rally).
/// </summary>
public class GetRichGbpSessionReversalStrategy : Strategy
{
	private readonly StrategyParam<int> _rsiPeriod;
	private readonly StrategyParam<int> _emaPeriod;
	private readonly StrategyParam<decimal> _overbought;
	private readonly StrategyParam<decimal> _oversold;
	private readonly StrategyParam<DataType> _candleType;

	private decimal _prevRsi;
	private bool _hasPrev;

	public int RsiPeriod { get => _rsiPeriod.Value; set => _rsiPeriod.Value = value; }
	public int EmaPeriod { get => _emaPeriod.Value; set => _emaPeriod.Value = value; }
	public decimal Overbought { get => _overbought.Value; set => _overbought.Value = value; }
	public decimal Oversold { get => _oversold.Value; set => _oversold.Value = value; }
	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }

	public GetRichGbpSessionReversalStrategy()
	{
		_rsiPeriod = Param(nameof(RsiPeriod), 14)
			.SetDisplay("RSI Period", "RSI lookback", "Indicators");

		_emaPeriod = Param(nameof(EmaPeriod), 50)
			.SetDisplay("EMA Period", "EMA trend filter", "Indicators");

		_overbought = Param(nameof(Overbought), 70m)
			.SetDisplay("Overbought", "RSI overbought level", "Levels");

		_oversold = Param(nameof(Oversold), 30m)
			.SetDisplay("Oversold", "RSI oversold level", "Levels");

		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
			.SetDisplay("Candle Type", "Candle timeframe", "General");
	}

	public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities() => [(Security, CandleType)];
	protected override void OnReseted() { base.OnReseted(); _prevRsi = 0m; _hasPrev = false; }

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

		_hasPrev = false;

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

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(rsi, ema, ProcessCandle)
			.Start();
	}

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

		var close = candle.ClosePrice;

		if (!_hasPrev)
		{
			_prevRsi = rsi;
			_hasPrev = true;
			return;
		}

		// RSI crosses below oversold = buy reversal
		if (_prevRsi >= Oversold && rsi < Oversold && Position <= 0)
		{
			if (Position < 0)
				BuyMarket();
			BuyMarket();
		}
		// RSI crosses above overbought = sell reversal
		else if (_prevRsi <= Overbought && rsi > Overbought && Position >= 0)
		{
			if (Position > 0)
				SellMarket();
			SellMarket();
		}

		_prevRsi = rsi;
	}
}