Auf GitHub ansehen

Trickerless RHMP-Strategie (StockSharp Port)

Diese Strategie portiert den Expertenberater Trickerless RHMP von MetaTrader auf das hohe Niveau von StockSharp API. Es bleibt die Mehrstufigigkeit erhalten Eingabelogik des ursprünglichen Roboters – Kombination aus Bestätigung des durchschnittlichen Richtungsindex, geglätteter gleitender Durchschnittsstruktur und Volatilitätsgesteuertes Positionsmanagement – unter Einhaltung der in AGENTS.md dokumentierten Rahmenkonventionen.

Handelslogik

  1. Indikatoren

    • Durchschnittlicher wahrer Bereich (ATR) mit konfigurierbarem Zeitraum für die Volatilitätsgröße.
    • Durchschnittlicher Richtungsindex (ADX) mit vollständigen +DI/-DI-Komponenten zur Qualifizierung der Trendstärke.
    • Zwei geglättete gleitende Durchschnitte (SMMA), die die schnellen und langsamen Trendfilter darstellen.
  2. Trendauswertung

    • Die langsame SMMA-Steigung muss innerhalb des MinSlopePipsMaxSlopePips-Korridors liegen (gemessen in Instrumenten-Pips).
    • ADX muss AdxThreshold überschreiten und im Vergleich zur vorherigen Kerze steigen.
    • Der Preis muss mindestens TrendSpacePips vom schnellen SMMA entfernt bleiben, um eine Überlastung zu vermeiden.
    • Eine bullische Tendenz erfordert den schnellen SMMA über dem langsamen SMMA, +DI ≥ -DI und einen steigenden schnellen Durchschnitt. Die bärische Tendenz spiegelt dies wider Schecks.
  3. Primäre Einträge

    • Wenn die bullische (oder bärische) Tendenz aktiv ist, eröffnet die Strategie eine Long- (oder Short-)Order mit einem Volumen von OrderVolume MaxNetPositions und mindestens SleepInterval Wartezeit zwischen den Einträgen.
    • Wenn eine entgegengesetzte Nettoposition vorhanden ist, wird diese zunächst abgeflacht, um die Absicherung deaktiviert zu halten.
  4. Spike-Einträge

    • Wenn die aktuelle Kerzenspanne das CandleSpikeMultiplier-fache der vorherigen Spanne überschreitet, kann die Strategie eine Hilfskerze auslösen Position in Richtung des Kerzenkörpers, wenn die ADX-Komponenten übereinstimmen. Die Position verwendet OrderVolume * SpikeVolumeMultiplier.

Risikomanagement

  • ATR-basierter Stop-Loss, Take-Profit und optionaler Trailing-Stop (StopLossAtrMultiplier, TakeProfitAtrMultiplier, TrailingAtrMultiplier).
  • Sitzungsweiter Schutz: Sobald der realisierte PnL DailyProfitTarget (Bruchteil des Startkapitals) erreicht, werden neue Einträge blockiert.
  • Der globale Notschalter EmergencyExit schließt beim Umschalten sofort alle Positionen.

Parameter

Name Beschreibung Standard
CandleType Für alle Berechnungen verwendeter Zeitrahmen. 5-Minuten-Kerzen
OrderVolume Basisvolumen für jeden Eintrag. 0,03
AtrPeriod ATR Lookback-Länge. 14
AdxPeriod ADX Lookback-Länge. 14
AdxThreshold Mindestwert von ADX, um den Handel zu ermöglichen. 10
FastMaPeriod Schnelle geglättete gleitende Durchschnittsperiode. 60
SlowMaPeriod Langsam geglätteter Zeitraum des gleitenden Durchschnitts. 120
MinSlopePips / MaxSlopePips Zulässiger Steigungskorridor für den langsamen SMMA. 2 / 9
TrendSpacePips Minimaler Preisabstand zum schnellen SMMA (in Pips). 5
CandleSpikeMultiplier Wie viel größer muss die Kerzenspanne sein, um Spitzeneinträge auszulösen? 7
TakeProfitAtrMultiplier ATR Vielfache für Take-Profit. 1,0
StopLossAtrMultiplier ATR Vielfache für Stop-Loss. 1.5
TrailingAtrMultiplier ATR Vielfache für Trailing-Stop (0 deaktiviert). 0
MaxNetPositions Maximale Anzahl gleichzeitiger Nettopositionseinheiten. 1
SleepInterval Mindestzeit zwischen aufeinanderfolgenden Einträgen. 24 Minuten
DailyProfitTarget Bruchteil des anfänglichen Eigenkapitals, der den Handel blockiert, sobald er erreicht ist. 0,045
AllowNewEntries Hauptschalter zum Aktivieren/Deaktivieren von Einträgen. wahr
SpikeVolumeMultiplier Volumenmultiplikator für Spitzeneinträge. 1,0
EmergencyExit Schließt alle Positionen sofort, wenn wahr. falsch

