GitHub で見る

Gselector パターンの確率戦略

概要

Gselector パターン確率 戦略は、MetaTrader 4「Gselector」エキスパートの StockSharp 移植です。複数のステップ サイズから構築された合成価格シリーズの方向変化を研究し、観察されたすべてのパターンの確率統計を保持し、継続的な動きの確率が十分に高い場合に取引します。ストップロスとテイクプロフィットの距離は、元の専門家の行動を反映するためにソフトウェアでシミュレートされます。

学習プロセス

  1. 合成ラダー – 設定されたデルタ マルチプルごとに、市場が必要な距離だけ移動するたびに最後の終値を記録することで、戦略はステップベースのシリーズを構築します。
  2. パターン エンコーディング – ラダー内の隣接する値のすべてのペアを比較することによってビット マスクが作成されます。上昇ステップはビット 0 を取得し、下降ステップはビット 1 を取得します。これは、MQL 実装からの Ncomb エンコーディングを再現します。
  3. イベント追跡 – 新しいパターンが出現すると、この戦略は設定されたストップ レベルごとにウォッチャーを開始します。ウォッチャーは元の価格を保存し、価格がしきい値によって上下するまで待ちます。
  4. 確率の更新 – ウォッチャーが完了すると、上向きの動きは「成長」統計を増加させ、下向きの動きは「衰退」統計を増やします。忘却係数は、元のエキスパートの減衰ロジック (forg) をエミュレートします。
  5. メモリ内の永続性 – すべての統計はメモリに保持され、戦略の開始時にリセットされ、ReadHistory が無効になっている場合の MQL バージョンの動作と一致します。

取引ロジック

  1. 継続確率は、各デルタ ラダーの現在のパターンに対して計算されます。
  2. 買いシグナルには以下が必要です。
    • 確率 ≥ ProbabilityThreshold
    • 観測値 ≥ MinSamples
    • 前回の購入からクールダウンが経過しました。
    • 売りポジションが存在する場合、新しい確率は、保存されている売り確率に ProbabilityBuffer を加えたものを超える必要があります。
  3. 売りシグナルは、成長と下落の役割を交換した買いルールを反映しています。
  4. エントリは、BuyMarket / SellMarket を使用して OrderSend をエミュレートします。反対のポジションがオープンしている場合、ストラテジーは最初にポジションをクローズし、エキスパートアドバイザーの反転動作を再現します。
  5. プロテクティブエグジットは内部で処理されます。ストップとテイクは、ポイント値とストップレベルから派生した価格単位で表されます。

パラメーター

名前 説明 デフォルト
CandleType バックテスト/ライブセッションに使用されるキャンドルデータタイプ。 1分の時間枠
ProbabilityThreshold 取引を開始するために必要な最小継続確率。 0.8
BaseDeltaPoints 最初の合成ラダーを定義する基点の距離。 1
DeltaSteps 評価するデルタラダーの数。 20
PatternLength ラダー履歴の要素の数。 10
StopLevels ストップ/テイクレベルの数。 1
StopDistancePoints ベースストップ/距離をポイントで表示します。 25
ForgetFactor 各観測後に成長/衰退カウンターに減衰が適用されます。 1.05
MinSamples 完了した観測の最小数。 10
ProbabilityBuffer 反対のポジションを決済するには追加の確率が必要です。 0.05
FixedVolume 基本取引高。 1ロット
UseReinvest バランス比例した音量調整が可能になります。 本当の
VolumeMode 0 – 固定、1 – 10k あたりのパーセント、2 – ラダー、3 – リニア。 1
PercentPer10k モード 1 での 10,000 ユニットあたりのパーセンテージ。 3
BaseDeposit モード 2 および 3 の基本デポジット。 500
DepositStep モード 2 および 3 の入金増分。 500
MaxVolume 最大ボリュームの上限。 10000
CooldownFactor 再アクティブ化のクールダウンとして使用されるキャンドル間隔の数。 2

MQL エキスパートとの違い

  • ファイルベースの永続性は削除されました。統計は戦略が開始されるたびに最初から再構築されます。
  • 注文は、MT4 未決注文の代わりに、BuyMarket/SellMarket とソフトウェアストップ管理を通じてシミュレートされます。
  • ポジションサイジングヘルパーは、StockSharp ポートフォリオ データに適応されました。株式価値が利用できない場合、戦略は固定ボリュームに戻ります。
  • MT4 バージョンでは適用されなかったため、元のコードからのトレーリング ストップ入力は無視されます。

使用上の注意

  • 有効な PriceStep を使用して戦略を証券に添付します。ステップが不明な場合、戦略は 0.0001 に戻ります。
  • 学習プロセスには最小限の数のラダーのアクティブ化が必要です。取引を開始する前にウォームアップ段階を期待してください。
  • DeltaSteps または PatternLength を増やすと、パターン ディクショナリが急速に増大するため、メモリ使用量が急激に増加します。
  • デフォルトの確率しきい値 (0.8) は非常に厳密です。より頻繁に取引する場合は、値を低くします。
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>
/// Gselector Pattern Probability strategy - SMA crossover with RSI filter.
/// Buys when fast SMA crosses above slow SMA and RSI is below overbought.
/// Sells when fast SMA crosses below slow SMA and RSI is above oversold.
/// </summary>
public class GselectorPatternProbabilityStrategy : Strategy
{
	private readonly StrategyParam<int> _fastPeriod;
	private readonly StrategyParam<int> _slowPeriod;
	private readonly StrategyParam<int> _rsiPeriod;
	private readonly StrategyParam<decimal> _overbought;
	private readonly StrategyParam<decimal> _oversold;
	private readonly StrategyParam<DataType> _candleType;

	private decimal _prevFast;
	private decimal _prevSlow;
	private bool _hasPrev;

	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 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 GselectorPatternProbabilityStrategy()
	{
		_fastPeriod = Param(nameof(FastPeriod), 10)
			.SetDisplay("Fast SMA", "Fast SMA period", "Indicators");

		_slowPeriod = Param(nameof(SlowPeriod), 30)
			.SetDisplay("Slow SMA", "Slow SMA period", "Indicators");

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

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

		_oversold = Param(nameof(Oversold), 25m)
			.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(); _prevFast = 0m; _prevSlow = 0m; _hasPrev = false; }

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

		_hasPrev = false;

		var fast = new SimpleMovingAverage { Length = FastPeriod };
		var slow = new SimpleMovingAverage { Length = SlowPeriod };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(fast, slow, ProcessCandle)
			.Start();
	}

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

		if (!_hasPrev)
		{
			_prevFast = fast;
			_prevSlow = slow;
			_hasPrev = true;
			return;
		}

		// Fast crosses above slow = buy
		if (_prevFast <= _prevSlow && fast > slow && Position <= 0)
		{
			if (Position < 0)
				BuyMarket();
			BuyMarket();
		}
		// Fast crosses below slow = sell
		else if (_prevFast >= _prevSlow && fast < slow && Position >= 0)
		{
			if (Position > 0)
				SellMarket();
			SellMarket();
		}

		_prevFast = fast;
		_prevSlow = slow;
	}
}