Ver en GitHub

Estrategia Neuro Nirvaman MQ4

Descripción general

La Estrategia Neuro Nirvaman MQ4 es una fiel adaptación del MetaTrader 4 asesor experto NeuroNirvaman.mq4. El robot original combina un filtro Laguerre personalizado aplicado al componente +DI del indicador ADX con un detector de ruptura SilverTrend. Tres perceptrones evalúan estas entradas y un supervisor decide si comprar o vender. La versión StockSharp refleja ese flujo de trabajo y ejecuta una posición a la vez, recalculando su lógica solo en velas completamente cerradas.

Cómo funciona la estrategia

  1. Feed de datos de mercado: la estrategia se suscribe a una única serie de velas definida por CandleType y procesa solo Finished velas. No evalúa eventos intrabar, replicando la verificación Time[0] utilizada en MT4.
  2. Suavizado Laguerre +DI: cuatro indicadores AverageDirectionalIndex proporcionan valores +DI que se envían a través de un filtro Laguerre (LaguerrePlusDiState) utilizando la gamma original de 0,764. El filtro produce valores de oscilador en el rango [0, 1] y cada flujo tiene su propio período ADX y ancho de zona neutral (Laguerre*Distance).
  3. Puerto SilverTrend: dos objetos SilverTrendState reproducen la lógica Sv2.mq4. Realizan un seguimiento del máximo más alto y del mínimo más bajo para SSP velas, reducen el canal con la constante Kmax = 50.6 y devuelven 1 para una tendencia alcista o -1 para una tendencia bajista. Las profundidades de retrospectiva están controladas por SilverTrend1Length y SilverTrend2Length.
  4. Perceptrones
    • Perceptron #1 mezcla la primera activación de Laguerre con el primer swing de SilverTrend usando los pesos X11 - 100 y X12 - 100.
    • Perceptron #2 combina la segunda activación de Laguerre con el segundo swing de SilverTrend y pesa X21 - 100 y X22 - 100.
    • Perceptron #3 evalúa la tercera y cuarta activaciones de Laguerre ponderadas por X31 - 100 y X32 - 100. Cada activación de Laguerre se cuantifica en -1, 0 o 1 dependiendo de su distancia del nivel de equilibrio 0,5.
  5. Supervisor (Pass) – El supervisor reproduce la función MQL Supervisor():
    • Pass = 3: requiere Perceptron #3 > 0. Si también es Perceptron #2 > 0, la estrategia compra utilizando el segundo conjunto TP/SL; de lo contrario, si es Perceptron #1 < 0, se vende utilizando el primer conjunto TP/SL.
    • Pass = 2: un Perceptron #2 positivo abre un largo con el segundo conjunto TP/SL, mientras que cualquier valor no positivo abre un corto con el primer conjunto.
    • Pass = 1: un Perceptron #1 negativo abre un corto, en caso contrario se abre un largo. Ambas ramas utilizan el primer conjunto TP/SL.
  6. Gestión de pedidos y riesgos: las inscripciones se envían con BuyMarket o SellMarket usando TradeVolume. Los niveles de toma de ganancias y límite de pérdidas se calculan como entry ± points * PriceStep. Debido a que StockSharp realiza órdenes de mercado puras, las salidas protectoras se simulan verificando los máximos y mínimos de las velas, exactamente como se activarían las órdenes TP/SL del lado del corredor en MT4.

Parámetros

Nombre Tipo Predeterminado Descripción
CandleType DataType plazo de 15 minutos Tipo de vela procesada por la estrategia.
TradeVolume decimal 0.1 Volumen de pedidos en lotes.
SilverTrend1Length int 7 Longitud retrospectiva para el primer cálculo de SilverTrend (SSP).
Laguerre1Period int 14 ADX período para la primera transmisión de Laguerre.
Laguerre1Distance decimal 0 Ancho de la zona neutral (porcentaje) alrededor de 0,5 para el arroyo Laguerre #1.
X11, X12 decimal 100 Pesos utilizados dentro del perceptrón n.° 1 (el código resta 100 antes de aplicarlos).
TakeProfit1, StopLoss1 decimal 100 / 50 Distancias de protección en puntos para el primer perfil de riesgo y todas las operaciones cortas.
SilverTrend2Length int 7 Longitud retrospectiva para el segundo cálculo de SilverTrend.
Laguerre2Period int 14 ADX período para la segunda transmisión de Laguerre.
Laguerre2Distance decimal 0 Ancho de la zona neutral (porcentaje) alrededor de 0,5 para el arroyo Laguerre #2.
X21, X22 decimal 100 Pesos utilizados dentro del perceptrón n.° 2.
TakeProfit2, StopLoss2 decimal 100 / 50 Distancias de protección en puntos para el segundo perfil de riesgo.
Laguerre3Period, Laguerre4Period int 14 ADX períodos para la tercera y cuarta transmisión de Laguerre.
Laguerre3Distance, Laguerre4Distance decimal 0 Anchos de la zona neutral (porcentaje) para la tercera y cuarta corriente Laguerre.
X31, X32 decimal 100 Pesos utilizados dentro del perceptrón n.° 3.
Pass int 3 Rama supervisora que selecciona qué perceptrones pueden activar operaciones.

