Auf GitHub ansehen

Hammer hängend Stochastic

Diese Strategie portiert den MetaTrader-Experten „Expert_AH_HM_Stoch“ auf die StockSharp-Hochebene API. Es kombiniert Hammer- und Hängemann-Kerzenmuster mit der Bestätigung eines stochastischen Oszillators, um Umkehrsituationen nach längeren Bewegungen zu erfassen.

Die Strategie wartet auf eine abgeschlossene Kerze, bevor sie handelt, verwendet die stochastische Signallinie zum Filtern und schließt Positionen, wenn das Momentum die Extremzonen verlässt.

Einzelheiten

  • Eintrittskriterien:
    • Long: Bullische Hammerkerze und stochastischer %D (vorheriger Balken) unterhalb des überverkauften Niveaus.
    • Short: Bärische „Hanging Man“-Kerze und stochastischer %D (vorheriger Balken) über dem überkauften Niveau.
  • Lang/Kurz: Beides.
  • Ausstiegskriterien: Positionen schließen, wenn der stochastische %D über/unter konfigurierbare Erholungs- und Extremniveaus kreuzt.
  • Stoppt: Aktiviert über den integrierten StartProtection()-Hook (standardmäßig Schutz auf Kontoebene).
  • Standardwerte:
    • CandleType = TimeSpan.FromHours(1)
    • StochPeriodK = 15
    • StochPeriodD = 49
    • StochPeriodSlow = 25
    • OversoldLevel = 30
    • OverboughtLevel = 70
    • ExitLowerLevel = 20
    • ExitUpperLevel = 80
    • MaxBodyRatio = 0,35
    • LowerShadowMultiplier = 2,5
    • UpperShadowMultiplier = 0,3
  • Filter:
    • Kategorie: Muster + Oszillatorbestätigung
    • Richtung: Beide
    • Indikatoren: Candlestick, Stochastic
    • Stopps: Optionale Risikokontrollen über StartProtection
    • Komplexität: Mittelschwer
    • Zeitrahmen: Swing / Intraday (Standard: 1 Stunde)
    • Saisonalität: Nein
    • Neuronale Netze: Nein
    • Divergenz: Nein
    • Risikostufe: Moderat

Wie es funktioniert

  1. Abonniert die konfigurierte Kerzenserie und den stochastischen Oszillator mithilfe des High-Levels BindEx API.
  2. Erkennt Hammer- und Hängende-Mann-Formationen anhand des Körper- und Schattenverhältnisses.
  3. Bestätigt Eingaben mit der stochastischen %D-Linie unter Verwendung des vorherigen geschlossenen Balkenwerts.
  4. Verwaltet Exits, wenn die Stochastik die überverkauften/überkauften Zonen verlässt, und spiegelt die Logik des ursprünglichen MQL-Experten wider.
  5. Bietet Diagrammvisualisierung für Kerzen, stochastische und eigene Trades, wenn ein Diagrammbereich verfügbar ist.
namespace StockSharp.Samples.Strategies;

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

/// <summary>
/// Hammer/Hanging Man + Stochastic strategy.
/// Buys on hammer in oversold, sells on hanging man in overbought.
/// </summary>
public class HammerHangingStochasticStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _stochPeriod;
	private readonly StrategyParam<decimal> _oversold;
	private readonly StrategyParam<decimal> _overbought;

	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
	public int StochPeriod { get => _stochPeriod.Value; set => _stochPeriod.Value = value; }
	public decimal Oversold { get => _oversold.Value; set => _oversold.Value = value; }
	public decimal Overbought { get => _overbought.Value; set => _overbought.Value = value; }

	public HammerHangingStochasticStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
			.SetDisplay("Candle Type", "Candle timeframe", "General");
		_stochPeriod = Param(nameof(StochPeriod), 14)
			.SetGreaterThanZero()
			.SetDisplay("Stoch Period", "Stochastic K period", "Indicators");
		_oversold = Param(nameof(Oversold), 30m)
			.SetDisplay("Oversold", "Stochastic oversold level", "Signals");
		_overbought = Param(nameof(Overbought), 70m)
			.SetDisplay("Overbought", "Stochastic overbought level", "Signals");
	}

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		var stoch = new StochasticOscillator { K = { Length = StochPeriod }, D = { Length = 3 } };
		var subscription = SubscribeCandles(CandleType);
		subscription.BindEx(stoch, ProcessCandle).Start();
	}

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

		var stochTyped = stochValue as StochasticOscillatorValue;
		if (stochTyped?.K is not decimal kValue) return;

		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;

		// Hammer: small body at top, long lower shadow
		var isHammer = lowerShadow > body * 2 && upperShadow < body;

		// Hanging Man: small body at bottom, long upper shadow
		var isHangingMan = upperShadow > body * 2 && lowerShadow < body;

		if (isHammer && kValue < Oversold && Position <= 0)
			BuyMarket();
		else if (isHangingMan && kValue > Overbought && Position >= 0)
			SellMarket();
	}
}