GitHub で見る

ハンマーと吊るされた男、CCI 確認付き

この戦略は、StockSharp の MetaTrader「AH HM CCI」エキスパートを再実装します。ハンマーと吊るされた男の燭台を監視します パターンがあり、取引を開始する前に商品チャネル指数 (CCI) からの確認が必要です。追加の確認フィルター 弱いパターンを見つけ出し、CCI によって通知された勢いの変化にエントリーを合わせるのに役立ちます。

このロジックは完了したローソク足でのみ実行され、短い単純移動平均 (SMA) を使用して一般的なトレンドを定義します。前回の ローソク足は、買うには売られすぎている下降トレンドのハンマー、または売るには買われすぎている上昇トレンドのぶら下がっている男でなければなりません。出口 CCI が構成可能なトリガー レベルを超えたときに管理され、元のエキスパートからの投票ベースの終了ロジックが複製されます。

取引ロジック

  1. トレンド フィルター – 前のローソク足の中間点は、計算された SMA より下 (ロングの場合) または上 (ショートの場合) である必要があります。 終値。これは、元のウィザードの移動平均トレンド チェックを模倣しています。
  2. パターン検出 – この戦略は前のバーを評価し、以下をチェックします。
    • 実体全体がローソク足レンジの上位3分の1に入っている。
    • 前のローソク足の始値/終値とその前のローソク足の間のギャップ。
    • 方向性のコンテキスト (下降トレンドの場合はハンマー、上昇トレンドの場合はハンギングマン)。
  3. CCI の確認 – 前のバーの CCI は長いしきい値を下回るか、短いしきい値を上回る必要があります。デフォルト値 MetaTrader テンプレートと一致します (ロングの場合は 40、ショートの場合は 60)。
  4. ポジションの決済 – CCI が下限または上限の決済しきい値を超えると、既存のポジションが決済されます。からの交差点 以下はロングを閉じます。上からクロスするとショーツが閉じます。

パラメーター

名前 説明 デフォルト
CandleType パターン認識に使用されるローソクの種類と時間枠。 TimeSpan.FromMinutes(15)
CciPeriod 商品チャネル指数で使用されるバーの数。 11
MaPeriod SMA トレンド フィルター内のバーの数。 5
LongConfirmationThreshold ハンマー信号に許可される最大 CCI 値。 40
ShortConfirmationThreshold ぶら下がりマン信号に許可される最小値は CCI です。 60
ExitUpperThreshold CCI レベルは上向きのクロスの後に出口をトリガーします。 70
ExitLowerThreshold 初期信号の二次出口レベル。 30

すべてのパラメータを最適化に使用できます。しきい値は負の値を受け入れるため、戦略を他の値に適応させることができます。 フィルターを締めたり緩めたりして、市場やノイズレベルを調整します。

注文管理

  • エントリーでは、Volume + |Position| のサイズの成行注文が使用され、1 回の取引で反転が確実に実行されます。
  • Exits は、MetaTrader の専門家に近づき続けるために、純粋に CCI のクロスに依存しています。必要に応じて、StartProtection 呼び出しを追加します 明示的なストップロスまたはテイクプロフィットレベル。

使用のヒント

  • ローソク足のギャップとテールが有益な流動的な商品に戦略を適用します。
  • より長い時間枠でトレードする際のノイズを平滑化するには、より長い CciPeriodMaPeriod の値を試してください。
  • LongConfirmationThreshold を下げるか、ShortConfirmationThreshold を上げると、取引数は減りますが改善されます。 選択性。
namespace StockSharp.Samples.Strategies;

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

/// <summary>
/// Hammer/Hanging Man + CCI strategy.
/// Buys on hammer with negative CCI, sells on hanging man with positive CCI.
/// </summary>
public class HammerHangingManCciStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _cciPeriod;
	private readonly StrategyParam<decimal> _cciLevel;
	private readonly StrategyParam<int> _signalCooldownCandles;
	private int _candlesSinceTrade;

	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
	public int CciPeriod { get => _cciPeriod.Value; set => _cciPeriod.Value = value; }
	public decimal CciLevel { get => _cciLevel.Value; set => _cciLevel.Value = value; }
	public int SignalCooldownCandles { get => _signalCooldownCandles.Value; set => _signalCooldownCandles.Value = value; }

	public HammerHangingManCciStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(60).TimeFrame())
			.SetDisplay("Candle Type", "Candle timeframe", "General");
		_cciPeriod = Param(nameof(CciPeriod), 14)
			.SetGreaterThanZero()
			.SetDisplay("CCI Period", "CCI period", "Indicators");
		_cciLevel = Param(nameof(CciLevel), 100m)
			.SetDisplay("CCI Level", "CCI threshold", "Signals");
		_signalCooldownCandles = Param(nameof(SignalCooldownCandles), 6)
			.SetGreaterThanZero()
			.SetDisplay("Signal Cooldown", "Bars to wait between trades", "Trading");
	}

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

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_candlesSinceTrade = SignalCooldownCandles;
		var cci = new CommodityChannelIndex { Length = CciPeriod };
		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(cci, ProcessCandle).Start();
	}

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

		if (_candlesSinceTrade < SignalCooldownCandles)
			_candlesSinceTrade++;

		var body = Math.Abs(candle.ClosePrice - candle.OpenPrice);
		var range = candle.HighPrice - candle.LowPrice;
		if (range <= 0 || body <= 0) return;

		var upperShadow = candle.HighPrice - Math.Max(candle.OpenPrice, candle.ClosePrice);
		var lowerShadow = Math.Min(candle.OpenPrice, candle.ClosePrice) - candle.LowPrice;

		var isHammer = lowerShadow > body * 2.5m && upperShadow < body * 0.5m;
		var isHangingMan = upperShadow > body * 2.5m && lowerShadow < body * 0.5m;

		if (isHammer && cciValue < -CciLevel && Position <= 0 && _candlesSinceTrade >= SignalCooldownCandles)
		{
			BuyMarket();
			_candlesSinceTrade = 0;
		}
		else if (isHangingMan && cciValue > CciLevel && Position >= 0 && _candlesSinceTrade >= SignalCooldownCandles)
		{
			SellMarket();
			_candlesSinceTrade = 0;
		}
	}
}