Exp RSIOMA V2 é uma conversão do consultor especialista original do MetaTrader 5 que opera no oscilador RSIOMA (Índice de Força Relativa da Média Móvel). A estratégia reproduz as mesmas ideias dentro da API de alto nível do StockSharp: os dados de preço são suavizados, convertidos em uma série de momentum e alimentados em um acumulador estilo RSI. As decisões de trading são tomadas quando o oscilador muda de direção ou cruza zonas predefinidas.
Lógica de trading
Pré-processamento de preço – o preço de candle selecionado (fechamento por padrão) é suavizado com uma das quatro famílias de médias móveis (simples, exponencial, suavizada ou linear ponderada).
Cálculo de momentum – o preço suavizado é comparado com o valor de MomentumPeriod barras atrás para obter o impulso de momentum.
Computação RSIOMA – os componentes de momentum positivo e negativo são acumulados com uma suavização exponencial de comprimento RsiomaLength, produzindo o valor RSIOMA no intervalo [0; 100].
Avaliação de sinais – os candles fechados mais recentes são inspecionados de acordo com o Mode escolhido:
Breakdown – reage quando RSIOMA sai dos níveis de tendência principal (MainTrendLong / MainTrendShort). Quando o oscilador sai da zona superior, as vendidas são fechadas e entradas compradas são permitidas; sair da zona inferior executa a ação oposta.
Twist – procura pontos de virada. Uma compra ocorre quando a inclinação do RSIOMA muda de descendente para ascendente, enquanto as vendas reagem a uma transição de ascendente para descendente.
CloudTwist – emula a lógica de nuvem colorida do indicador MT5. Os trades são abertos quando RSIOMA retorna de extremos de sobrecompra/sobrevenda de volta para dentro do canal, e posições opostas são fechadas ao mesmo tempo.
Os sinais são avaliados na barra especificada por SignalBar (padrão: o candle completamente fechado anterior), garantindo que apenas dados confirmados sejam usados.
Parâmetros
Nome
Descrição
Valor padrão
OrderVolume
Volume de ordem padrão usado por ordens de mercado.
1
CandleType
Série de dados de candle processada pela estratégia.
Período de 4 horas
EnableLongEntries / EnableShortEntries
Permitir a abertura de novas posições compradas/vendidas.
true
EnableLongExits / EnableShortExits
Permitir o fechamento de posições compradas/vendidas existentes.
true
Mode
Lógica de trading (Breakdown, Twist ou CloudTwist).
Breakdown
PriceSmoothing
Média móvel aplicada ao preço antes do RSIOMA.
Exponential
RsiomaLength
Período de média RSIOMA.
14
MomentumPeriod
Atraso entre amostras ao computar momentum.
1
AppliedPrice
Preço de candle usado para o oscilador (fechamento, abertura, mediana, DeMark, etc.).
Close
MainTrendLong / MainTrendShort
Níveis RSIOMA que definem zonas de sobrecompra/sobrevenda.
60 / 40
SignalBar
Número de barras fechadas atrás que devem ser analisadas.
1
Notas de implementação
Apenas as famílias de suavização disponíveis no StockSharp são suportadas (simples, exponencial, suavizada e linear ponderada). Os modos avançados da versão MT5 (JJMA, VIDYA, AMA, …) não estão incluídos.
As médias RSI são inicializadas usando os primeiros RsiomaLength valores de momentum para espelhar a inicialização do MetaTrader. Depois disso uma atualização exponencial é aplicada, correspondendo ao comportamento original do consultor especialista.
Posições são sempre fechadas antes que uma entrada oposta seja emitida. As permissões de entrada (EnableLongEntries, EnableShortEntries) e as permissões de saída (EnableLongExits, EnableShortExits) fornecem controle total sobre as direções permitidas.
SignalBar = 0 pode ser usado para reagir ao candle finalizado atual; valores mais altos reproduzem a capacidade do MT5 de aguardar várias barras antes de agir.
Uso
Adicionar a estratégia a um projeto StockSharp e atribuir o instrumento que deseja operar.
Configurar a assinatura de candle através de CandleType (padrão são candles de 4 horas) e ajustar limites se o símbolo usar características de volatilidade diferentes.
Selecionar o modo de sinal preferido dependendo de se deseja entradas de estilo rompimento (Breakdown), viradas de momentum (Twist) ou mudanças de cor de nuvem (CloudTwist).
Iniciar a estratégia. Durante a execução a estratégia se inscreve na série de candles escolhida, computa a cadeia RSIOMA e emite ordens de mercado quando as condições são satisfeitas.
using System;
using System.Collections.Generic;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// RSIOMA strategy using RSI with overbought/oversold levels.
/// Buys when RSI crosses above oversold, sells when crosses below overbought.
/// </summary>
public class ExpRsiomaV2Strategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _rsiPeriod;
private readonly StrategyParam<decimal> _overbought;
private readonly StrategyParam<decimal> _oversold;
private decimal? _prevRsi;
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public int RsiPeriod
{
get => _rsiPeriod.Value;
set => _rsiPeriod.Value = value;
}
public decimal Overbought
{
get => _overbought.Value;
set => _overbought.Value = value;
}
public decimal Oversold
{
get => _oversold.Value;
set => _oversold.Value = value;
}
public ExpRsiomaV2Strategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame())
.SetDisplay("Candle Type", "Timeframe", "General");
_rsiPeriod = Param(nameof(RsiPeriod), 14)
.SetGreaterThanZero()
.SetDisplay("RSI Period", "RSI calculation period", "Indicators");
_overbought = Param(nameof(Overbought), 65m)
.SetDisplay("Overbought", "Overbought RSI level", "Levels");
_oversold = Param(nameof(Oversold), 35m)
.SetDisplay("Oversold", "Oversold RSI level", "Levels");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevRsi = null;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevRsi = null;
var rsi = new RelativeStrengthIndex { Length = RsiPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(rsi, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawOwnTrades(area);
}
var indArea = CreateChartArea();
if (indArea != null)
{
DrawIndicator(indArea, rsi);
}
}
private void ProcessCandle(ICandleMessage candle, decimal rsiValue)
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
{
_prevRsi = rsiValue;
return;
}
if (_prevRsi == null)
{
_prevRsi = rsiValue;
return;
}
// RSI crosses above oversold → buy signal
if (_prevRsi.Value <= Oversold && rsiValue > Oversold && Position <= 0)
{
if (Position < 0)
BuyMarket();
BuyMarket();
}
// RSI crosses below overbought → sell signal
else if (_prevRsi.Value >= Overbought && rsiValue < Overbought && Position >= 0)
{
if (Position > 0)
SellMarket();
SellMarket();
}
_prevRsi = rsiValue;
}
}
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 exp_rsioma_v2_strategy(Strategy):
def __init__(self):
super(exp_rsioma_v2_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(1))) \
.SetDisplay("Candle Type", "Timeframe", "General")
self._rsi_period = self.Param("RsiPeriod", 14) \
.SetDisplay("RSI Period", "RSI calculation period", "Indicators")
self._overbought = self.Param("Overbought", 65.0) \
.SetDisplay("Overbought", "Overbought RSI level", "Levels")
self._oversold = self.Param("Oversold", 35.0) \
.SetDisplay("Oversold", "Oversold RSI level", "Levels")
self._prev_rsi = None
@property
def CandleType(self):
return self._candle_type.Value
@property
def RsiPeriod(self):
return self._rsi_period.Value
@property
def Overbought(self):
return self._overbought.Value
@property
def Oversold(self):
return self._oversold.Value
def OnReseted(self):
super(exp_rsioma_v2_strategy, self).OnReseted()
self._prev_rsi = None
def OnStarted2(self, time):
super(exp_rsioma_v2_strategy, self).OnStarted2(time)
self._prev_rsi = None
rsi = RelativeStrengthIndex()
rsi.Length = self.RsiPeriod
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(rsi, self._on_process).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawOwnTrades(area)
ind_area = self.CreateChartArea()
if ind_area is not None:
self.DrawIndicator(ind_area, rsi)
def _on_process(self, candle, rsi_value):
if candle.State != CandleStates.Finished:
return
rv = float(rsi_value)
if not self.IsFormedAndOnlineAndAllowTrading():
self._prev_rsi = rv
return
if self._prev_rsi is None:
self._prev_rsi = rv
return
ob = float(self.Overbought)
os_level = float(self.Oversold)
# RSI crosses above oversold
if self._prev_rsi <= os_level and rv > os_level and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
# RSI crosses below overbought
elif self._prev_rsi >= ob and rv < ob and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._prev_rsi = rv
def CreateClone(self):
return exp_rsioma_v2_strategy()