GitHub で見る

Two MA One RSI戦略

この戦略はMetaTrader 5エキスパート「Two MA one RSI」をStockSharpに移植します。高速と低速の移動平均クロスオーバーを前の閉じたロウソク足で評価したRSI確認と組み合わせます。柔軟なスイッチにより各比較を「より大きい」または「より小さい」ルールに変換でき、コードを変更せずに設定を反転させることができます。

詳細

  • エントリー条件
    • ロングシグナルは、高速MAが2バー前に低速MAより下にあり、最新の閉じたバーで高速MAが低速MAより上にあり、前のバーのRSIが上部閾値より上であることを必要とします。各比較はブール値パラメーターで反転できます。
    • ショートシグナルはロジックを反映し、反対のMA関係とRSIが下部閾値を下回っていることを確認します。
    • 両MAは同じ平均化タイプを使用します;遅い期間は常にFastMaPeriod * SlowPeriodMultiplierです。オプションの水平シフトはインジケーター値を数ロウソク足前に読み取るMT5の動作を再現します。
  • ロング/ショート:戦略は両方向にポジションを開くことができます。CloseOppositePositionsは新しいシグナルが入場前に反対側を強制決済するかどうかを制御します。
  • エグジット条件
    • pipで設定可能なストップロスとテイクプロフィット。
    • オプションのトレーリングストップ。価格がエントリーを超えて少なくともTrailingStopPips + TrailingStepPips進んだ後にのみ移動します。
    • ProfitCloseは浮動P&L(インジケーターのステップ価格を使用)を監視し、目標通貨額に達すると全ポジションを決済します。
  • ストップStopLossPipsがゼロの場合、戦略はトレーリングストップモジュールのみに依存します(有効な場合)。TrailingStopPipsは正のTrailingStepPipsを必要とし、元のエキスパートの検証に一致します。
  • デフォルト値
    • FastMaPeriod = 10SlowPeriodMultiplier = 2
    • FastMaShift = 3SlowMaShift = 0
    • RsiPeriod = 10RsiUpperLevel = 70RsiLowerLevel = 30
    • StopLossPips = 50TakeProfitPips = 150TrailingStopPips = 15TrailingStepPips = 5
    • MaxPositions = 10ProfitClose = 100TradeVolume = 1
  • フィルター:6つのブールスイッチ(BuyPreviousFastBelowSlowBuyCurrentFastAboveSlowBuyRequiresRsiAboveUpperSellPreviousFastAboveSlowSellCurrentFastBelowSlowSellRequiresRsiBelowLower)によりユーザーが各比較の意味を即座に変更できます。

パラメーター

名前 説明
CandleType 分析に使用する時間軸(またはその他のロウソク足タイプ)。
MaType 移動平均のファミリー(単純、指数、平滑化、加重、出来高加重)。
FastMaPeriod 高速MAの期間。
SlowPeriodMultiplier 低速MAの期間乗数(低速 = 高速 * 乗数)。
FastMaShiftSlowMaShift MA値評価時に適用するロウソク足での水平シフト。
RsiPeriod RSIの長さ(前の完了したロウソク足を使用)。
RsiUpperLevelRsiLowerLevel ロングとショートの確認のためのRSI閾値。
BuyPreviousFastBelowSlowBuyCurrentFastAboveSlowBuyRequiresRsiAboveUpper ロングシグナルの比較を切り替え。
SellPreviousFastAboveSlowSellCurrentFastBelowSlowSellRequiresRsiBelowLower ショートシグナルの比較を切り替え。
StopLossPipsTakeProfitPips pipで測定した保護ストップとターゲット(pip サイズは銘柄の価格ステップから導出)。
TrailingStopPipsTrailingStepPips トレーリングストップ距離と最小改善値。
MaxPositions 方向ごとの同時エントリーの最大数(0 = 無制限)。
ProfitClose 達成時に全ポジションを決済する通貨利益目標。
CloseOppositePositions 新しいトレードを開く前に反対側を決済するかどうか。
TradeVolume 基本注文サイズ;戦略のVolumeプロパティとも同期します。

実装メモ

  • すべての決定は完了したロウソク足のみを使用し、MT5エキスパートの「新しいバー」ロジックに一致します。
  • pip サイズはインジケーターの価格ステップに等しくなります。市場が分数pip価格を使用する場合、元のエキスパートのdigits_adjustロジックに一致するよう銘柄設定を適宜調整してください。
  • トレーリングストップは価格がTrailingStopPips + TrailingStepPips進んだ後にのみ開始します;ストップは終値からTrailingStopPips離れたところに固定され、少なくともTrailingStepPips改善された場合にのみ移動します。
  • ProfitCloseは銘柄のPriceStepStepPriceを使用して浮動利益を計算します。正確な通貨結果のためにそれらのフィールドが設定されていることを確認してください。
using System;
using System.Collections.Generic;

using Ecng.Common;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// Two MA one RSI strategy (simplified).
/// EMA crossover filtered by RSI levels.
/// </summary>
public class TwoMaOneRsiStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _fastPeriod;
	private readonly StrategyParam<int> _slowPeriod;
	private readonly StrategyParam<int> _rsiPeriod;

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

	public int FastPeriod
	{
		get => _fastPeriod.Value;
		set => _fastPeriod.Value = value;
	}

	public int SlowPeriod
	{
		get => _slowPeriod.Value;
		set => _slowPeriod.Value = value;
	}

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

	public TwoMaOneRsiStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame())
			.SetDisplay("Candle Type", "Candles", "General");

		_fastPeriod = Param(nameof(FastPeriod), 10)
			.SetGreaterThanZero()
			.SetDisplay("Fast Period", "Fast EMA", "Indicators");

		_slowPeriod = Param(nameof(SlowPeriod), 30)
			.SetGreaterThanZero()
			.SetDisplay("Slow Period", "Slow EMA", "Indicators");

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

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

		var fast = new ExponentialMovingAverage { Length = FastPeriod };
		var slow = new ExponentialMovingAverage { Length = SlowPeriod };
		var rsi = new RelativeStrengthIndex { Length = RsiPeriod };

		decimal prevFast = 0, prevSlow = 0;
		bool hasPrev = false;

		var subscription = SubscribeCandles(CandleType);
		// Use Bind with fast, slow - RSI computed separately via cross-feed
		subscription
			.Bind(fast, slow, (ICandleMessage candle, decimal fastValue, decimal slowValue) =>
			{
				if (candle.State != CandleStates.Finished)
					return;

				if (!hasPrev)
				{
					prevFast = fastValue;
					prevSlow = slowValue;
					hasPrev = true;
					return;
				}

				if (!IsFormedAndOnlineAndAllowTrading())
				{
					prevFast = fastValue;
					prevSlow = slowValue;
					return;
				}

				// Golden cross + RSI not overbought
				if (prevFast <= prevSlow && fastValue > slowValue && Position <= 0)
				{
					BuyMarket();
				}
				// Death cross + RSI not oversold
				else if (prevFast >= prevSlow && fastValue < slowValue && Position >= 0)
				{
					SellMarket();
				}

				prevFast = fastValue;
				prevSlow = slowValue;
			})
			.Start();

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