Auf GitHub ansehen

Open Oscillator Cloud MMRec-Strategie

Diese Strategie portiert den MetaTrader-Expertenberater Exp_Open_Oscillator_Cloud_MMRec auf die StockSharp High-Level-API. Das System handelt den Kreuzungspunkt des Open Oscillator Cloud-Indikators, der den aktuellen Eröffnungskurs mit den Eröffnungskursen der höchsten und niedrigsten Balken innerhalb eines gleitenden Fensters vergleicht und das Ergebnis mit einem konfigurierbaren gleitenden Durchschnitt glättet.

Strategie-Logik

Indikator-Konstruktion

  • Ein Rückblickfenster (Oscillator Period, Standard 20 Balken) abgeschlossener Kerzen vom gewählten Zeitrahmen wird erstellt.
  • Der Balken mit dem höchsten Hoch wird gefunden und sein Eröffnungskurs gespeichert; der Balken mit dem niedrigsten Tief wird gefunden und sein Eröffnungskurs gespeichert.
  • Zwei Rohwerte für die aktuelle Kerze werden berechnet:
    • Oberes Band = aktuelle Eröffnung − Eröffnungskurs beim höchsten Hoch.
    • Unteres Band = Eröffnungskurs beim niedrigsten Tief − aktuelle Eröffnung.
  • Beide Serien werden mit dem gewählten gleitenden Durchschnitt geglättet (Smoothing Method, Smoothing Length). Unterstützte Typen sind Einfache, Exponentielle, Geglättete und Gewichtete gleitende Durchschnitte.
  • Die geglättete Historie wird gespeichert und das Signal um Signal Bar vollständig geschlossene Kerzen (Standard 1) verzögert, um die ursprüngliche EA-Logik nachzuahmen, die auf dem vorherigen Balken agiert.

Einstiegskriterien

  • Long-Einstieg: Das obere Band des vorherigen Balkens lag über dem unteren Band, und der letzte verzögerte Wert kreuzt nach unten (upper ≤ lower). Kann über Enable Long Entries deaktiviert werden.
  • Short-Einstieg: Das obere Band des vorherigen Balkens lag unter dem unteren Band, und der letzte verzögerte Wert kreuzt nach oben (upper ≥ lower). Kann über Enable Short Entries deaktiviert werden.

Ausstiegskriterien

  • Long-Ausstieg: Das obere Band des vorherigen Balkens lag unter dem unteren Band, was ein bearishes Regime signalisiert. Gesteuert durch Enable Long Exits.
  • Short-Ausstieg: Das obere Band des vorherigen Balkens lag über dem unteren Band, was ein bullishes Regime signalisiert. Gesteuert durch Enable Short Exits.
  • Risikomanagement: Wenn Stop Loss Points oder Take Profit Points größer als null sind, schließt die Strategie die Position automatisch, sobald der Preis diese Abstände (gemessen in Instrument-Preisschritten) vom Einstieg erreicht.

Order-Handling

  • Es werden nur Marktorders verwendet. Vor dem Öffnen einer neuen Position wird die entgegengesetzte Seite geglättet, um mit dem Einzelpositions-Verhalten des MetaTrader-Roboters ausgerichtet zu bleiben.
  • Der Parameter Trade Volume legt die Basis-Positionsgröße für jeden Einstieg fest.

Parameter

  • Candle Type – Zeitrahmen der für den Oszillator verwendeten Kerzen (Standard 1 Stunde).
  • Oscillator Period – Anzahl der Kerzen im gleitenden Fenster (Standard 20).
  • Smoothing Method – Auf die Eröffnungslücken angewandter gleitender Durchschnitt (Simple, Exponential, Smoothed, Weighted).
  • Smoothing Length – Länge des glättenden gleitenden Durchschnitts (Standard 10).
  • Signal Bar – Anzahl vollständig geschlossener Balken zur Verzögerung der Signalauswertung (Standard 1).
  • Enable Long Entries / Enable Short Entries – Erlaubt oder blockiert das Öffnen von Trades in jede Richtung.
  • Enable Long Exits / Enable Short Exits – Erlaubt oder blockiert automatische Ausstiege für die jeweilige Richtung.
  • Trade Volume – Größe jeder Marktorder (Standard 1 Kontrakt/Lot).
  • Stop Loss Points – Schützender Stop-Abstand in Preisschritten (0 deaktiviert den Stop, Standard 1000).
  • Take Profit Points – Gewinnziel-Abstand in Preisschritten (0 deaktiviert das Ziel, Standard 2000).

