GitHub で見る

RSI Bollinger Bands EA(StockSharp変換)

概要

この戦略はMetaTrader 5エキスパートアドバイザー「RSI Bollinger Bands EA」の高レベルStockSharpポートです。15分足のローソク足で取引し、2つの独立したRSIベースのトリガーを組み合わせます:

  • トリガー1 – M15、H1、H4でのRSIの固定された買われ過ぎ/売られ過ぎしきい値に、確認用のストキャスティクスと傾きフィルターを組み合わせたもの。
  • トリガー2 – すべての3つの時間軸で設定可能なサンプルサイズを使って非対称標準偏差(別々の正/負シグマ)から計算される適応型RSIバンド。ストキャスティクスがモメンタムを確認しながらRSIは動的バンドを突き抜けなければなりません。

両方のトリガーは、低い時間軸(M15ボリンジャースプレッド)でのボラティリティ収縮、高い時間軸(H4ボリンジャースプレッド)でのボラティリティ拡大、およびH4 ATRによる穏やかな環境を必要とします。オリジナルEAの制約を反映して、一度に1つのトリガーのみを有効にできます。

データ要件

  • 主要実行ローソク足:M15CandleType(デフォルト:15分)。すべてのエントリーとエグジットはこれらのローソク足の終値で評価されます。
  • 確認ローソク足:H1CandleType(デフォルト:1時間)RSI条件と統計用。
  • 上位時間軸ローソク足:H4CandleType(デフォルト:4時間)RSI確認、ボリンジャースプレッドフィルター、ATRボラティリティフィルター用。

トレーディングロジック

  1. セッションフィルター

    • トレーディングはEntryHourから始まりOpenHours時間続く設定可能な時間ウィンドウに制限されています。OpenHoursがゼロの場合、ウィンドウは単一の開始時間だけ続きます。
    • 金曜日はローソク足の時間がFridayEndHourに達すると取引が停止します(デフォルト:4、つまり金曜日の04:00以降)。
    • 新しいポジションは、現在の純ポジションがフラット(Position == 0)の場合にのみ開けます。
  2. ボラティリティとスプレッドフィルター(両トリガー)

    • H4ボリンジャースプレッドは上位時間軸のレンジが十分に広いことを確認するためにBbSpreadH4MinX pips(X = 1または2)より大きくなければなりません。
    • M15ボリンジャースプレッドは取引時間軸で価格が圧縮されているようにBbSpreadM15MaxX pips以下でなければなりません。
    • pipに変換されたH4 ATRはAtrLimit以下でなければなりません。
  3. トリガー1 – 固定RSIレベル

    • M15、H1、H4のRSI値はロング設定をトリガーするためにそれぞれの「Low」しきい値を下回りながら「Low Limit」フェイルセーフを上回らなければなりません。
    • RSIはロングの場合RDeltaM15Lim1(デフォルト:–3.5 pips)を超えて前のM15読み取り値より上昇しなければならず、ショートの場合は反転したしきい値より大きく下落しなければなりません。
    • ストキャスティクスのメインラインはロングの場合StocLoM15_1を下回り、ショートの場合StocHiM15_1を上回らなければなりません。
    • ショートエントリーはRSI値が「High」しきい値を上回り「High Limit」フェイルセーフを下回ることを必要とします。
  4. トリガー2 – 適応型RSIシグマバンド

    • 各時間軸について過去のRSIサンプルが保持されます(最大NumRsi要素)。別々の正と負の標準偏差が計算され、非対称なボリンジャーに似たバンドが構築されます。
    • 各時間軸の動的な下限と上限バンドはRsi*M*Sigma2乗数(M15/H1/H4)を適用することで生成されます。追加の「リミット」乗数(Rsi*M*SigmaLim2)は許可される極値を制限します。
    • ロングエントリーはすべての3つのRSI値がそれぞれの適応下限バンドを下回り下限を上回ることを要求します。ストキャスティクスはStocLoM15_2を下回り、RSIの傾きはRDeltaM15Lim2より大きくなければなりません。
    • ショートエントリーは上限バンドとしきい値でロジックを反映します。
  5. 注文実行とエグジット

    • トリガーが発動すると、サイズVolume(デフォルト:0.1ロット)の成行注文が出されます。
    • ストップロスとテイクプロフィット価格はアクティブなトリガーの設定されたpip距離(StopLoss*XTakeProfit*X)からインストゥルメントのpipサイズヒューリスティックを使用して導出されます(5桁と3桁のシンボルは10倍スケーリングを受けます)。
    • 保護エグジットは次のM15ローソク足でシミュレートされます:ローソク足の高値/安値がストップまたはテイクプロフィットレベルに触れると、戦略はポジションを成行注文で閉じ、保護価格をリセットします。これはストップ注文に依存していたMT5の動作を模倣します。

パラメーター

