ホーム
/
戦略のサンプル
GitHub で見る
一攫千金のGBPセッションリバーサル戦略
概要
Get Rich or Die Trying GBP Strategy は、MetaTrader 4 エキスパート アドバイザー「Get Rich or Die Trying GBP」を StockSharp の高レベル API に移植した高頻度平均回帰システムです。このロジックは、分足のローソク足の短いローリング履歴を監視し、最新のローソク足が予想方向に反してほぼ終了した 1 日の事前定義された 2 つの時間帯付近で取引を開始します。このアプローチは、ロンドンとニューヨークのセッションが重なった直後の素早いリトレースメントを捉えようとします。
取引ロジック
この戦略は、デフォルトで 1 分ローソク足をサブスクライブします (ローソク足のタイプはカスタマイズできます)。
最後に ルックバック して完了したキャンドルのローリング ウィンドウが維持されます。各キャンドルは次のように分類されます。
+1 終値が始値(弱気のローソク足)を下回った場合。
-1 終値が始値を上回った場合 (強気ローソク足)。
0 キャンドルが中立の場合。
これらの分類の累積合計は、取引の方向を決定するために使用されます。
プラスの合計は、弱気のローソク足が優勢であり、戦略がロング エントリーの準備をしていることを意味します。
マイナスの合計は、強気のローソク足が優勢であり、戦略が ショート エントリーの準備をしていることを意味します。
注文は、現在のサーバー時間が次の 2 つの目標時間のいずれかに一致する時間後の最初の EntryWindowMinutes 分間にのみ行うことができます。
FirstEntryHour + HourShift (デフォルト: GMT+2 修正後のロンドン午前 0 時)。
SecondEntryHour + HourShift (デフォルト: ニューヨークの閉店時間と重なるサーバー時間の 21:00)。
オープンなポジションがなく、すべての条件が満たされている場合、ストラテジーは固定ロット サイズまたは資金管理ブロックから計算された動的サイズのいずれかを使用して成行注文を送信します。
ポジションにいる間、この戦略は 3 つの独立した出口ルールを適用します。
部分テイクプロフィット は、終値がPartialTakeProfitPoints 価格に有利に移動すると取引を終了します。
ハードストップロス は、価格が取引に対して StopLossPoints 価格ステップを移動したときにトリガーされます。
トレーリング ストップ は、市場がTrailingStopPoints の価格ステップを超えた後に、エントリー以降の最高高値 (ロングの場合) または最低安値 (ショートの場合) を使用して利益を確定します。
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 + HourShift と SecondEntryHour + 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;
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import RelativeStrengthIndex, ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
class get_rich_gbp_session_reversal_strategy(Strategy):
def __init__(self):
super(get_rich_gbp_session_reversal_strategy, self).__init__()
self._rsi_period = self.Param("RsiPeriod", 14).SetDisplay("RSI Period", "RSI lookback", "Indicators")
self._ema_period = self.Param("EmaPeriod", 50).SetDisplay("EMA Period", "EMA trend filter", "Indicators")
self._overbought = self.Param("Overbought", 70.0).SetDisplay("Overbought", "RSI overbought level", "Levels")
self._oversold = self.Param("Oversold", 30.0).SetDisplay("Oversold", "RSI oversold level", "Levels")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))).SetDisplay("Candle Type", "Candle timeframe", "General")
self._prev_rsi = 0.0
self._has_prev = False
@property
def rsi_period(self): return self._rsi_period.Value
@property
def ema_period(self): return self._ema_period.Value
@property
def overbought(self): return self._overbought.Value
@property
def oversold(self): return self._oversold.Value
@property
def candle_type(self): return self._candle_type.Value
def OnReseted(self):
super(get_rich_gbp_session_reversal_strategy, self).OnReseted()
self._prev_rsi = 0.0
self._has_prev = False
def OnStarted2(self, time):
super(get_rich_gbp_session_reversal_strategy, self).OnStarted2(time)
self._has_prev = False
rsi = RelativeStrengthIndex()
rsi.Length = self.rsi_period
ema = ExponentialMovingAverage()
ema.Length = self.ema_period
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(rsi, ema, self.process_candle).Start()
def process_candle(self, candle, rsi, ema):
if candle.State != CandleStates.Finished:
return
rsi_val = float(rsi)
if not self._has_prev:
self._prev_rsi = rsi_val
self._has_prev = True
return
if self._prev_rsi >= self.oversold and rsi_val < self.oversold and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
elif self._prev_rsi <= self.overbought and rsi_val > self.overbought and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._prev_rsi = rsi_val
def CreateClone(self):
return get_rich_gbp_session_reversal_strategy()