GitHub で見る

三人の兵士 Stochastic の戦略

この戦略は、古典的な 3 ローソク足反転パターンと Stochastic オシレーターの確認を組み合わせた、MetaTrader のエキスパート Expert_ABC_WS_Stoch.mq5 を再現します。ロングシグナルは売られ過ぎのStochasticシグナルラインと強気の「スリーホワイトソルジャー」フォーメーションを必要とし、ショートシグナルは買われ過ぎのStochasticによって確認される弱気の「スリーブラッククロウズ」に依存します。イグジットロジックは、設定可能なバンドを介してポジションを閉じるまでの信号ラインのクロスオーバーを監視します。

取引ロジック

  1. パターン検出
    • 最新の 3 つの完了したキャンドルを追跡します。
    • 3 本のローソク足がすべて強気で、それぞれの終値が前のローソク足よりも高い場合、3 人の白い兵士 を識別します。
    • 3 つのローソク足がすべて弱気で、それぞれの終値が前の終値よりも低い場合、3 つの黒いカラス を特定します。
  2. 発振器の確認
    • 元のエキスパートと同じ %K%D、および Slowing 周期 (デフォルトでは 47、9、13) を使用して Stochastic オシレーターを計算します。
    • 確認として信号線 (%D) を使用します。
      • 以前のシグナルラインの値が売られすぎのしきい値(デフォルトは 30)を下回っている場合は、long を入力します。
      • 以前のシグナルラインの値が買われすぎのしきい値(デフォルトは 70)を超えている場合は、short を入力します。
  3. 終了条件
    • シグナルラインが下限または上限の終了しきい値 (デフォルトは 20 および 80) を上回ったときにロング取引を終了します。
    • シグナルラインがこれらのしきい値を下回ったときにショートトレードを終了します。
    • どちらの出口チェックも、以前とその前前の信号線の値に基づいて、本物のクロスオーバーを検出します。

パラメーター

名前 デフォルト 説明
CandleType 1h 時間枠 キャンドルのサブスクリプションの期間。
StochKPeriod 47 %K のルックバック期間。
StochDPeriod 9 信号線の移動平均の長さ。
StochSlowing 13 追加の平滑化が %K に適用されました。
OversoldLevel 30 ロングエントリーを確認するために必要な信号線レベル。
OverboughtLevel 70 ショートエントリーを確認するために必要な信号線レベル。
ExitLowerLevel 20 長い出口クロスオーバーに使用される下限。
ExitUpperLevel 80 短い出口クロスオーバーに使用される上限。

すべての数値パラメータは、MetaTrader テンプレートに一致する最適化範囲をサポートしているため、Strategy Designer を通じて動作を微調整できます。

注文管理

  • この戦略は、反対のシグナルが現れたときに、現在位置の絶対サイズを設定された Volume に加算することによって位置を反転します。
  • StartProtection() はプラットフォームのリスク管理と統合することができますが、デフォルトでは明示的なストップロスまたはテイクプロフィットのレベルは適用されません。

可視化

Strategy Designer 内で実行すると、戦略は以下を描画します。

  • 選択したシンボルと時間枠のローソク足の価格。
  • 構成された Stochastic オシレーター。
  • マーカーをトレードしてエントリーとエグジットを強調表示します。

使用上の注意

  • 信号を期待する前に、Stochastic 発振器がウォームアップするのに十分な履歴が機器に提供されていることを確認します。
  • ライブでデプロイする場合は、戦略を追加のリスク フィルター (ボラティリティ、セッション フィルターなど) と組み合わせることを検討してください。
  • しきい値はパラメーターとして公開されるため、コードを編集することなく、さまざまな確認バンドでの迅速な実験が可能になります。
namespace StockSharp.Samples.Strategies;

using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;

/// <summary>
/// Three Soldiers Stochastic strategy: detects three consecutive bullish/bearish candles
/// confirmed by RSI levels.
/// </summary>
public class ThreeSoldiersStochasticStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _rsiPeriod;
	private readonly StrategyParam<int> _signalCooldownCandles;

	private int _bullCount;
	private int _bearCount;
	private int _candlesSinceTrade;

	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
	public int RsiPeriod { get => _rsiPeriod.Value; set => _rsiPeriod.Value = value; }
	public int SignalCooldownCandles { get => _signalCooldownCandles.Value; set => _signalCooldownCandles.Value = value; }

	public ThreeSoldiersStochasticStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(60).TimeFrame())
			.SetDisplay("Candle Type", "Candle timeframe", "General");
		_rsiPeriod = Param(nameof(RsiPeriod), 14)
			.SetGreaterThanZero()
			.SetDisplay("RSI Period", "RSI period for confirmation", "Indicators");
		_signalCooldownCandles = Param(nameof(SignalCooldownCandles), 6)
			.SetGreaterThanZero()
			.SetDisplay("Signal Cooldown", "Bars to wait between trades", "Trading");
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_bullCount = 0;
		_bearCount = 0;
		_candlesSinceTrade = SignalCooldownCandles;
	}

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_bullCount = 0;
		_bearCount = 0;
		_candlesSinceTrade = SignalCooldownCandles;
		var rsi = new RelativeStrengthIndex { Length = RsiPeriod };
		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(rsi, ProcessCandle).Start();
	}

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

		if (_candlesSinceTrade < SignalCooldownCandles)
			_candlesSinceTrade++;

		if (candle.ClosePrice > candle.OpenPrice)
		{
			_bullCount++;
			_bearCount = 0;
		}
		else if (candle.ClosePrice < candle.OpenPrice)
		{
			_bearCount++;
			_bullCount = 0;
		}
		else
		{
			_bullCount = 0;
			_bearCount = 0;
		}

		if (_bullCount >= 3 && rsi < 65 && Position <= 0 && _candlesSinceTrade >= SignalCooldownCandles)
		{
			BuyMarket();
			_bullCount = 0;
			_candlesSinceTrade = 0;
		}
		else if (_bearCount >= 3 && rsi > 35 && Position >= 0 && _candlesSinceTrade >= SignalCooldownCandles)
		{
			SellMarket();
			_bearCount = 0;
			_candlesSinceTrade = 0;
		}
	}
}