GitHub で見る

Exp Rj SlidingRangeRj Digit システム Tm Plus 戦略

概要

このStockSharp戦略はMetaTraderエキスパートアドバイザー Exp_Rj_SlidingRangeRj_Digit_System_Tm_Plus のポートです。カスタムチャンネルインジケーター Rj_SlidingRangeRj_Digit に基づくオリジナルのトレードロジックを再現し、設定可能なトレード管理オプションを保持しています。戦略は設定可能な時間軸での完成したローソク足を監視し、チャンネルを超えたブレイクアウトを検出し、遅延エントリー、オプションのタイマー決済、価格ベースのストップ/ターゲット管理でそれらのイベントに反応します。

インジケーターロジック

Rj_SlidingRangeRj_Digitインジケーターは多段階の平均化プロセスを使用してアダプティブ価格チャンネルを構築します:

  1. 上部バンドについては、UpCalcPeriodRange バーの最高高値が UpCalcPeriodShift バーずつシフトした直近の UpCalcPeriodRange スライディングウィンドウのそれぞれで計算されます。これらの最大値の平均が UpDigit で指定された精度に丸められます。
  2. 下部バンドは DnCalcPeriodRangeDnCalcPeriodShiftDnDigit を使用して安値に同じロジックを繰り返します。
  3. ローソク足の終値が上部バンドより上(色 2 / 3)または下部バンドより下(色 0 / 1)にある場合にブレイクアウトとしてラベル付けされます。チャンネル内のローソク足は中立色(4)を生成します。

戦略は完成したローソク足をストリームし、各更新でバンドを再構築し、MQL実装の CopyBuffer/SignalBar 動作を模倣するために最新のカラーコードを保存します。

トレードルール

  • エントリー遅延: シグナルは SignalBar で定義されたバー(デフォルトは1バー前)で評価されます。戦略はブレイクアウトカラーが現れ、前のバーが同じブレイクアウトカラーを持たない時まで待ちます。これはトレードを取る前のオリジナルの1バー遅延を再現します。
  • ロングエントリー: EnableBuyEntries で有効化。強気ブレイクアウト(色2 または 3)はロングポジションがオープンでない場合に市場買いを発動します(ショートエクスポージャーは自動的にネットアウト)。
  • ショートエントリー: EnableSellEntries で有効化。弱気ブレイクアウト(色0 または 1)はショートポジションがオープンでない場合に市場売りを発動します。
  • 決済シグナル:
    • EnableBuyExits が真の場合、弱気ブレイクアウトカラーでロングをクローズ。
    • EnableSellExits が真の場合、強気ブレイクアウトカラーでショートをクローズ。
    • オプションの時間ベース決済(UseTimeExit)は ExitMinutes より長く保持されたオープンポジションをクローズ。
    • ポイントで表されたオプションのストップロスとテイクプロフィットレベル(StopLossPointsTakeProfitPoints)は楽器の PriceStep を使用して価格オフセットに変換されます。

すべてのアクションは BuyMarket / SellMarket を使用するため、戦略は必要に応じてポジションを自動的に反転します。

パラメーター

パラメーター 説明 デフォルト値
CandleType シグナル検出に使用されるローソク足タイプ(時間軸)。 8時間ローソク足
EnableBuyEntries / EnableSellEntries ロング/ショートブレイクアウトエントリーを許可。 true
EnableBuyExits / EnableSellExits ロング/ショートのインジケーターベース決済を許可。 true
UseTimeExit 固定保持時間後に取引をクローズ。 true
ExitMinutes 分単位の保持時間制限。 1920
UpCalcPeriodRange, UpCalcPeriodShift, UpDigit 上部チャンネルバンドのパラメーター。 5, 0, 2
DnCalcPeriodRange, DnCalcPeriodShift, DnDigit 下部チャンネルバンドのパラメーター。 5, 0, 2
SignalBar ブレイクアウトシグナル評価に使用されるバーオフセット。 1
StopLossPoints, TakeProfitPoints 価格ポイントでのストップロス / テイクプロフィット(PriceStep で変換)。 1000, 2000

ポジションサイズを制御するために戦略の Volume プロパティを設定します。ストップロスとテイクプロフィットパラメーターはオプションです;いずれかの保護レベルを無効にするには 0 に設定してください。

注意事項

  • 戦略はスライディングチャンネルを形成するために十分な履歴を必要とします(約 max(shift + 2 × range) ローソク足)。内部バッファを自動的に管理し、十分なデータが利用可能になるまでシグナルを無視します。
  • 価格の丸めは10進数桁数を使用して実行され、MQLインジケーターの丸め動作を反映します。
  • プロジェクト指示に従いPython実装は意図的に省略されています;C#バージョンのみが提供されます。
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>
/// Sliding range breakout strategy using Highest/Lowest channel.
/// Enters on breakout above/below the channel, exits on opposite breakout.
/// </summary>
public class ExpRjSlidingRangeRjDigitSystemTmPlusStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _period;

	private decimal? _prevUpper;
	private decimal? _prevLower;

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

	public int Period
	{
		get => _period.Value;
		set => _period.Value = value;
	}

	public ExpRjSlidingRangeRjDigitSystemTmPlusStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
			.SetDisplay("Candle Type", "Timeframe", "General");

		_period = Param(nameof(Period), 10)
			.SetGreaterThanZero()
			.SetDisplay("Period", "Channel lookback", "Indicators");
	}

	public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
	{
		return [(Security, CandleType)];
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_prevUpper = null;
		_prevLower = null;
	}

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

		_prevUpper = null;
		_prevLower = null;

		var highest = new Highest { Length = Period };
		var lowest = new Lowest { Length = Period };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(highest, lowest, ProcessCandle)
			.Start();

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

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

		if (!IsFormedAndOnlineAndAllowTrading())
		{
			_prevUpper = upper;
			_prevLower = lower;
			return;
		}

		var close = candle.ClosePrice;

		if (_prevUpper == null || _prevLower == null)
		{
			_prevUpper = upper;
			_prevLower = lower;
			return;
		}

		// Breakout above previous upper → buy
		if (close > _prevUpper.Value && Position <= 0)
		{
			if (Position < 0)
				BuyMarket();
			BuyMarket();
		}
		// Breakdown below previous lower → sell
		else if (close < _prevLower.Value && Position >= 0)
		{
			if (Position > 0)
				SellMarket();
			SellMarket();
		}

		_prevUpper = upper;
		_prevLower = lower;
	}
}