Auf GitHub ansehen

Neuro Nirvaman MQ4-Strategie

Überblick

Die Neuro Nirvaman MQ4-Strategie ist eine originalgetreue Umsetzung des MetaTrader 4-Expertenberaters NeuroNirvaman.mq4. Der ursprüngliche Roboter kombiniert einen benutzerdefinierten Laguerre-Filter, der auf die +DI-Komponente des ADX-Indikators angewendet wird, mit einem SilverTrend-Breakout-Detektor. Drei Perzeptrone werten diese Eingaben aus und ein Supervisor entscheidet über Kauf oder Verkauf. Die StockSharp-Version spiegelt diesen Workflow wider und führt jeweils eine Position aus, wobei ihre Logik nur bei vollständig geschlossenen Kerzen neu berechnet wird.

Wie die Strategie funktioniert

  1. Marktdaten-Feed – Die Strategie abonniert eine einzelne Kerzenserie, die durch CandleType definiert wird, und verarbeitet nur Finished Kerzen. Es wertet keine Intrabar-Ereignisse aus und repliziert die in MT4 verwendete Time[0]-Prüfung.
  2. Laguerre +DI-Glättung – Vier AverageDirectionalIndex-Indikatoren liefern +DI-Werte, die unter Verwendung des ursprünglichen Gammas von 0,764 durch einen Laguerre-Filter (LaguerrePlusDiState) gesendet werden. Der Filter liefert Oszillatorwerte im [0, 1]-Bereich und jeder Strom hat seine eigene ADX-Periode und neutrale Zonenbreite (Laguerre*Distance).
  3. SilverTrend-Port – Zwei SilverTrendState-Objekte reproduzieren die Sv2.mq4-Logik. Sie verfolgen das höchste Hoch und das niedrigste Tief für SSP-Kerzen, verkleinern den Kanal mit der Konstante Kmax = 50.6 und geben 1 für einen Aufwärtstrend oder -1 für einen Abwärtstrend zurück. Die Lookback-Tiefen werden durch SilverTrend1Length und SilverTrend2Length gesteuert.
  4. Perzeptrone
    • Perceptron #1 mischt die erste Laguerre-Aktivierung mit dem ersten SilverTrend-Schwung unter Verwendung der Gewichte X11 - 100 und X12 - 100.
    • Perceptron #2 kombiniert die zweite Laguerre-Aktivierung mit dem zweiten SilverTrend-Schwung und den Gewichten X21 - 100 und X22 - 100.
    • Perceptron #3 wertet die dritte und vierte Laguerre-Aktivierung gewichtet mit X31 - 100 und X32 - 100 aus. Jede Laguerre-Aktivierung wird je nach Abstand vom 0,5-Gleichgewichtsniveau zu -1, 0 oder 1 quantisiert.
  5. Supervisor (Pass) – Der Supervisor reproduziert die Funktion MQL Supervisor():
    • Pass = 3: erfordert Perceptron #3 > 0. Wenn auch Perceptron #2 > 0, kauft die Strategie mit dem zweiten TP/SL-Satz; andernfalls, wenn Perceptron #1 < 0, wird mit dem ersten TP/SL-Set verkauft.
    • Pass = 2: Ein positiver Perceptron #2 eröffnet eine Long-Position mit dem zweiten TP/SL-Satz, während jeder nicht positive Wert eine Short-Position mit dem ersten Satz eröffnet.
    • Pass = 1: Ein negativer Perceptron #1 eröffnet einen Short, andernfalls wird ein Long eröffnet. Beide Zweige verwenden den ersten TP/SL-Satz.
  6. Auftrags- und Risikomanagement – Einträge werden mit BuyMarket oder SellMarket mit TradeVolume gesendet. Take-Profit- und Stop-Loss-Level werden als entry ± points * PriceStep berechnet. Da StockSharp reine Marktaufträge platziert, werden Schutzausstiege durch die Überprüfung von Kerzenhochs und -tiefs simuliert, genau wie TP/SL-Aufträge auf Brokerseite in MT4 ausgelöst würden.

Parameter

Name Typ Standard Beschreibung
CandleType DataType 15-minütiger Zeitrahmen Von der Strategie verarbeiteter Kerzentyp.
TradeVolume decimal 0,1 Bestellvolumen in Losen.
SilverTrend1Length int 7 Lookback-Länge für die erste SilverTrend-Berechnung (SSP).
Laguerre1Period int 14 ADX Zeitraum für den ersten Laguerre-Stream.
Laguerre1Distance decimal 0 Die Breite der neutralen Zone (Prozent) beträgt etwa 0,5 für den Laguerre-Strom Nr. 1.
X11, X12 decimal 100 Gewichte, die im Perzeptron Nr. 1 verwendet werden (der Code subtrahiert 100, bevor er sie anwendet).
TakeProfit1, StopLoss1 decimal 100 / 50 Schutzabstände in Punkten für das erste Risikoprofil und alle Short-Trades.
SilverTrend2Length int 7 Lookback-Länge für die zweite SilverTrend-Berechnung.
Laguerre2Period int 14 ADX Zeitraum für den zweiten Laguerre-Stream.
Laguerre2Distance decimal 0 Die Breite der neutralen Zone (Prozent) beträgt etwa 0,5 für den Laguerre-Strom Nr. 2.
X21, X22 decimal 100 Gewichte, die im Perzeptron Nr. 2 verwendet werden.
TakeProfit2, StopLoss2 decimal 100 / 50 Schutzabstände in Punkten für das zweite Risikoprofil.
Laguerre3Period, Laguerre4Period int 14 ADX Perioden für den dritten und vierten Laguerre-Strom.
Laguerre3Distance, Laguerre4Distance decimal 0 Breiten der neutralen Zone (Prozent) für den dritten und vierten Laguerre-Strom.
X31, X32 decimal 100 Gewichte, die im Perzeptron Nr. 3 verwendet werden.
Pass int 3 Supervisor-Zweig, der auswählt, welche Perzeptrone Trades auslösen können.

Nutzungshinweise

  • Standardgewichte von 100 neutralisieren die entsprechende Perzeptron-Eingabe. Bewegen Sie die Gewichte von 100 weg, um aussagekräftige Signale zu erzeugen.
  • SilverTrend beginnt mit der Rückgabe von ±1, sobald genügend Kerzen gesammelt wurden. Bis dahin können die Perceptron-Ausgaben auf Null bleiben und das MT4-Verhalten nachahmen, bei dem iCustom Null zurückgibt, bevor die Puffer bereit sind.
  • Take-Profit- und Stop-Loss-Checks basieren auf Candle-Extremen; Wenn zwischen den Balken Intra-Candle-Spitzen auftreten, kann die Simulation leicht von der Ausführung auf Brokerseite abweichen.
  • Es kann jeweils nur eine Position existieren. Ein neues Signal wird ignoriert, bis die aktuelle Position entweder durch TP, SL oder eine gegenteilige Entscheidung geschlossen wird.
  • Passen Sie CandleType an, um den vom ursprünglichen MT4-Setup verwendeten Diagrammzeitraum (z. B. M15 oder H1) widerzuspiegeln, um die Skalierung des Indikators konsistent zu halten.
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;
	}
}