Diese Strategie ist eine StockSharp-Portierung des MetaTrader-Experten Expert_AH_HM_RSI. Es sucht nach Hammer- oder Hängemann-Kerzenmustern und erfordert vor dem Handel ein bestätigendes Signal vom Relative Strength Index (RSI). Der Ansatz spiegelt den ursprünglichen Expert Advisor wider, einschließlich seiner Risikomanagementphilosophie, Positionen umzukehren, wenn ein neues Signal erscheint.
Handelslogik
Trendfilter – Ein kurzer einfacher gleitender Durchschnitt (Standardlänge 2) wird verwendet, um zu bestimmen, ob sich der Markt in einem Mikro-Abwärtstrend oder einem Aufwärtstrend befindet.
Kerzenmuster – Die Strategie analysiert die zuletzt abgeschlossene Kerze:
Ein Hammer wird erkannt, wenn der Körper im oberen Drittel der Spanne liegt, die Lücken der Kerze geringer sind als der vorherige Balken und der Mittelpunkt der Kerze unter dem Trend des gleitenden Durchschnitts liegt.
Ein hängender Mann wird erkannt, wenn der Körper im oberen Drittel sitzt, die Lücken der Kerze höher als der vorherige Balken sind und der Mittelpunkt der Kerze über dem Trend des gleitenden Durchschnitts liegt.
RSI Filter –
Für Long-Trades muss der RSI unter dem konfigurierbaren Hammer-Schwellenwert liegen (Standard 40).
Short-Trades erfordern, dass der RSI über dem Hanging-Man-Schwellenwert liegt (Standard 60).
Handelsausführung – Bei einem gültigen Signal beginnt die Strategie mit Volume + |Position|, sodass offene Positionen sofort umgekehrt werden, wenn das entgegengesetzte Setup eintritt.
Ausstiegsregeln – Positionen werden abgeflacht, wenn der RSI die konfigurierbare untere (Standard 30) oder obere (Standard 70) Grenze in die entgegengesetzte Richtung überschreitet, wodurch die Ausstiegsstimmen im Originalcode repliziert werden.
Indikatoren
RelativeStrengthIndex (Standardlänge 33).
SimpleMovingAverage (Standardlänge 2) wird auf Kerzenschlüsse angewendet.
Parameter
Name
Beschreibung
Standard
Volume
Auftragsgröße, die für Einträge verwendet wird.
1
RsiPeriod
RSI Lookback-Zeitraum.
33
MaPeriod
Zeitraum des gleitenden Durchschnitts für den Trendfilter.
2
HammerRsiThreshold
Maximaler RSI-Wert, der einen hammerlangen Eintrag ermöglicht.
40
HangingManRsiThreshold
Minimaler RSI-Wert, der einen Short-Einstieg mit hängendem Mann ermöglicht.
60
LowerExitLevel
Die RSI-Grenze wird verwendet, um Shorts nach einem Aufwärtskreuz zu schließen.
30
UpperExitLevel
Die RSI-Grenze wird zum Schließen von Long-Positionen nach einem Abwärtskreuz verwendet.
70
CandleType
Von der Strategie verarbeiteter Zeitrahmen.
1 hour Kerzen
Alle Parameter können über die Parameter-Benutzeroberfläche StockSharp optimiert werden.
Nutzungshinweise
Die Logik funktioniert ausschließlich bei fertigen Kerzen. Stellen Sie sicher, dass der ausgewählte Zeitrahmen und der ausgewählte Datenfeed vollständige Balken erzeugen.
Da die Umkehrlogik immer Volume + |Position| handelt, ändern Positionen sofort ihre Richtung, wenn das entgegengesetzte Signal vorliegt und mit dem Expert Advisor übereinstimmt.
Starten Sie das integrierte Risikomanagement einmal beim Start (StartProtection() wird in OnStarted aufgerufen).
Dateien
CS/AhHmRsiStrategy.cs – Strategieumsetzung.
README.md – Englische Dokumentation.
README_zh.md – Chinesische Dokumentation.
README_ru.md – Russische Dokumentation.
namespace StockSharp.Samples.Strategies;
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;
/// <summary>
/// Hammer/Hanging Man + RSI strategy.
/// Buys on hammer with low RSI, sells on hanging man with high RSI.
/// </summary>
public class AhHmRsiStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _rsiPeriod;
private readonly StrategyParam<decimal> _rsiLow;
private readonly StrategyParam<decimal> _rsiHigh;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int RsiPeriod { get => _rsiPeriod.Value; set => _rsiPeriod.Value = value; }
public decimal RsiLow { get => _rsiLow.Value; set => _rsiLow.Value = value; }
public decimal RsiHigh { get => _rsiHigh.Value; set => _rsiHigh.Value = value; }
public AhHmRsiStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
_rsiPeriod = Param(nameof(RsiPeriod), 14)
.SetGreaterThanZero()
.SetDisplay("RSI Period", "RSI period", "Indicators");
_rsiLow = Param(nameof(RsiLow), 40m)
.SetDisplay("RSI Low", "RSI oversold threshold for buy", "Signals");
_rsiHigh = Param(nameof(RsiHigh), 60m)
.SetDisplay("RSI High", "RSI overbought threshold for sell", "Signals");
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var rsi = new RelativeStrengthIndex { Length = RsiPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(rsi, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal rsiValue)
{
if (candle.State != CandleStates.Finished) 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;
var isHammer = lowerShadow > body * 2 && upperShadow < body;
var isHangingMan = upperShadow > body * 2 && lowerShadow < body;
if (isHammer && rsiValue < RsiLow && Position <= 0)
BuyMarket();
else if (isHangingMan && rsiValue > RsiHigh && 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 RelativeStrengthIndex
from StockSharp.Algo.Strategies import Strategy
class ah_hm_rsi_strategy(Strategy):
def __init__(self):
super(ah_hm_rsi_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5)))
self._rsi_period = self.Param("RsiPeriod", 14)
self._rsi_low = self.Param("RsiLow", 40.0)
self._rsi_high = self.Param("RsiHigh", 60.0)
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
@property
def RsiPeriod(self):
return self._rsi_period.Value
@RsiPeriod.setter
def RsiPeriod(self, value):
self._rsi_period.Value = value
@property
def RsiLow(self):
return self._rsi_low.Value
@RsiLow.setter
def RsiLow(self, value):
self._rsi_low.Value = value
@property
def RsiHigh(self):
return self._rsi_high.Value
@RsiHigh.setter
def RsiHigh(self, value):
self._rsi_high.Value = value
def OnStarted2(self, time):
super(ah_hm_rsi_strategy, self).OnStarted2(time)
rsi = RelativeStrengthIndex()
rsi.Length = self.RsiPeriod
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(rsi, self._process_candle).Start()
def _process_candle(self, candle, rsi_value):
if candle.State != CandleStates.Finished:
return
rsi_val = float(rsi_value)
body = abs(float(candle.ClosePrice) - float(candle.OpenPrice))
rng = float(candle.HighPrice) - float(candle.LowPrice)
if rng <= 0 or body <= 0:
return
upper_shadow = float(candle.HighPrice) - max(float(candle.OpenPrice), float(candle.ClosePrice))
lower_shadow = min(float(candle.OpenPrice), float(candle.ClosePrice)) - float(candle.LowPrice)
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 rsi_val < self.RsiLow and self.Position <= 0:
self.BuyMarket()
elif is_hanging_man and rsi_val > self.RsiHigh and self.Position >= 0:
self.SellMarket()
def CreateClone(self):
return ah_hm_rsi_strategy()