Esta estratégia é uma versão StockSharp do MetaTrader especialista Expert_AH_HM_RSI. Ele procura padrões de velas de martelo ou homem enforcado e requer um sinal de confirmação do Índice de Força Relativa (RSI) antes de negociar. A abordagem reflete o Expert Advisor original, incluindo a sua filosofia de gestão de risco de reverter posições quando um novo sinal aparece.
Lógica de negociação
Filtro de tendência – Uma média móvel simples curta (comprimento padrão 2) é usada para determinar se o mercado está em uma micro tendência de baixa ou de alta.
Padrão de Candlestick – A estratégia analisa a vela concluída mais recentemente:
Um martelo é detectado quando o corpo fica no terço superior do intervalo, a vela fica abaixo da barra anterior e o ponto médio da vela está abaixo da tendência da média móvel.
Um homem enforcado é detectado quando o corpo fica no terço superior, a vela fica mais alta do que a barra anterior e o ponto médio da vela está acima da tendência da média móvel.
RSI Filtro –
As negociações longas exigem que RSI esteja abaixo do limite configurável do martelo (padrão 40).
As negociações curtas exigem que RSI esteja acima do limite do enforcamento (padrão 60).
Execução de negociação – Em um sinal válido, a estratégia entra com Volume + |Position|, então as posições abertas são revertidas imediatamente quando a configuração oposta chegar.
Regras de saída – As posições são achatadas quando o RSI cruza os limites configuráveis inferior (padrão 30) ou superior (padrão 70) na direção oposta, replicando os votos de saída no código original.
Indicadores
RelativeStrengthIndex (comprimento 33 por padrão).
SimpleMovingAverage (comprimento 2 por padrão) aplicado ao fechamento de velas.
Parâmetros
Nome
Descrição
Padrão
Volume
Tamanho do pedido usado para entradas.
1
RsiPeriod
RSI período de retrospectiva.
33
MaPeriod
Período de média móvel para o filtro de tendência.
2
HammerRsiThreshold
Valor máximo de RSI que permite uma entrada longa do martelo.
40
HangingManRsiThreshold
Valor mínimo de RSI que permite uma entrada curta de enforcamento.
60
LowerExitLevel
Limite RSI usado para fechar posições vendidas após um cruzamento ascendente.
30
UpperExitLevel
Limite RSI usado para fechar posições compradas após um cruzamento descendente.
70
CandleType
Prazo processado pela estratégia.
1 hour velas
Todos os parâmetros podem ser otimizados por meio da IU de parâmetro StockSharp.
Notas de uso
A lógica funciona exclusivamente em velas prontas. Certifique-se de que o período de tempo e o feed de dados selecionados produzam barras completas.
Como a lógica de reversão sempre negocia Volume + |Position|, as posições mudam de direção instantaneamente no sinal oposto, correspondendo ao Expert Advisor.
Inicie o gerenciamento de risco integrado uma vez no lançamento (StartProtection() é chamado em OnStarted).
Arquivos
CS/AhHmRsiStrategy.cs – Implementação da estratégia.
README.md – Documentação em inglês.
README_zh.md – documentação chinesa.
README_ru.md – Documentação russa.
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()