Estratégia de Impulso RRS
A Estratégia RRS Impulse é uma versão StockSharp de alto nível do consultor especialista MetaTrader "RRS Impulse". O robô original
filtros de bandas RSI, Stochastic e Bollinger combinados, alternados entre vários modos de intensidade de sinal e paradas de proteção usadas e
saídas virtuais de fuga. Esta versão C# mantém o mesmo comportamento, mas depende puramente do StockSharp alto nível API: vela
as assinaturas alimentam os indicadores, enquanto BuyMarket, SellMarket e ClosePosition executam os pedidos.
Lógica de negociação
- Modos Indicadores – Escolha entre quatro opções:
Rsi: negocie o oscilador quando ele sai da zona de sobrecompra/sobrevenda.
Stochastic: exige que %K e %D estejam acima/abaixo dos níveis configurados.
BollingerBands: reage a fechamentos acima da banda superior ou abaixo da banda inferior.
RsiStochasticBollinger: dispara somente quando todos os três filtros confirmam a mesma direção.
- Direção de negociação –
Trend segue o indicador (sobrecompra leva a posições vendidas, sobrevenda a posições longas). CounterTrend desaparece o
movimento (sobrecompra aciona posições compradas, sobrevenda aciona posições vendidas).
- Força do sinal – Controla quantos prazos devem ser acordados antes de entrar em uma negociação:
SingleTimeFrame: use apenas o prazo base fornecido por CandleType.
MultiTimeFrame: requer alinhamento entre velas M1, M5, M15, M30, H1 e H4.
Strong: concentre-se no impulso intradiário verificando M1, M5, M15 e M30.
VeryStrong: exige confirmação da escada M1… H4 completa. Quando o modo de indicador combinado é ativado a cada período
deve satisfazer todos os três filtros.
- Gerenciamento de Riscos – Cada posição rastreia o preço médio de preenchimento e monitora três condições de saída:
- distância fixa de stop-loss em pips;
- distância fixa de lucro em pips;
- trailing stop ativado quando o lucro excede
TrailingStartPips e mantido em TrailingGapPips.
Sempre que a direção muda, a estratégia chama ClosePosition() primeiro para achatar e só abre a negociação oposta depois
o próximo tique de confirmação.
Parâmetros
| Grupo |
Nome |
Descrição |
| Dados |
CandleType |
Série base de velas processada para decisões de negociação. |
| Pedidos |
TradeVolume |
Volume utilizado no envio de ordens de mercado. |
| Risco |
StopLossPips, TakeProfitPips, TrailingStartPips, TrailingGapPips |
Saídas de proteção virtuais expressas em pips. |
| Sinais |
IndicatorMode, TradeDirection, SignalStrength |
Mudanças de comportamento copiadas do bloco de entrada MQL. |
| RSI |
RsiPeriod, RsiUpperLevel, RsiLowerLevel |
Configuração RSI para detecção de sobrecompra/sobrevenda. |
| Stochastic |
StochasticKPeriod, StochasticDPeriod, StochasticSlowing, StochasticUpperLevel, StochasticLowerLevel |
Configurações do oscilador estocástico lento. |
| Bollinger |
BollingerPeriod, BollingerDeviation |
Bollinger Multiplicador de lookback e desvio de bandas. |
Todos os parâmetros suportam faixas de otimização idênticas à versão MetaTrader onde fazia sentido (por exemplo, parar e percorrer distâncias
ou limites do oscilador).
Requisitos de dados
A estratégia precisa de velas minúsculas para a escada de confirmação. Quando SignalStrength solicita prazos adicionais, a estratégia
adiciona automaticamente as assinaturas necessárias (GetWorkingSecurities as anuncia no mecanismo). As cotações de nível 1 não são usadas;
apenas os preços de fechamento das velas finalizadas geram entradas e saídas. A lógica protetora, portanto, reproduz o stop/target "virtual"
comportamento do robô original.
Notas sobre a conversão
- A rotação aleatória de símbolos do EA foi removida intencionalmente. As estratégias StockSharp funcionam com um único
Security, então o
O porto concentra-se em combinar a lógica do indicador e o gerenciamento de risco, deixando a rotação do instrumento para o usuário.
- O gerenciamento de pedidos é baseado no mercado: quando a direção muda ou uma condição de proteção é acionada,
ClosePosition() é chamado,
espelhando os loops MetaTrader que iteraram por meio de tickets.
- A conversão mantém todos os comentários em inglês e usa tabulações para recuo para cumprir as diretrizes do repositório.
namespace StockSharp.Samples.Strategies;
using System;
using System.Collections.Generic;
using StockSharp.Algo;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
/// <summary>
/// RRS Impulse strategy.
/// Combines RSI, Stochastic and Bollinger Bands for counter-trend entries.
/// </summary>
public class RrsImpulseStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _rsiPeriod;
private readonly StrategyParam<decimal> _rsiUpperLevel;
private readonly StrategyParam<decimal> _rsiLowerLevel;
private readonly StrategyParam<int> _stochasticKPeriod;
private readonly StrategyParam<int> _stochasticDPeriod;
private readonly StrategyParam<decimal> _stochasticUpperLevel;
private readonly StrategyParam<decimal> _stochasticLowerLevel;
private readonly StrategyParam<int> _bollingerPeriod;
private readonly StrategyParam<decimal> _bollingerDeviation;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int RsiPeriod { get => _rsiPeriod.Value; set => _rsiPeriod.Value = value; }
public decimal RsiUpperLevel { get => _rsiUpperLevel.Value; set => _rsiUpperLevel.Value = value; }
public decimal RsiLowerLevel { get => _rsiLowerLevel.Value; set => _rsiLowerLevel.Value = value; }
public int StochasticKPeriod { get => _stochasticKPeriod.Value; set => _stochasticKPeriod.Value = value; }
public int StochasticDPeriod { get => _stochasticDPeriod.Value; set => _stochasticDPeriod.Value = value; }
public decimal StochasticUpperLevel { get => _stochasticUpperLevel.Value; set => _stochasticUpperLevel.Value = value; }
public decimal StochasticLowerLevel { get => _stochasticLowerLevel.Value; set => _stochasticLowerLevel.Value = value; }
public int BollingerPeriod { get => _bollingerPeriod.Value; set => _bollingerPeriod.Value = value; }
public decimal BollingerDeviation { get => _bollingerDeviation.Value; set => _bollingerDeviation.Value = value; }
public RrsImpulseStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame())
.SetDisplay("Candle Type", "Timeframe", "General");
_rsiPeriod = Param(nameof(RsiPeriod), 14)
.SetDisplay("RSI Period", "RSI length", "RSI");
_rsiUpperLevel = Param(nameof(RsiUpperLevel), 65m)
.SetDisplay("RSI Upper", "Overbought", "RSI");
_rsiLowerLevel = Param(nameof(RsiLowerLevel), 35m)
.SetDisplay("RSI Lower", "Oversold", "RSI");
_stochasticKPeriod = Param(nameof(StochasticKPeriod), 10)
.SetDisplay("Stochastic %K", "%K period", "Stochastic");
_stochasticDPeriod = Param(nameof(StochasticDPeriod), 3)
.SetDisplay("Stochastic %D", "%D period", "Stochastic");
_stochasticUpperLevel = Param(nameof(StochasticUpperLevel), 70m)
.SetDisplay("Stochastic Upper", "Overbought", "Stochastic");
_stochasticLowerLevel = Param(nameof(StochasticLowerLevel), 30m)
.SetDisplay("Stochastic Lower", "Oversold", "Stochastic");
_bollingerPeriod = Param(nameof(BollingerPeriod), 20)
.SetDisplay("Bollinger Period", "BB length", "Bollinger");
_bollingerDeviation = Param(nameof(BollingerDeviation), 2m)
.SetDisplay("Bollinger Deviation", "BB deviation", "Bollinger");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var rsi = new RelativeStrengthIndex { Length = RsiPeriod };
var stochastic = new StochasticOscillator();
stochastic.K.Length = StochasticKPeriod;
stochastic.D.Length = StochasticDPeriod;
var bollinger = new BollingerBands { Length = BollingerPeriod, Width = BollingerDeviation };
var subscription = SubscribeCandles(CandleType);
subscription
.BindEx(rsi, stochastic, bollinger, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, bollinger);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, IIndicatorValue rsiVal, IIndicatorValue stochVal, IIndicatorValue bbVal)
{
if (candle.State != CandleStates.Finished)
return;
if (!rsiVal.IsFinal || !stochVal.IsFinal || !bbVal.IsFinal)
return;
if (!rsiVal.IsFormed || !stochVal.IsFormed || !bbVal.IsFormed)
return;
var rsi = rsiVal.GetValue<decimal>();
var stoch = (StochasticOscillatorValue)stochVal;
var stochK = stoch.K ?? 50m;
var bb = (BollingerBandsValue)bbVal;
var bbUpper = bb.UpBand ?? candle.ClosePrice;
var bbLower = bb.LowBand ?? candle.ClosePrice;
var close = candle.ClosePrice;
// Count how many indicators signal overbought/oversold
var obSignals = 0;
var osSignals = 0;
if (rsi >= RsiUpperLevel) obSignals++;
if (rsi <= RsiLowerLevel) osSignals++;
if (stochK >= StochasticUpperLevel) obSignals++;
if (stochK <= StochasticLowerLevel) osSignals++;
if (close >= bbUpper) obSignals++;
if (close <= bbLower) osSignals++;
// Counter-trend: need at least 2 of 3 indicators confirming
if (osSignals >= 2 && Position <= 0)
{
BuyMarket();
}
else if (obSignals >= 2 && Position >= 0)
{
SellMarket();
}
// Exit long when RSI and stoch neutralize
else if (Position > 0 && rsi > 50m && stochK > 50m)
{
SellMarket();
}
// Exit short when RSI and stoch neutralize
else if (Position < 0 && rsi < 50m && stochK < 50m)
{
BuyMarket();
}
}
}
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
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import BollingerBands, RelativeStrengthIndex, StochasticOscillator
from StockSharp.Algo.Strategies import Strategy
class rrs_impulse_strategy(Strategy):
"""RSI + Stochastic + Bollinger Bands counter-trend strategy."""
def __init__(self):
super(rrs_impulse_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) \
.SetGreaterThanZero() \
.SetDisplay("RSI Period", "RSI length", "RSI")
self._rsi_upper_level = self.Param("RsiUpperLevel", 65.0) \
.SetDisplay("RSI Upper", "Overbought", "RSI")
self._rsi_lower_level = self.Param("RsiLowerLevel", 35.0) \
.SetDisplay("RSI Lower", "Oversold", "RSI")
self._stochastic_k_period = self.Param("StochasticKPeriod", 10) \
.SetGreaterThanZero() \
.SetDisplay("Stochastic %K", "%K period", "Stochastic")
self._stochastic_d_period = self.Param("StochasticDPeriod", 3) \
.SetGreaterThanZero() \
.SetDisplay("Stochastic %D", "%D period", "Stochastic")
self._stochastic_upper_level = self.Param("StochasticUpperLevel", 70.0) \
.SetDisplay("Stochastic Upper", "Overbought", "Stochastic")
self._stochastic_lower_level = self.Param("StochasticLowerLevel", 30.0) \
.SetDisplay("Stochastic Lower", "Oversold", "Stochastic")
self._bollinger_period = self.Param("BollingerPeriod", 20) \
.SetGreaterThanZero() \
.SetDisplay("Bollinger Period", "BB length", "Bollinger")
self._bollinger_deviation = self.Param("BollingerDeviation", 2.0) \
.SetGreaterThanZero() \
.SetDisplay("Bollinger Deviation", "BB deviation", "Bollinger")
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
def OnStarted2(self, time):
super(rrs_impulse_strategy, self).OnStarted2(time)
rsi = RelativeStrengthIndex()
rsi.Length = self._rsi_period.Value
stochastic = StochasticOscillator()
stochastic.K.Length = self._stochastic_k_period.Value
stochastic.D.Length = self._stochastic_d_period.Value
bollinger = BollingerBands()
bollinger.Length = self._bollinger_period.Value
bollinger.Width = self._bollinger_deviation.Value
subscription = self.SubscribeCandles(self.CandleType)
subscription.BindEx(rsi, stochastic, bollinger, self._process_candle).Start()
def _process_candle(self, candle, rsi_val, stoch_val, bb_val):
if candle.State != CandleStates.Finished:
return
if not rsi_val.IsFinal or not stoch_val.IsFinal or not bb_val.IsFinal:
return
if not rsi_val.IsFormed or not stoch_val.IsFormed or not bb_val.IsFormed:
return
rsi = float(rsi_val)
stoch_k = float(stoch_val.K) if stoch_val.K is not None else 50.0
bb_upper = bb_val.UpBand
bb_lower = bb_val.LowBand
upper = float(bb_upper) if bb_upper is not None else float(candle.ClosePrice)
lower = float(bb_lower) if bb_lower is not None else float(candle.ClosePrice)
close = float(candle.ClosePrice)
ob_signals = 0
os_signals = 0
if rsi >= float(self._rsi_upper_level.Value):
ob_signals += 1
if rsi <= float(self._rsi_lower_level.Value):
os_signals += 1
if stoch_k >= float(self._stochastic_upper_level.Value):
ob_signals += 1
if stoch_k <= float(self._stochastic_lower_level.Value):
os_signals += 1
if close >= upper:
ob_signals += 1
if close <= lower:
os_signals += 1
if os_signals >= 2 and self.Position <= 0:
self.BuyMarket()
elif ob_signals >= 2 and self.Position >= 0:
self.SellMarket()
elif self.Position > 0 and rsi > 50.0 and stoch_k > 50.0:
self.SellMarket()
elif self.Position < 0 and rsi < 50.0 and stoch_k < 50.0:
self.BuyMarket()
def CreateClone(self):
return rrs_impulse_strategy()