Notas de uso

  • Los pesos predeterminados de 100 neutralizan la entrada del perceptrón correspondiente. Aleje los pesos de 100 para crear señales significativas.
  • SilverTrend comienza a devolver ±1 una vez que se recolectan suficientes velas. Hasta entonces, las salidas del perceptrón pueden permanecer en cero, emulando el comportamiento de MT4 donde iCustom devuelve cero antes de que los buffers estén listos.
  • Las comprobaciones de obtención de beneficios y limitación de pérdidas se basan en los extremos de las velas; Si se producen picos dentro de la vela entre barras, la simulación puede diferir ligeramente de la ejecución por parte del corredor.
  • Sólo puede existir una posición a la vez. Una nueva señal se ignora hasta que TP, SL o una decisión contraria cierren la posición actual.
  • Ajuste CandleType para reflejar el período del gráfico utilizado por la configuración MT4 original (por ejemplo, M15 o H1) para mantener constante la escala del indicador.
using System;

using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;

namespace StockSharp.Samples.Strategies;

/// <summary>
/// NeuroNirvaman: Perceptron-inspired strategy using RSI momentum
/// with EMA trend filter and weighted signal scoring.
/// </summary>
public class NeuroNirvamanMq4Strategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _rsiLength;
	private readonly StrategyParam<int> _fastEmaLength;
	private readonly StrategyParam<int> _slowEmaLength;
	private readonly StrategyParam<int> _atrLength;

	private decimal _prevRsi;
	private decimal _prevFast;
	private decimal _prevSlow;
	private decimal _entryPrice;

	public NeuroNirvamanMq4Strategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
			.SetDisplay("Candle Type", "Timeframe.", "General");

		_rsiLength = Param(nameof(RsiLength), 14)
			.SetDisplay("RSI Length", "RSI period.", "Indicators");

		_fastEmaLength = Param(nameof(FastEmaLength), 10)
			.SetDisplay("Fast EMA", "Fast EMA period.", "Indicators");

		_slowEmaLength = Param(nameof(SlowEmaLength), 30)
			.SetDisplay("Slow EMA", "Slow EMA period.", "Indicators");

		_atrLength = Param(nameof(AtrLength), 14)
			.SetDisplay("ATR Length", "ATR period.", "Indicators");
	}

	public DataType CandleType
	{
		get => _candleType.Value;
		set => _candleType.Value = value;
	}

	public int RsiLength
	{
		get => _rsiLength.Value;
		set => _rsiLength.Value = value;
	}

	public int FastEmaLength
	{
		get => _fastEmaLength.Value;
		set => _fastEmaLength.Value = value;
	}

	public int SlowEmaLength
	{
		get => _slowEmaLength.Value;
		set => _slowEmaLength.Value = value;
	}

	public int AtrLength
	{
		get => _atrLength.Value;
		set => _atrLength.Value = value;
	}

	/// <inheritdoc />
	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();

		_prevRsi = 0;
		_prevFast = 0;
		_prevSlow = 0;
		_entryPrice = 0;
	}

		protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);

		_prevRsi = 0;
		_prevFast = 0;
		_prevSlow = 0;
		_entryPrice = 0;

		var rsi = new RelativeStrengthIndex { Length = RsiLength };
		var fast = new ExponentialMovingAverage { Length = FastEmaLength };
		var slow = new ExponentialMovingAverage { Length = SlowEmaLength };
		var atr = new AverageTrueRange { Length = AtrLength };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(rsi, fast, slow, atr, ProcessCandle)
			.Start();

		var area = CreateChartArea();
		if (area != null)
		{
			DrawCandles(area, subscription);
			DrawIndicator(area, fast);
			DrawIndicator(area, slow);
			DrawOwnTrades(area);
		}
	}

	private void ProcessCandle(ICandleMessage candle, decimal rsiVal, decimal fastVal, decimal slowVal, decimal atrVal)
	{
		if (candle.State != CandleStates.Finished)
			return;

		if (_prevFast == 0 || _prevSlow == 0 || _prevRsi == 0 || atrVal <= 0)
		{
			_prevRsi = rsiVal;
			_prevFast = fastVal;
			_prevSlow = slowVal;
			return;
		}

		var close = candle.ClosePrice;

		// Perceptron score: weighted RSI momentum + EMA trend alignment
		var rsiSignal = rsiVal > 50 ? 1m : -1m;
		var trendSignal = fastVal > slowVal ? 1m : -1m;
		var rsiAccel = rsiVal - _prevRsi > 0 ? 1m : -1m;
		var score = rsiSignal * 0.4m + trendSignal * 0.4m + rsiAccel * 0.2m;

		// Exit management
		if (Position > 0)
		{
			if (close <= _entryPrice - atrVal * 2m || close >= _entryPrice + atrVal * 3m || score < -0.5m)
			{
				SellMarket();
				_entryPrice = 0;
			}
		}
		else if (Position < 0)
		{
			if (close >= _entryPrice + atrVal * 2m || close <= _entryPrice - atrVal * 3m || score > 0.5m)
			{
				BuyMarket();
				_entryPrice = 0;
			}
		}

		// Entry: strong perceptron score with RSI crossover confirmation
		if (Position == 0)
		{
			if (score > 0.5m && _prevRsi <= 50 && rsiVal > 50)
			{
				_entryPrice = close;
				BuyMarket();
			}
			else if (score < -0.5m && _prevRsi >= 50 && rsiVal < 50)
			{
				_entryPrice = close;
				SellMarket();
			}
		}

		_prevRsi = rsiVal;
		_prevFast = fastVal;
		_prevSlow = slowVal;
	}
}