ハンマー足リバーサル (Hammer Candle Reversal)
ハンマー足(Hammer)は、売り圧力が収まった後のイントラデイ・リバーサルを示すことが多くあります。この戦略はハンマーパターンを探してロングエントリーし、反発を予測します。
テストでは年平均リターンが約64%となっています。外国為替(forex)市場での運用に最も適しています。
システムは実体の少なくとも2倍の下ヒゲと、ほとんど上ヒゲのないことを要求します。確認後、設定されたポジションサイズで買いエントリーし、利益またはストップロスを待ちます。
詳細
- エントリー条件: ハンマー足が検出された。
- ロング/ショート: ロングのみ。
- エグジット条件: ストップロスまたは裁量的なエグジット。
- ストップ: はい。
- デフォルト値:
CandleType= TimeSpan.FromMinutes(5)RewardRiskRatio= 2m ストップはハンマーの安値、目標はエントリーからそのリスク幅の RewardRiskRatio 倍上に置かれ、どちらもローソク足の終値で判定します。
- フィルター:
- カテゴリ: パターン
- 方向: ロングのみ
- インジケーター: Candlestick
- ストップ: はい
- 複雑さ: 基本
- 時間軸: イントラデイ
- 季節性: いいえ
- ニューラルネットワーク: いいえ
- ダイバージェンス: いいえ
- リスクレベル: 中
using System;
using System.Collections.Generic;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Hammer Candle strategy.
/// Buys after a hammer: a candle whose lower shadow is at least twice its body and whose upper shadow is under half of it.
/// The stop is the hammer's low and the target lies RewardRiskRatio times that risk above the entry close.
/// </summary>
public class HammerCandleStrategy : Strategy
{
private readonly StrategyParam<decimal> _rewardRiskRatio;
private readonly StrategyParam<DataType> _candleType;
private decimal _stopPrice;
private decimal _targetPrice;
/// <summary>
/// Distance of the target in multiples of the distance to the stop.
/// </summary>
public decimal RewardRiskRatio
{
get => _rewardRiskRatio.Value;
set => _rewardRiskRatio.Value = value;
}
/// <summary>
/// Candle type and timeframe.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Constructor.
/// </summary>
public HammerCandleStrategy()
{
_rewardRiskRatio = Param(nameof(RewardRiskRatio), 2m)
.SetGreaterThanZero()
.SetDisplay("Reward/Risk", "Target distance in multiples of the stop distance", "Risk");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Type of candles to use", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_stopPrice = default;
_targetPrice = default;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
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 close = candle.ClosePrice;
if (Position > 0)
{
if (close <= _stopPrice || close >= _targetPrice)
SellMarket(Position);
return;
}
if (Position != 0)
return;
var body = Math.Abs(candle.OpenPrice - close);
var lowerShadow = Math.Min(candle.OpenPrice, close) - candle.LowPrice;
var upperShadow = candle.HighPrice - Math.Max(candle.OpenPrice, close);
var isHammer = body > 0 && lowerShadow >= body * 2m && upperShadow < body * 0.5m;
if (!isHammer || close <= candle.LowPrice)
return;
BuyMarket(Volume);
_stopPrice = candle.LowPrice;
_targetPrice = close + RewardRiskRatio * (close - candle.LowPrice);
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan, Math, Decimal
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Strategies import Strategy
class hammer_candle_strategy(Strategy):
"""
Hammer Candle strategy.
Buys after a hammer: a candle whose lower shadow is at least twice its body and whose upper shadow is under half of it.
The stop is the hammer's low and the target lies RewardRiskRatio times that risk above the entry close.
"""
def __init__(self):
super(hammer_candle_strategy, self).__init__()
self._reward_risk_ratio = self.Param("RewardRiskRatio", 2.0).SetGreaterThanZero().SetDisplay("Reward/Risk", "Target distance in multiples of the stop distance", "Risk")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))).SetDisplay("Candle Type", "Type of candles to use", "General")
self._stop_price = Decimal(0)
self._target_price = Decimal(0)
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(hammer_candle_strategy, self).OnReseted()
self._stop_price = Decimal(0)
self._target_price = Decimal(0)
def OnStarted2(self, time):
super(hammer_candle_strategy, self).OnStarted2(time)
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
close = candle.ClosePrice
if self.Position > 0:
if close <= self._stop_price or close >= self._target_price:
self.SellMarket(self.Position)
return
if self.Position != 0:
return
body = Math.Abs(candle.OpenPrice - close)
lower_shadow = Math.Min(candle.OpenPrice, close) - candle.LowPrice
upper_shadow = candle.HighPrice - Math.Max(candle.OpenPrice, close)
is_hammer = body > 0 and lower_shadow >= body * Decimal(2) and upper_shadow < body * Decimal(0.5)
if not is_hammer or close <= candle.LowPrice:
return
self.BuyMarket(self.Volume)
self._stop_price = candle.LowPrice
self._target_price = close + Decimal(self._reward_risk_ratio.Value) * (close - candle.LowPrice)
def CreateClone(self):
return hammer_candle_strategy()