Notizen

  • Der StockSharp-Port konzentriert sich auf die saubere, hohe Ebene API anstelle der Ticket-für-Ticket-Mikroverwaltung von MetaTrader. Alle Die Geldverwaltungslogik wird über Volume- und ATR-basierte Ebenen implementiert.
  • Das Original EA hatte mehrere Saldo- und Margenprüfungen. Diese werden mit DailyProfitTarget, MaxNetPositions angenähert. und ATR Größenparameter, damit das Verhalten ohne direkte MT4-Kontoaufrufe angepasst bleibt.
  • Da die Strategie geglättete Durchschnittswerte verwendet, stellen Sie sicher, dass eine ausreichende Aufwärmphase vorhanden ist, bevor Sie Trades bewerten.
using System;

using Ecng.Common;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// Simplified from "Trickerless RHMP" MetaTrader expert.
/// Uses fast/slow EMA crossover for entries.
/// Fast EMA above slow = buy, below = sell.
/// </summary>
public class TrickerlessRhmpStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _fastMaPeriod;
	private readonly StrategyParam<int> _slowMaPeriod;

	private ExponentialMovingAverage _fastMa;
	private ExponentialMovingAverage _slowMa;
	private decimal? _prevFast;
	private decimal? _prevSlow;

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

	public int FastMaPeriod
	{
		get => _fastMaPeriod.Value;
		set => _fastMaPeriod.Value = value;
	}

	public int SlowMaPeriod
	{
		get => _slowMaPeriod.Value;
		set => _slowMaPeriod.Value = value;
	}

	public TrickerlessRhmpStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(60).TimeFrame())
			.SetDisplay("Candle Type", "Primary timeframe", "General");

		_fastMaPeriod = Param(nameof(FastMaPeriod), 20)
			.SetGreaterThanZero()
			.SetDisplay("Fast MA", "Fast EMA period", "Indicators");

		_slowMaPeriod = Param(nameof(SlowMaPeriod), 50)
			.SetGreaterThanZero()
			.SetDisplay("Slow MA", "Slow SMA period (computed manually)", "Indicators");
	}

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

		_prevFast = null;
		_prevSlow = null;

		_fastMa = new ExponentialMovingAverage { Length = FastMaPeriod };
		_slowMa = new ExponentialMovingAverage { Length = SlowMaPeriod };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(_fastMa, _slowMa, ProcessCandle)
			.Start();

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

	private void ProcessCandle(ICandleMessage candle, decimal fastValue, decimal slowValue)
	{
		if (candle.State != CandleStates.Finished)
			return;

		if (!_fastMa.IsFormed || !_slowMa.IsFormed)
		{
			_prevFast = fastValue;
			_prevSlow = slowValue;
			return;
		}

		if (_prevFast is null || _prevSlow is null)
		{
			_prevFast = fastValue;
			_prevSlow = slowValue;
			return;
		}

		var volume = Volume;
		if (volume <= 0)
			volume = 1;

		var crossUp = _prevFast.Value <= _prevSlow.Value && fastValue > slowValue;
		var crossDown = _prevFast.Value >= _prevSlow.Value && fastValue < slowValue;

		if (crossUp)
		{
			if (Position <= 0)
				BuyMarket(Position < 0 ? Math.Abs(Position) + volume : volume);
		}
		else if (crossDown)
		{
			if (Position >= 0)
				SellMarket(Position > 0 ? Math.Abs(Position) + volume : volume);
		}

		_prevFast = fastValue;
		_prevSlow = slowValue;
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		_fastMa = null;
		_slowMa = null;
		_prevFast = null;
		_prevSlow = null;

		base.OnReseted();
	}
}