Forex Hammer und Hängender Mann Strategie
Diese Strategie handelt klassische Candlestick-Umkehrmuster: den bullishen Hammer und den bearishen Hängenden Mann. Sie geht nach einem Hammer long und nach einem Hängenden Mann short und hält die Position für eine feste Anzahl von Kerzen.
Die Position wird geschlossen, sobald der Haltezeitraum abläuft oder Schutz-Stops ausgelöst werden.
Details
- Einstiegskriterien: Hammer für Long, Hängender Mann für Short.
- Long/Short: Beide.
- Ausstiegskriterien: Haltezeitraum oder Stop-Loss/Take-Profit.
- Stops: Ja.
- Standardwerte:
CandleType= TimeSpan.FromMinutes(5)BodyLengthMultiplier= 5ShadowRatio= 1HoldPeriods= 26
- Filter:
- Kategorie: Muster
- Richtung: Beide
- Indikatoren: Candlestick
- Stops: Ja
- Komplexität: Grundlegend
- Zeitrahmen: Intraday
- Saisonalität: Nein
- Neuronale Netze: Nein
- Divergenz: Nein
- Risikolevel: Mittel
using System;
using System.Collections.Generic;
using Ecng.Common;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Forex Hammer and Hanging Man strategy.
/// A candle qualifies when its range exceeds BodyLengthMultiplier times its body and its lower shadow is longer than ShadowRatio
/// times its upper shadow. A bullish one is a hammer and goes long, a bearish one is a hanging man and goes short, reversing an
/// opposite position. A position is closed after HoldPeriods candles.
/// </summary>
public class ForexHammerAndHangingManStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<decimal> _bodyLengthMultiplier;
private readonly StrategyParam<decimal> _shadowRatio;
private readonly StrategyParam<int> _holdPeriods;
private int _barsInPosition;
/// <summary>
/// Candle type.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// How many bodies the candle range must exceed.
/// </summary>
public decimal BodyLengthMultiplier
{
get => _bodyLengthMultiplier.Value;
set => _bodyLengthMultiplier.Value = value;
}
/// <summary>
/// How many upper shadows the lower shadow must exceed.
/// </summary>
public decimal ShadowRatio
{
get => _shadowRatio.Value;
set => _shadowRatio.Value = value;
}
/// <summary>
/// Candles a position is held.
/// </summary>
public int HoldPeriods
{
get => _holdPeriods.Value;
set => _holdPeriods.Value = value;
}
/// <summary>
/// Constructor.
/// </summary>
public ForexHammerAndHangingManStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Type of candles to use", "General");
_bodyLengthMultiplier = Param(nameof(BodyLengthMultiplier), 5m)
.SetNotNegative()
.SetDisplay("Body Multiplier", "How many bodies the candle range must exceed", "Pattern");
_shadowRatio = Param(nameof(ShadowRatio), 1m)
.SetNotNegative()
.SetDisplay("Shadow Ratio", "How many upper shadows the lower shadow must exceed", "Pattern");
_holdPeriods = Param(nameof(HoldPeriods), 26)
.SetGreaterThanZero()
.SetDisplay("Hold Periods", "Candles a position is held", "Trading");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_barsInPosition = 0;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_barsInPosition = 0;
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle)
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
var body = Math.Abs(candle.ClosePrice - candle.OpenPrice);
var range = candle.HighPrice - candle.LowPrice;
var lowerShadow = Math.Min(candle.OpenPrice, candle.ClosePrice) - candle.LowPrice;
var upperShadow = candle.HighPrice - Math.Max(candle.OpenPrice, candle.ClosePrice);
var shape = range > 0 && range > BodyLengthMultiplier * body && lowerShadow > ShadowRatio * upperShadow;
var hammer = shape && candle.ClosePrice > candle.OpenPrice;
var hangingMan = shape && candle.ClosePrice < candle.OpenPrice;
if (hammer && Position <= 0)
{
BuyMarket(Volume + Math.Abs(Position));
_barsInPosition = 0;
return;
}
if (hangingMan && Position >= 0)
{
SellMarket(Volume + Math.Abs(Position));
_barsInPosition = 0;
return;
}
if (Position == 0)
return;
_barsInPosition++;
if (_barsInPosition < HoldPeriods)
return;
if (Position > 0)
SellMarket(Position);
else
BuyMarket(-Position);
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Strategies import Strategy
class forex_hammer_and_hanging_man_strategy(Strategy):
"""
Forex Hammer and Hanging Man strategy.
A candle qualifies when its range exceeds BodyLengthMultiplier times its body and its lower shadow is longer than ShadowRatio
times its upper shadow. A bullish one is a hammer and goes long, a bearish one is a hanging man and goes short, reversing an
opposite position. A position is closed after HoldPeriods candles.
"""
def __init__(self):
super(forex_hammer_and_hanging_man_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))).SetDisplay("Candle Type", "Type of candles to use", "General")
self._body_length_multiplier = self.Param("BodyLengthMultiplier", 5.0).SetNotNegative().SetDisplay("Body Multiplier", "How many bodies the candle range must exceed", "Pattern")
self._shadow_ratio = self.Param("ShadowRatio", 1.0).SetNotNegative().SetDisplay("Shadow Ratio", "How many upper shadows the lower shadow must exceed", "Pattern")
self._hold_periods = self.Param("HoldPeriods", 26).SetGreaterThanZero().SetDisplay("Hold Periods", "Candles a position is held", "Trading")
self._bars_in_position = 0
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(forex_hammer_and_hanging_man_strategy, self).OnReseted()
self._bars_in_position = 0
def OnStarted2(self, time):
super(forex_hammer_and_hanging_man_strategy, self).OnStarted2(time)
self._bars_in_position = 0
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(self._process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawOwnTrades(area)
def _process_candle(self, candle):
if candle.State != CandleStates.Finished:
return
if not self.IsFormedAndOnlineAndAllowTrading():
return
open_price = float(candle.OpenPrice)
close = float(candle.ClosePrice)
high = float(candle.HighPrice)
low = float(candle.LowPrice)
body = abs(close - open_price)
rng = high - low
lower_shadow = min(open_price, close) - low
upper_shadow = high - max(open_price, close)
shape = rng > 0 and rng > float(self._body_length_multiplier.Value) * body and lower_shadow > float(self._shadow_ratio.Value) * upper_shadow
hammer = shape and close > open_price
hanging_man = shape and close < open_price
if hammer and self.Position <= 0:
self.BuyMarket(self.Volume + abs(self.Position))
self._bars_in_position = 0
return
if hanging_man and self.Position >= 0:
self.SellMarket(self.Volume + abs(self.Position))
self._bars_in_position = 0
return
if self.Position == 0:
return
self._bars_in_position += 1
if self._bars_in_position < self._hold_periods.Value:
return
if self.Position > 0:
self.SellMarket(self.Position)
else:
self.BuyMarket(-self.Position)
def CreateClone(self):
return forex_hammer_and_hanging_man_strategy()