GitHub で見る

ローソク足シャドウ V1戦略

概要

ローソク足シャドウ V1はStockSharpの高レベルAPI内でオリジナルのMetaTraderエキスパートアドバイザーロジックを再現する価格行動リバーサル戦略です。システムは設定可能な取引セッション中に強い支配的なヒゲと最小限の反対側の影を持つローソク足を探します。トレードはバーの最初の数分間のみ許可されており、閉じたローソク足で機能し続けながらMQLバージョンのイントラバー実行をエミュレートします。

取引ロジック

  1. 設定された時間軸のローソク足(デフォルト5分)をサブスクライブし、完了したバーのみを評価します。
  2. StartHourEndHourパラメーターを使用してセッションウィンドウを適用します。ローソク足がウィンドウ外で開いた場合、取引は考慮されません。
  3. ローソク足が開いた時刻からOpenWithinMinutesより前に閉じた場合にのみエントリーを許可し、長いバーでの遅いシグナルを防ぎます。
  4. ロングセットアップ:ローソク足はCandleSizeMinPipsピップより大きい下ヒゲを印刷し、上影はOppositeShadowMaxPipsピップ以内でなければなりません。条件が満たされ、オープンポジションがない場合、成行買いが送られます。
  5. ショートセットアップ:ローソク足はCandleSizeMinPipsピップより大きい上ヒゲを印刷し、下影はOppositeShadowMaxPipsピップ以内でなければなりません。口座がフラットであれば成行売りが発行されます。
  6. ローソク足1本につき1トレードのみが許可され、元の「バー当たり1注文」制約に一致します。

ポジション管理

  • 初期保護距離はピップで表され、各インストゥルメントのPipValueパラメーターを通じて変換されます。
  • ハードなストップロスとテイクプロフィットのチェックは完了した各ローソク足で行われます。ローソク足の高値/安値が閾値に触れると、ポジションはフラット化されます。
  • トレーリング管理はMQLのトレーリングストップを模倣します:価格が少なくともTrailingStopPips + TrailingStepPips進んだら、ストップはTrailingStepPipsピップの増分で移動されます。
  • ポジションがPositionLivesBarsバー以上オープンのままである場合、即座にクローズされます。利益のあるトレードも利益を確保するためにCloseProfitsOnBarバー後に強制的に退出させられます。
  • 次のトレードボリュームは、前のトレードが損失でクローズされるたびにBaseVolumeLossReductionFactorで割ることで削減されます(元のエキスパートアドバイザーのロット削減と同様)。

パラメーター

名前 説明 デフォルト
PipValue ピップ距離を価格オフセットに変換するために使用される1ピップの金銭的価値。 0.0001
StopLossPips ピップ単位のストップロス距離。ハードストップを無効にするには0に設定。 50
TakeProfitPips ピップ単位のテイクプロフィット距離。ハードターゲットを無効にするには0に設定。 50
TrailingStopPips ピップ単位のトレーリングストップ距離。0のときトレーリングは適用されません。 15
TrailingStepPips トレーリングストップ調整間の最小ステップ(ピップ)。トレーリングが有効な場合は正でなければなりません。 5
PositionLivesBars ポジションが強制的にクローズされる前にオープンのままでいられる完了バーの最大数。 4
CloseProfitsOnBar ゼロより大きい場合、利益のあるポジションはエントリーからこの数のバー後にクローズされます。 2
OpenWithinMinutes 新しいトレードが許可されるバー開始後の最大分数。 7
CandleSizeMinPips ローソク足の支配側に必要なヒゲの長さ(ピップ)。 15
OppositeShadowMaxPips 反対側のローソク足の影の最大サイズ(ピップ)。 1
StartHour 取引所時間でのセッション開始時間(0–23)。 6
EndHour 取引所時間でのセッション終了時間(0–23)。 18
LossReductionFactor 負けトレードの後にBaseVolumeに適用される除数。 1.5
BaseVolume エントリーに使用されるデフォルトの成行注文サイズ。 1
CandleType 計算に使用されるローソク足シリーズ。デフォルトは5分時間軸。 5 min

注意事項

  • 常にPipValueをインストゥルメントのティックサイズに合わせて調整してください(例えばJPYクロスには0.01、インデックス先物には1)。
  • 戦略は完了したローソク足で機能するため、実行はバーのクローズで発生します。低い時間軸(1–5分)が元のエキスパートアドバイザーのイントラバー動作を最もよく複製します。
  • 外部インジケーターは必要なく、戦略をあらゆるStockSharpデータソースで簡単に実行できます。
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>
/// Candle Shadows V1 strategy (simplified). Detects candles with long shadows
/// (wicks) relative to body as reversal signals, filtered by EMA trend.
/// </summary>
public class CandleShadowsV1Strategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _emaLength;
	private readonly StrategyParam<decimal> _shadowRatio;

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

	public int EmaLength
	{
		get => _emaLength.Value;
		set => _emaLength.Value = value;
	}

	public decimal ShadowRatio
	{
		get => _shadowRatio.Value;
		set => _shadowRatio.Value = value;
	}

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

		_emaLength = Param(nameof(EmaLength), 30)
			.SetGreaterThanZero()
			.SetDisplay("EMA Length", "Trend EMA period", "Indicators");

		_shadowRatio = Param(nameof(ShadowRatio), 3m)
			.SetDisplay("Shadow Ratio", "Min shadow/body ratio", "Logic");
	}

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

		var ema = new ExponentialMovingAverage { Length = EmaLength };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(ema, (ICandleMessage candle, decimal emaValue) =>
			{
				if (candle.State != CandleStates.Finished)
					return;

				if (!IsFormedAndOnlineAndAllowTrading())
					return;

				var close = candle.ClosePrice;
				var open = candle.OpenPrice;
				var high = candle.HighPrice;
				var low = candle.LowPrice;

				var body = Math.Abs(close - open);
				if (body <= 0) return;

				var upperShadow = high - Math.Max(close, open);
				var lowerShadow = Math.Min(close, open) - low;

				// Long lower shadow (hammer) near EMA => buy signal
				if (lowerShadow > body * ShadowRatio && close > emaValue && Position <= 0)
					BuyMarket();
				// Long upper shadow (shooting star) near EMA => sell signal
				else if (upperShadow > body * ShadowRatio && close < emaValue && Position >= 0)
					SellMarket();
			})
			.Start();

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