Auf GitHub ansehen

RPM5 BullsBearsEyes-Strategie

Überblick

Die RPM5 BullsBearsEyes Strategy ist eine C#-Portierung des MetaTrader 4-Experten Rpm5_mt4v1. Der Berater baute den benutzerdefinierten BullsBearsEyes-Oszillator anhand der Bulls Power- und Bears Power-Messwerte um und eröffnete eine einzelne Position, die der vorherrschenden Tendenz folgte. Diese StockSharp-Version reproduziert das gleiche Verhalten unter Verwendung des High-Level-API und behält dabei die ursprünglichen Risikoparameter, die nachgestellte Logik und die Signalschwellenwerte bei.

Rekonstruktion des Indikators

  • Zwei klassische Oszillatoren – Bulls Power und Bears Power – werden auf der konfigurierten Kerzenserie berechnet.
  • Ihre Summe durchläuft den identischen vierstufigen IIR-Glätter, der vom MT4-Indikator verwendet wird. Der Glättungsfaktor (Gamma) steuert, wie schnell der Oszillator reagiert.
  • Die gefilterte Ausgabe wird in einen Wert zwischen 0 und 1 umgewandelt. Werte über dem zentralen Schwellenwert signalisieren eine bullische Dominanz, Werte darunter deuten auf eine bärische Kontrolle hin. Eine exakte Null oder Eins erscheint, wenn eine Seite vollständig erschöpft ist, was den ursprünglichen Randfällen des Indikators entspricht.

Handelsregeln

  1. Die Strategie abonniert den ausgewählten Zeitrahmen (standardmäßig 5 Minuten) und wartet nur auf abgeschlossene Kerzen.
  2. Im flachen Zustand wird das BullsBearsEyes-Verhältnis ausgewertet:
    • Langer Eintrag – aktueller Wert streng über Threshold (Standard 0,5).
    • Kurzer Eintrag – aktueller Wert strikt unter dem Threshold.
    • Der Algorithmus behält höchstens eine offene Position. Gegensignale werden ignoriert, bis die aktive Position durch das Risikomanagement vollständig geschlossen ist.
  3. Sobald ein Trade abgeschlossen ist, bleibt die Position unberührt, bis ein Stop-Loss-, Take-Profit- oder Trailing-Stop-Ereignis eintritt.

Risikomanagement

  • Stop-Loss-/Take-Profit-Abstände werden anhand der ursprünglichen 25/150-Pip-Einstellungen wiederhergestellt. Sie werden mit dem Instrument PriceStep (Pip) jedes Mal neu berechnet, wenn eine neue Position eröffnet wird.
  • ATR nachlaufend: Bei jeder fertigen Kerze wird der Average True Range (Zeitraum AtrPeriod, Standard 5) ausgewertet. Die Nachlaufdistanz entspricht einem Pip plus AtrMultiplier × ATR. Wenn der Abschluss über diesen Abstand hinausgeht, wird der Schutzanschlag verschärft, um die Lücke aufrechtzuerhalten, identisch mit der MQL-Logik, die wiederholt OrderModify aufgerufen hat.
  • Schutzstufen werden vor der Verarbeitung neuer Signale überprüft, um sicherzustellen, dass Exits immer Vorrang vor neuen Einträgen haben, genau wie in der Quelle EA.

Parameter

Name Standard Beschreibung
Bulls/Bears Period 13 Mittelungszeitraum für die Indikatoren Bulls Power und Bears Power.
Gamma 0,5 Vierstufiges IIR-Glättungsverhältnis für den BullsBearsEyes-Oszillator.
Threshold 0,5 Trennlinie zwischen bullischen (> Schwellenwert) und bärischen (< Schwellenwert) Zonen.
ATR Period 5 Lookback, der für den ATR-basierten Trailing Stop verwendet wird.
ATR Multiplier 1.5 Beim Ableiten der Nachlaufstrecke wird ein Multiplikator auf ATR angewendet.
Stop Loss (pips) 25 Schutzstoppdistanz, umgerechnet von Pips in Preis.
Take Profit (pips) 150 Gewinnzielentfernung, umgerechnet von Pips in Preis.
Trade Volume 1 Market-Order-Volumen, das für jede neue Position verwendet wird.
Candle Type 5-Minuten-Kerzen Von der Strategie verarbeiteter Zeitrahmen.

Notizen

  • Der Port zeichnet nicht die visuellen täglichen Kanalobjekte, die in MT4 vorhanden waren, da sie nur kosmetischer Natur waren.
  • Alle Kommentare im Code sind wie gewünscht in Englisch verfasst.
  • Die Tests bleiben unverändert; Führen Sie die vorhandenen Lösungsebenenprüfungen durch, wenn eine Validierung erforderlich ist.
using System;
using System.Collections.Generic;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// RPM5 Bulls Bears Eyes strategy using Bull/Bear power with EMA filter.
/// Buy when bull power is positive and bear power crosses above threshold.
/// Sell when bear power is negative and bull power crosses below threshold.
/// </summary>
public class Rpm5BullsBearsEyesStrategy : Strategy
{
	private readonly StrategyParam<int> _emaPeriod;
	private readonly StrategyParam<int> _powerPeriod;
	private readonly StrategyParam<DataType> _candleType;

	private decimal _prevBull;
	private decimal _prevBear;
	private bool _hasPrev;

	public int EmaPeriod { get => _emaPeriod.Value; set => _emaPeriod.Value = value; }
	public int PowerPeriod { get => _powerPeriod.Value; set => _powerPeriod.Value = value; }
	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }

	public Rpm5BullsBearsEyesStrategy()
	{
		_emaPeriod = Param(nameof(EmaPeriod), 13)
			.SetDisplay("EMA Period", "EMA trend period", "Indicators");

		_powerPeriod = Param(nameof(PowerPeriod), 13)
			.SetDisplay("Power Period", "Bulls/Bears power period", "Indicators");

		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
			.SetDisplay("Candle Type", "Candle timeframe", "General");
	}

	/// <inheritdoc />
	public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
	{
		return [(Security, CandleType)];
	}

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

		_prevBull = 0m;
		_prevBear = 0m;
		_hasPrev = false;
	}

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);

		_hasPrev = false;

		var ema = new ExponentialMovingAverage { Length = EmaPeriod };
		var bulls = new BullPower { Length = PowerPeriod };
		var bears = new BearPower { Length = PowerPeriod };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(ema, bulls, bears, ProcessCandle)
			.Start();
	}

	private void ProcessCandle(ICandleMessage candle, decimal emaValue, decimal bullValue, decimal bearValue)
	{
		if (candle.State != CandleStates.Finished)
			return;

		if (!_hasPrev)
		{
			_prevBull = bullValue;
			_prevBear = bearValue;
			_hasPrev = true;
			return;
		}

		// Long: price above EMA, bull power positive, bear power crossing from negative to less negative
		var longSignal = candle.ClosePrice > emaValue && bullValue > 0 && _prevBear < 0 && bearValue > _prevBear;
		// Short: price below EMA, bear power negative, bull power crossing from positive to less positive
		var shortSignal = candle.ClosePrice < emaValue && bearValue < 0 && _prevBull > 0 && bullValue < _prevBull;

		if (Position <= 0 && longSignal)
		{
			if (Position < 0)
				BuyMarket();
			BuyMarket();
		}
		else if (Position >= 0 && shortSignal)
		{
			if (Position > 0)
				SellMarket();
			SellMarket();
		}

		_prevBull = bullValue;
		_prevBear = bearValue;
	}
}