Ver en GitHub

Estrategia de impulso RRS

La RRS Impulse Strategy es una versión StockSharp de alto nivel del MetaTrader asesor experto "RRS Impulse". El robot original filtros de bandas combinados RSI, Stochastic y Bollinger, rotados entre varios modos de intensidad de señal y paradas protectoras utilizadas y salidas finales virtuales. Esta versión de C# mantiene el mismo comportamiento pero se basa exclusivamente en el StockSharp nivel alto API: vela las suscripciones alimentan los indicadores, mientras que BuyMarket, SellMarket y ClosePosition ejecutan las órdenes.

Lógica de trading

  1. Modos de indicador: elija entre cuatro opciones:
    • Rsi: opera con el oscilador cuando sale de la zona de sobrecompra/sobreventa.
    • Stochastic: requiere que %K y %D estén por encima o por debajo de los niveles configurados.
    • BollingerBands: reacciona ante cierres por encima de la banda superior o por debajo de la banda inferior.
    • RsiStochasticBollinger: se activa solo cuando los tres filtros confirman la misma dirección.
  2. Dirección comercial: Trend sigue el indicador (la sobrecompra conduce a posiciones cortas, la sobreventa a posiciones largas). CounterTrend desvanece el movimiento (la sobrecompra desencadena posiciones largas, la sobreventa activa posiciones cortas).
  3. Intensidad de la señal: controla cuántos períodos de tiempo deben acordar antes de ingresar a una operación:
    • SingleTimeFrame: utilice únicamente el plazo base proporcionado por CandleType.
    • MultiTimeFrame: requiere alineación entre velas M1, M5, M15, M30, H1 y H4.
    • Strong: céntrese en el impulso intradiario marcando M1, M5, M15 y M30.
    • VeryStrong: exige confirmación de la escalera M1...H4 completa. Cuando el modo de indicador combinado está habilitado en cada período de tiempo debe satisfacer los tres filtros.
  4. Gestión de riesgos: cada posición rastrea el precio de ejecución promedio y monitorea tres condiciones de salida:
    • distancia fija de stop-loss en pips;
    • distancia fija de obtención de beneficios en pips;
    • trailing stop activado una vez que la ganancia excede TrailingStartPips y mantenido por TrailingGapPips. Siempre que la dirección cambia, la estrategia llama a ClosePosition() primero para aplanarse y solo abre la operación opuesta después el siguiente tick de confirmación.

Parámetros

grupo Nombre Descripción
Datos CandleType Serie de velas base procesadas para decisiones comerciales.
Órdenes TradeVolume Volumen utilizado al enviar órdenes de mercado.
Riesgo StopLossPips, TakeProfitPips, TrailingStartPips, TrailingGapPips Salidas protectoras virtuales expresadas en pips.
Señales IndicatorMode, TradeDirection, SignalStrength Cambios de comportamiento copiados del bloque de entrada MQL.
RSI RsiPeriod, RsiUpperLevel, RsiLowerLevel Configuración RSI para detección de sobrecompra/sobreventa.
Stochastic StochasticKPeriod, StochasticDPeriod, StochasticSlowing, StochasticUpperLevel, StochasticLowerLevel Configuraciones lentas del oscilador estocástico.
Bollinger BollingerPeriod, BollingerDeviation Bollinger Multiplicador de desviación y retroceso de bandas.

Todos los parámetros admiten rangos de optimización idénticos a la versión MetaTrader donde tenía sentido (por ejemplo, detenerse y tomar distancias). u umbrales del oscilador).

Requisitos de datos

La estrategia necesita velas diminutas para la escalera de confirmación. Cuando SignalStrength solicita plazos adicionales, la estrategia agrega automáticamente las suscripciones requeridas (GetWorkingSecurities las anuncia en el motor). No se utilizan comillas de nivel 1; sólo los precios de cierre de las velas terminadas impulsan las entradas y salidas. Por lo tanto, la lógica de protección reproduce la parada/objetivo "virtual". comportamiento del robot original.

Notas sobre la conversión

  • La rotación aleatoria de símbolos de EA se eliminó intencionalmente. Las estrategias StockSharp funcionan con un solo Security, por lo que el El puerto se concentra en hacer coincidir la lógica del indicador y la gestión de riesgos, dejando la rotación del instrumento en manos del usuario.
  • La gestión de órdenes se basa en el mercado: cuando la dirección cambia o se activa una condición de protección, se llama a ClosePosition(), reflejando los bucles MetaTrader que se repitieron a través de los tickets.
  • La conversión mantiene todos los comentarios en inglés y utiliza pestañas para sangría para cumplir con las pautas del repositorio.
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();
		}
	}
}