A estratégia AMS ES RSI replica o comportamento do MetaTrader especialista Expert_AMS_ES_RSI dentro de StockSharp. Ele combina formações de velas estelares da manhã/vespertina com um filtro de confirmação do Índice de Força Relativa (RSI). As negociações longas são abertas quando uma estrela da manhã de alta aparece enquanto RSI indica condições de sobrevenda. As negociações curtas são realizadas quando uma estrela da noite de baixa se forma em conjunto com um RSI sobrecomprado. As posições são fechadas quando RSI ultrapassa os níveis de limite configuráveis.
Suposições de mercado
Funciona em qualquer instrumento que produza velas OHLC regulares. Spot FX e futuros de índices foram os alvos originais do especialista MQL.
A estratégia espera uma ação de preço suave onde os padrões de velas japonesas sejam significativos. Gráficos de ticks extremamente barulhentos podem não produzir sinais confiáveis.
Lógica de entrada
Assine o prazo configurado (padrão: 1 hora) e aguarde três velas totalmente fechadas.
Calcule o tamanho médio do corpo nas últimas velas BodyAveragePeriod (padrão: 3).
Detecte uma Estrela da Manhã quando:
A vela 3 é fortemente baixista (Open - Close maior que o tamanho médio do corpo).
A vela 2 tem um corpo real pequeno (menos da metade da média) e lacunas abaixo da vela 3.
A vela 1 fecha acima do ponto médio da vela 3.
Detecte uma Evening Star com condições simétricas de baixa.
Confirme entradas longas quando o valor atual de RSI estiver abaixo de LongEntryRsi (padrão: 40). Confirme as entradas curtas quando RSI estiver acima de ShortEntryRsi (padrão: 60).
Execute ordens de mercado usando a estratégia Volume.
Sair da lógica
Fechar posições longas quando RSI cruzar para baixo através de UpperExitRsi (padrão: 70) ou LowerExitRsi (padrão: 30).
Feche as posições curtas quando RSI cruzar para cima através dos mesmos níveis.
Nenhum stop-loss ou take-profit rígido é aplicado. A gestão de riscos deve ser tratada externamente ou ajustando os limites.
Parâmetros
Nome
Descrição
Padrão
Alcance
CandleType
Tipo de dados que representa a série de velas a ser assinada.
Período de 1 hora
Qualquer tipo de vela compatível
RsiPeriod
RSI comprimento de cálculo.
47
Otimizável (10–70)
BodyAveragePeriod
Número de velas usadas para calcular o tamanho médio do corpo necessário para validação do padrão.
3
Otimizável (2–6)
LongEntryRsi
Valor máximo de RSI que permite entradas longas.
40
Otimizável (20–50)
ShortEntryRsi
Valor mínimo de RSI que permite entradas curtas.
60
Otimizável (50–80)
LowerExitRsi
Limite inferior que aciona saídas quando cruzado para cima.
30
Otimizável (20–40)
UpperExitRsi
Limite superior que aciona saídas quando cruzado para baixo.
70
Otimizável (60–80)
Notas de implementação
Usa o StockSharp API de alto nível com assinaturas automáticas de velas.
Baseia-se exclusivamente nos valores dos indicadores fornecidos por Bind, evitando chamadas manuais de GetValue de acordo com as diretrizes do projeto.
Mantém apenas um histórico mínimo na memória (três velas recentes) para validação de padrão.
A estratégia chama automaticamente StartProtection() no lançamento para ativar mecanismos de segurança integrados.
Dicas de uso
Anexe a estratégia a um par instrumento/carteira e certifique-se de que a série de velas esteja disponível em seu conector.
Ajuste os níveis de RSI de acordo com a volatilidade dos ativos. Limites mais amplos reduzem o número de negociações, mas aumentam a qualidade da confirmação.
Combine com módulos externos de dimensionamento de posição (por exemplo, volume baseado em risco) para emular o comportamento do lote fixo do EA original.
Ao fazer backtesting, certifique-se de que os dados da vela contenham lacunas para que os padrões estelares possam ser identificados corretamente.
namespace StockSharp.Samples.Strategies;
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;
/// <summary>
/// Morning/Evening Star + RSI strategy.
/// Buys on morning star with low RSI, sells on evening star with high RSI.
/// </summary>
public class AmsEsRsiStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _rsiPeriod;
private readonly StrategyParam<decimal> _rsiLow;
private readonly StrategyParam<decimal> _rsiHigh;
private ICandleMessage _prevCandle;
private ICandleMessage _prevPrevCandle;
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 AmsEsRsiStrategy()
{
_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", "Signals");
_rsiHigh = Param(nameof(RsiHigh), 60m)
.SetDisplay("RSI High", "RSI overbought threshold", "Signals");
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevCandle = null;
_prevPrevCandle = null;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevCandle = null;
_prevPrevCandle = null;
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;
if (_prevCandle != null && _prevPrevCandle != null)
{
var prevBody = Math.Abs(_prevCandle.ClosePrice - _prevCandle.OpenPrice);
var prevRange = _prevCandle.HighPrice - _prevCandle.LowPrice;
var isSmallBody = prevRange > 0 && prevBody < prevRange * 0.3m;
var firstBearish = _prevPrevCandle.OpenPrice > _prevPrevCandle.ClosePrice;
var currBullish = candle.ClosePrice > candle.OpenPrice;
var isMorningStar = firstBearish && isSmallBody && currBullish;
var firstBullish = _prevPrevCandle.ClosePrice > _prevPrevCandle.OpenPrice;
var currBearish = candle.OpenPrice > candle.ClosePrice;
var isEveningStar = firstBullish && isSmallBody && currBearish;
if (isMorningStar && rsiValue < RsiLow && Position <= 0)
BuyMarket();
else if (isEveningStar && rsiValue > RsiHigh && Position >= 0)
SellMarket();
}
_prevPrevCandle = _prevCandle;
_prevCandle = candle;
}
}
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 ams_es_rsi_strategy(Strategy):
def __init__(self):
super(ams_es_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)
self._prev_candle = None
self._prev_prev_candle = None
@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 OnReseted(self):
super(ams_es_rsi_strategy, self).OnReseted()
self._prev_candle = None
self._prev_prev_candle = None
def OnStarted2(self, time):
super(ams_es_rsi_strategy, self).OnStarted2(time)
self._prev_candle = None
self._prev_prev_candle = None
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)
if self._prev_candle is not None and self._prev_prev_candle is not None:
prev_body = abs(float(self._prev_candle.ClosePrice) - float(self._prev_candle.OpenPrice))
prev_range = float(self._prev_candle.HighPrice) - float(self._prev_candle.LowPrice)
is_small_body = prev_range > 0 and prev_body < prev_range * 0.3
first_bearish = float(self._prev_prev_candle.OpenPrice) > float(self._prev_prev_candle.ClosePrice)
curr_bullish = float(candle.ClosePrice) > float(candle.OpenPrice)
is_morning_star = first_bearish and is_small_body and curr_bullish
first_bullish = float(self._prev_prev_candle.ClosePrice) > float(self._prev_prev_candle.OpenPrice)
curr_bearish = float(candle.OpenPrice) > float(candle.ClosePrice)
is_evening_star = first_bullish and is_small_body and curr_bearish
if is_morning_star and rsi_val < self.RsiLow and self.Position <= 0:
self.BuyMarket()
elif is_evening_star and rsi_val > self.RsiHigh and self.Position >= 0:
self.SellMarket()
self._prev_prev_candle = self._prev_candle
self._prev_candle = candle
def CreateClone(self):
return ams_es_rsi_strategy()