パラメーター 説明 デフォルト
Volume ロット単位のトレードボリューム。 0.1
TriggerOne 固定RSIトリガーを有効にします。 true
TriggerTwo 適応型RSIトリガーを有効にします(トリガー1と相互排他)。 false
BbSpreadH4Min1 トリガー1のH4ボリンジャー最小スプレッド(pips)。 84
BbSpreadM15Max1 トリガー1のM15ボリンジャー最大スプレッド(pips)。 64
RsiPeriod1 すべての時間軸でトリガー1が使用するRSI長。 10
RsiLoM15_1, RsiHiM15_1 M15のRSIしきい値。 24, 66
RsiLoH1_1, RsiHiH1_1 H1のRSIしきい値。 34, 54
RsiLoH4_1, RsiHiH4_1 H4のRSIしきい値。 48, 56
RsiLoLim*, RsiHiLim* 極端なRSI読み取りをブロックするための安全リミット。 20–92
RDeltaM15Lim1 トリガー1のM15での最小RSI傾き。 -3.5
StocLoM15_1, StocHiM15_1 トリガー1のストキャスティクス境界。 26, 64
BbSpreadH4Min2 トリガー2のH4ボリンジャー最小スプレッド(pips)。 65
BbSpreadM15Max2 トリガー2のM15ボリンジャー最大スプレッド(pips)。 75
RsiPeriod2 トリガー2が使用するRSI長。 20
NumRsi RSI統計のサンプルサイズ。 60
Rsi*M*Sigma2 主要適応バンドの乗数(M15/H1/H4)。 1.20 / 0.95 / 0.9
Rsi*M*SigmaLim2 外部リミットの乗数(M15/H1/H4)。 1.85 / 2.55 / 2.7
RDeltaM15Lim2 トリガー2のM15での最小RSI傾き。 -5.5
StocLoM15_2, StocHiM15_2 トリガー2のストキャスティクス境界。 24, 68
TakeProfitBuy1, StopLossBuy1 トリガー1ロングの保護距離(pips)。 150, 70
TakeProfitSell1, StopLossSell1 トリガー1ショートの保護距離(pips)。 70, 35
TakeProfitBuy2, StopLossBuy2 トリガー2ロングの保護距離(pips)。 140, 35
TakeProfitSell2, StopLossSell2 トリガー2ショートの保護距離(pips)。 60, 30
AtrPeriod H4 ATR計算期間。 60
BollingerPeriod M15とH4でのBollinger Bands長。 20
AtrLimit エントリーを許可する最大ATR(pips)。 90
EntryHour セッション開始時間(0–23)。 0
OpenHours セッションの長さ(時間)(0 = 1時間)。 14
NumPositions 最大同時純ポジション数(戦略はフラット時のみ開きます)。 1
FridayEndHour 取引が停止する金曜日の時間。 4
StochasticK, StochasticD, StochasticSlowing ストキャスティクスオシレーターのパラメーター。 12 / 5 / 5
M15CandleType, H1CandleType, H4CandleType 各時間軸のローソク足データタイプ。 15m / 1h / 4h

ノート

  • オリジナルEAの保護ストップロスとテイクプロフィット注文は、M15ローソク足の高値/安値を監視することでエミュレートされます。インタバーのティック精度が必要な場合は、低レベルAPIを通じてストップ注文を追加することを検討してください。
  • ポートフォリオがすべてのリクエストされた時間軸へのアクセスを提供していることを確認してください。そうでなければ、トリガーキューが形成されず、戦略はアイドル状態のままになります。
  • pipサイズのヒューリスティックは一般的なMetaTraderの慣習に従います:5桁(またはJPYクロスの場合は3桁)のシンボルは取引所のPriceStepを10倍します。
namespace StockSharp.Samples.Strategies;

using System;

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

/// <summary>
/// RSI Bollinger Bands strategy.
/// Buys when RSI is oversold and price is near the lower Bollinger Band.
/// Sells when RSI is overbought and price is near the upper Bollinger Band.
/// </summary>
public class RsiBollingerBandsEaStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _rsiPeriod;
	private readonly StrategyParam<int> _bbPeriod;
	private readonly StrategyParam<decimal> _rsiOversold;
	private readonly StrategyParam<decimal> _rsiOverbought;

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

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

	public int BbPeriod
	{
		get => _bbPeriod.Value;
		set => _bbPeriod.Value = value;
	}

	public decimal RsiOversold
	{
		get => _rsiOversold.Value;
		set => _rsiOversold.Value = value;
	}

	public decimal RsiOverbought
	{
		get => _rsiOverbought.Value;
		set => _rsiOverbought.Value = value;
	}

	public RsiBollingerBandsEaStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
			.SetDisplay("Candle Type", "Timeframe for strategy", "General");

		_rsiPeriod = Param(nameof(RsiPeriod), 14)
			.SetGreaterThanZero()
			.SetDisplay("RSI Period", "RSI length", "Indicators");

		_bbPeriod = Param(nameof(BbPeriod), 20)
			.SetGreaterThanZero()
			.SetDisplay("BB Period", "Bollinger Bands length", "Indicators");

		_rsiOversold = Param(nameof(RsiOversold), 35m)
			.SetDisplay("RSI Oversold", "Oversold level for buy signal", "Signals");

		_rsiOverbought = Param(nameof(RsiOverbought), 65m)
			.SetDisplay("RSI Overbought", "Overbought level for sell signal", "Signals");
	}

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);

		var rsi = new RelativeStrengthIndex { Length = RsiPeriod };
		var bb = new BollingerBands { Length = BbPeriod, Width = 2m };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.BindEx(rsi, bb, (ICandleMessage candle, IIndicatorValue rsiValue, IIndicatorValue bbValue) =>
			{
				if (candle.State != CandleStates.Finished)
					return;

				if (!IsFormedAndOnlineAndAllowTrading())
					return;

				var rsiVal = rsiValue.ToDecimal();
				var bbTyped = (BollingerBandsValue)bbValue;
				var bbUpper = bbTyped.UpBand;
				var bbLower = bbTyped.LowBand;

				// Buy when RSI is oversold and price near lower band
				if (rsiVal < RsiOversold && candle.ClosePrice <= bbLower && Position <= 0)
				{
					BuyMarket();
				}
				// Sell when RSI is overbought and price near upper band
				else if (rsiVal > RsiOverbought && candle.ClosePrice >= bbUpper && Position >= 0)
				{
					SellMarket();
				}
			})
			.Start();

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