GitHub で見る

ニューロ ニルヴァマン MQ4 攻略

概要

Neuro Nirvaman MQ4 Strategy は、MetaTrader 4 エキスパート アドバイザー NeuroNirvaman.mq4 を忠実に移植したものです。オリジナルのロボットは、ADX インジケーターの +DI コンポーネントに適用されるカスタム ラゲール フィルターと SilverTrend ブレイクアウト検出器を組み合わせています。 3 つのパーセプトロンがこれらの入力を評価し、スーパーバイザーが売買を決定します。 StockSharp バージョンはそのワークフローを反映し、一度に 1 つのポジションを実行し、完全に閉じたローソク足でのみロジックを再計算します。

戦略の仕組み

  1. 市場データ フィード – この戦略は、CandleType によって定義された単一のローソク足シリーズをサブスクライブし、Finished 個のローソク足のみを処理します。これはバー内イベントを評価せず、MT4 で使用される Time[0] チェックを複製します。
  2. ラゲール +DI スムージング – 4 つの AverageDirectionalIndex インジケーターは、元のガンマ 0.764 を使用してラゲール フィルター (LaguerrePlusDiState) を通じて送信される +DI 値を提供します。フィルターは [0, 1] 範囲のオシレーター値を生成し、各ストリームには独自の ADX 周期とニュートラル ゾーン幅 (Laguerre*Distance) があります。
  3. SilverTrend ポート – 2 つの SilverTrendState オブジェクトは Sv2.mq4 ロジックを再現します。これらは、SSP ローソク足の最高値と最低安値を追跡し、定数 Kmax = 50.6 でチャネルを縮小し、上昇トレンドの場合は 1、下降トレンドの場合は -1 を返します。ルックバックの深さは、SilverTrend1LengthSilverTrend2Length によって制御されます。
  4. パーセプトロン
    • パーセプトロン #1 は、重み X11 - 100X12 - 100 を使用して、最初の Laguerre アクティベーションと最初の SilverTrend スイングを混合します。
    • パーセプトロン #2 は、2 番目の Laguerre アクティベーションと 2 番目の SilverTrend スイングを組み合わせて、X21 - 100X22 - 100 を重み付けします。
    • パーセプトロン #3 は、X31 - 100X32 - 100 によって重み付けされた 3 番目と 4 番目のラゲール アクティベーションを評価します。 各ラゲール活性化は、0.5 平衡レベルからの距離に応じて、-10、または 1 に量子化されます。
  5. スーパーバイザー (Pass) – スーパーバイザーは、MQL Supervisor() 関数を再現します。
    • Pass = 3: Perceptron #3 > 0 が必要です。 Perceptron #2 > 0 の場合、戦略は 2 番目の TP/SL セットを使用して購入します。それ以外の場合、Perceptron #1 < 0 の場合は、最初の TP/SL セットを使用して販売されます。
    • Pass = 2: 正の Perceptron #2 は 2 番目の TP/SL セットでロングを開きますが、正でない値は最初のセットでショートを開きます。
    • Pass = 1: 負の Perceptron #1 はショートをオープンし、それ以外の場合はロングをオープンします。どちらのブランチも最初の TP/SL セットを使用します。
  6. 注文とリスク管理 – エントリは、TradeVolume を使用して、BuyMarket または SellMarket で送信されます。テイクプロフィットとストップロスのレベルは entry ± points * PriceStep として計算されます。 StockSharp は純粋な成行注文を行うため、ブローカー側の TP/SL 注文が MT4 でトリガーされるのとまったく同じように、ローソク足の高値と安値をチェックすることで保護的出口がシミュレートされます。

パラメーター

名前 種類 デフォルト 説明
CandleType DataType 15分の時間枠 戦略によって処理されるキャンドル タイプ。
TradeVolume decimal 0.1 ロット単位での注文量。
SilverTrend1Length int 7 最初の SilverTrend 計算 (SSP) のルックバック長。
Laguerre1Period int 14 最初のラゲール ストリームの ADX 期間。
Laguerre1Distance decimal 0 ラゲール ストリーム #1 のニュートラル ゾーン幅 (パーセント) は約 0.5。
X11, X12 decimal 100 パーセプトロン #1 内で使用される重み (コードは適用する前に 100 を減算します)。
TakeProfit1, StopLoss1 decimal 100 / 50 最初のリスクプロファイルとすべてのショートトレードのポイント単位の保護距離。
SilverTrend2Length int 7 2 番目の SilverTrend 計算のルックバック長。
Laguerre2Period int 14 2 番目のラゲール ストリームの ADX 期間。
Laguerre2Distance decimal 0 ラゲール ストリーム #2 のニュートラル ゾーン幅 (パーセント) は約 0.5。
X21, X22 decimal 100 パーセプトロン #2 内で使用される重み。
TakeProfit2, StopLoss2 decimal 100 / 50 2 番目のリスク プロファイルの保護距離 (ポイント単位)。
Laguerre3Period, Laguerre4Period int 14 3 番目と 4 番目のラゲール ストリームの ADX 期間。
Laguerre3Distance, Laguerre4Distance decimal 0 3 番目と 4 番目のラゲール ストリームのニュートラル ゾーン幅 (パーセント)。
X31, X32 decimal 100 パーセプトロン #3 内で使用される重み。
Pass int 3 どのパーセプトロンが取引をトリガーできるかを選択するスーパーバイザー ブランチ。

使用上の注意

  • デフォルトの重み 100 は、対応するパーセプトロン入力を中和します。重みを 100 から遠ざけて、意味のある信号を作成します。
  • 十分なキャンドルが収集されると、SilverTrend は ±1 を返し始めます。それまでは、パーセプトロンの出力はゼロのままで、バッファの準備ができる前に iCustom がゼロを返す MT4 の動作をエミュレートします。
  • テイクプロフィットとストップロスのチェックはローソク足の極値に依存します。ローソク足内スパイクがバー間で発生した場合、シミュレーションはブローカー側の実行からわずかに乖離する可能性があります。
  • 一度に存在できるポジションは 1 つだけです。新しいシグナルは、TP、SL、または反対の決定によって現在のポジションがクローズされるまで無視されます。
  • CandleType を調整して、元の MT4 設定 (M15 や H1 など) で使用されているチャート期間を反映し、インジケーターのスケーリングの一貫性を保ちます。
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;
	}
}