Ver no GitHub

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

  1. 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.
  2. Direção de negociaçãoTrend 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).
  3. 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.
  4. 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();
		}
	}
}