Implementierungshinweise

  • Die Glättungsmethoden entsprechen den gängigsten Optionen des ursprünglichen EA. Exotische Modi wie JJMA, T3, VIDYA oder AMA werden nicht portiert, da StockSharp bereits reichhaltige Alternativen für Optimierung und Robustheit bietet.
  • Signale werden nur bei CandleStates.Finished-Ereignissen ausgewertet, um nicht auf unvollständige Daten zu reagieren.
  • Die Strategie hält eine interne Historie geglätteter Werte, anstatt Indikator-Puffer abzufragen, was dem empfohlenen High-Level-StockSharp-Workflow entspricht.
  • Schutzlevels werden automatisch gelöscht, wenn die Position flach wird, um zu verhindern, dass veraltete Stops Trades wieder eröffnen.

Standardverhalten

  • Trendfolge in beide Richtungen mit verzögerter Bestätigung zur Rauschreduzierung.
  • Verwendet festes Money-Management (konstantes Trade Volume) unter Einhaltung von Stop-Loss- und Take-Profit-Abständen ähnlich der MetaTrader-Version.
  • Geeignet als Vorlage zum Experimentieren mit verschiedenen Glättungstypen oder zur Kombination des Oszillators mit zusätzlichen Filtern.
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>
/// Open oscillator cloud strategy using EMA crossover as trend proxy.
/// </summary>
public class OpenOscillatorCloudMmrecStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _fastPeriod;
	private readonly StrategyParam<int> _slowPeriod;

	private decimal? _prevFast;
	private decimal? _prevSlow;

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

	public int FastPeriod
	{
		get => _fastPeriod.Value;
		set => _fastPeriod.Value = value;
	}

	public int SlowPeriod
	{
		get => _slowPeriod.Value;
		set => _slowPeriod.Value = value;
	}

	public OpenOscillatorCloudMmrecStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame())
			.SetDisplay("Candle Type", "Timeframe", "General");

		_fastPeriod = Param(nameof(FastPeriod), 10)
			.SetGreaterThanZero()
			.SetDisplay("Fast Period", "Fast EMA period", "Indicators");

		_slowPeriod = Param(nameof(SlowPeriod), 30)
			.SetGreaterThanZero()
			.SetDisplay("Slow Period", "Slow EMA period", "Indicators");
	}

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

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_prevFast = null;
		_prevSlow = null;
	}

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

		_prevFast = null;
		_prevSlow = null;

		var fastEma = new ExponentialMovingAverage { Length = FastPeriod };
		var slowEma = new ExponentialMovingAverage { Length = SlowPeriod };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(fastEma, slowEma, ProcessCandle)
			.Start();

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

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

		if (!IsFormedAndOnlineAndAllowTrading())
		{
			_prevFast = fast;
			_prevSlow = slow;
			return;
		}

		if (_prevFast == null || _prevSlow == null)
		{
			_prevFast = fast;
			_prevSlow = slow;
			return;
		}

		var prevAbove = _prevFast.Value > _prevSlow.Value;
		var currAbove = fast > slow;

		_prevFast = fast;
		_prevSlow = slow;

		if (!prevAbove && currAbove)
		{
			if (Position < 0)
				BuyMarket();
			if (Position <= 0)
				BuyMarket();
		}
		else if (prevAbove && !currAbove)
		{
			if (Position > 0)
				SellMarket();
			if (Position >= 0)
				SellMarket();
		}
	}
}