GitHub で見る

DT RSI EXP1 戦略

このポートは、MT4 エキスパート アドバイザ DT-RSI-EXP1 を複製します。この戦略は 15 分間の RSI スイングをスキャンして、60/40 レベル付近のダブルトップまたはダブルボトムを検出します。最近の RSI のピークが 40 を下回る谷を表示せずに引き戻し、4 時間のトレンド フィルターが下向きになった場合、ロングトレードが行われます。ショートは、60 を超える谷と上昇トレンド フィルターを備えたロジックを反映しています。固定のストップロスとテイクプロフィットがすべてのポジションに付加され、オプションのトレーリングストップが利益を保護します。 RSI が極端な 70/30 レベルに達すると、ポジションは強制的にクローズされ、元の決済動作がコピーされます。

詳細

  • エントリー基準:
    • ロング: 2 つの強気の RSI のピークがあり、2 番目のピークは 60 を超え、その間に 40 を下回る弱気の谷はない、4 時間足の EMA は前終値を下回っており、RSI(1) は予想ネックラインを上回っており、RSI(2) はまだ下にあり、RSI(2) < 50、およびRSI(0) < 55。
    • ショート: RSIの弱気の谷が2つあり、2番目の谷が40未満、間に60を超える強気の山がない、4時間足のEMAが前終値を上回っている、RSI(1)が予想ネックラインを下回っている、RSI(2) > 50およびRSI(0) > 47。
  • ロング/ショート: 両方向。
  • 終了基準:
    • RSI の極値 (ロングの場合は RSI > 70、ショートの場合は RSI < 30)。
    • 価格ステップから計算されたストップロス/テイクプロフィットターゲット。
    • 価格が TrailingStopPoints だけ変動すると利益を固定するオプションのトレーリング ストップ。
  • ストップ: 固定ストップロスとテイクプロフィット、オプションのトレーリングストップ。
  • デフォルト値:
    • CandleType = 15 分のキャンドル。
    • TrendCandleType = 240 分足のローソク足 (トレンド フィルター EMA)。
    • RsiPeriod = 47。
    • StopLossPoints = 26。
    • TakeProfitPoints = 76。
    • TrailingStopPoints = 0 (無効)。
  • フィルター:
    • カテゴリ: RSI 構造のトレンドフォローエントリー。
    • 方向性:両方。
    • インジケーター: RSI、EMA トレンド フィルター。
    • 停止: はい。
    • 複雑さ: 中 (複数の制約のスイング検出)。
    • 時間枠: 日中 (H4 フィルターを使用した M15)。
    • 季節性:いいえ。
    • ニューラルネットワーク: いいえ。
    • ダイバージェンス: いいえ。
    • リスクレベル:中。

パラメーター

名前 デフォルト 説明 最適化可能
CandleType 15分 RSI とシグナルの計算に使用される主なローソク足シリーズ。 はい
TrendCandleType 240分 EMA トレンド フィルターで使用されるより高いタイムフレーム (MT4 RFTL インジケーターの代替)。 はい
RsiPeriod 47 RSI の長さが主ローソク足に適用されます。 はい
StopLossPoints 26 価格ステップにおけるストップロスまでの距離。 はい
TakeProfitPoints 76 価格ステップにおける利食いまでの距離。 はい
TrailingStopPoints 0 価格ステップ内のトレーリングストップのオフセット (0 はトレーリングを無効にします)。 はい

注意事項

  • MetaTrader RFTL カスタム インジケーターは、240 分の時間枠で 10 期間の EMA で近似されます。元の環境に合わせて、より長い時間枠または EMA の長さを調整してください。
  • ポイントベースのストップがブローカーのティック サイズと一致するように、商品の PriceStepStepPrice が設定されていることを確認します。
  • トレーリングストップは、価格がエントリー価格から TrailingStopPoints を超えて進んだ場合にのみ有効になり、元のストップを超えて緩むことはありません。
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>
/// DT RSI EXP1 strategy - RSI overbought/oversold with EMA trend filter.
/// Buys when RSI crosses above oversold level while above EMA trend.
/// Sells when RSI crosses below overbought level while below EMA trend.
/// </summary>
public class DtRsiExp1Strategy : Strategy
{
	private readonly StrategyParam<int> _rsiPeriod;
	private readonly StrategyParam<int> _emaPeriod;
	private readonly StrategyParam<decimal> _oversold;
	private readonly StrategyParam<decimal> _overbought;
	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 Oversold { get => _oversold.Value; set => _oversold.Value = value; }
	public decimal Overbought { get => _overbought.Value; set => _overbought.Value = value; }
	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }

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

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

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

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

		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).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();

		StartProtection(
			takeProfit: new Unit(2, UnitTypes.Percent),
			stopLoss: new Unit(1, UnitTypes.Percent)
		);
	}

	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 above oversold + bullish trend
		if (_prevRsi <= Oversold && rsi > Oversold && close > ema && Position == 0)
		{
			BuyMarket();
		}
		// RSI crosses below overbought + bearish trend
		else if (_prevRsi >= Overbought && rsi < Overbought && close < ema && Position == 0)
		{
			SellMarket();
		}

		_prevRsi = rsi;
	}
}