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
Abonniert die konfigurierte Kerzenserie und den stochastischen Oszillator mithilfe des High-Levels BindEx API.
Erkennt Hammer- und Hängende-Mann-Formationen anhand des Körper- und Schattenverhältnisses.
Bestätigt Eingaben mit der stochastischen %D-Linie unter Verwendung des vorherigen geschlossenen Balkenwerts.
Verwaltet Exits, wenn die Stochastik die überverkauften/überkauften Zonen verlässt, und spiegelt die Logik des ursprünglichen MQL-Experten wider.
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();
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import StochasticOscillator
from StockSharp.Algo.Strategies import Strategy
class hammer_hanging_stochastic_strategy(Strategy):
"""
Hammer/Hanging Man + Stochastic strategy.
Buys on hammer candle in oversold stochastic.
Sells on hanging man candle in overbought stochastic.
"""
def __init__(self):
super(hammer_hanging_stochastic_strategy, self).__init__()
self._stoch_period = self.Param("StochPeriod", 14) \
.SetDisplay("Stoch Period", "Stochastic K period", "Indicators")
self._oversold = self.Param("Oversold", 30.0) \
.SetDisplay("Oversold", "Stochastic oversold level", "Signals")
self._overbought = self.Param("Overbought", 70.0) \
.SetDisplay("Overbought", "Stochastic overbought level", "Signals")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))) \
.SetDisplay("Candle Type", "Candle timeframe", "General")
@property
def candle_type(self):
return self._candle_type.Value
def OnStarted2(self, time):
super(hammer_hanging_stochastic_strategy, self).OnStarted2(time)
stoch = StochasticOscillator()
stoch.K.Length = self._stoch_period.Value
stoch.D.Length = 3
subscription = self.SubscribeCandles(self.candle_type)
subscription.BindEx(stoch, self._process_candle).Start()
def _process_candle(self, candle, stoch_val):
if candle.State != CandleStates.Finished:
return
k_value = stoch_val.K
if k_value is None:
return
k_value = float(k_value)
close = float(candle.ClosePrice)
open_p = float(candle.OpenPrice)
high = float(candle.HighPrice)
low = float(candle.LowPrice)
body = abs(close - open_p)
range_val = high - low
if range_val <= 0 or body <= 0:
return
upper_shadow = high - max(open_p, close)
lower_shadow = min(open_p, close) - low
is_hammer = lower_shadow > body * 2 and upper_shadow < body
is_hanging_man = upper_shadow > body * 2 and lower_shadow < body
if is_hammer and k_value < self._oversold.Value and self.Position <= 0:
self.BuyMarket()
elif is_hanging_man and k_value > self._overbought.Value and self.Position >= 0:
self.SellMarket()
def CreateClone(self):
return hammer_hanging_stochastic_strategy()