Auf GitHub ansehen

Casino111-Strategie

Überblick

Casino111 ist ein Gegentrend-Breakout-System, das vom gleichnamigen MetaTrader 4-Expertenberater stammt. Bei jedem neuen Balken vergleicht die Strategie den aktuellen Eröffnungspreis mit Referenzniveaus, die von der vorherigen Tageskerze abgeleitet wurden. Wenn die offenen Lücken über die täglichen Extremwerte (plus konfigurierbare Puffer) hinausgehen, eröffnet der Algorithmus sofort eine Marktposition in die entgegengesetzte Richtung und verlässt sich auf einen symmetrischen Stop-Loss-/Take-Profit-Schutz. Der StockSharp-Port behält das Einzelpositionsverhalten des ursprünglichen Roboters bei und fügt umfangreiche Parametrisierung für Forschung und Optimierung hinzu.

Ein- und Ausstiegslogik

  1. Die vorherigen Tageshöchst- und -tiefstwerte werden aus einem speziellen täglichen Kerzenabonnement abgerufen. Zwei Offsets (UpperOffsetPoints und LowerOffsetPoints), ausgedrückt in MetaTrader Punkten, erweitern den Referenzkanal.
  2. Bei jeder abgeschlossenen Handelskerze prüft die Strategie die vorherigen und aktuellen Eröffnungen:
    • Wenn die neue Eröffnung über das Tageshoch plus den oberen Offset springt, wird eine Short-Position eröffnet (Fading der Lücke).
    • Wenn die neue Eröffnung unter das Tagestief abzüglich des unteren Offsets fällt, wird eine Long-Position eröffnet.
  3. Es ist jeweils nur eine Position zulässig. Alle aktiven Aufträge müssen ausgeführt werden, bevor ein neues Signal berücksichtigt wird.
  4. StartProtection spiegelt den ursprünglichen festen Stop und das Take-Ziel wider, die beide BetPoints vom Einstiegspreis entfernt liegen (umgerechnet in Preisschritte).

Geldmanagement

  • UseMoneyManagement = false hält die Handelsgröße fest (BaseVolume).
  • UseMoneyManagement = true aktiviert die Martingal-Progression, die im MT4-Code zu sehen ist:
    • Nach jedem Verlust- oder Break-Even-Trade wird das nächste Ordervolumen mit (BetPoints * 2) / (BetPoints - spreadPoints) multipliziert.
    • Der Spread wird anhand der neuesten besten Geld-/Briefkurse geschätzt, die über das Orderbuchabonnement gesammelt wurden. Wenn keine Kurse verfügbar sind, beträgt der Multiplikator standardmäßig 2.
    • Durch Siege wird die Positionsgröße auf BaseVolume zurückgesetzt. Alle Bände sind auf das Instrument VolumeStep ausgerichtet und durch MaxVolume begrenzt.

Parameter

Name Typ Standard Beschreibung
EnableBuy bool true Erlauben Sie lange Einträge, die durch Lücken unterhalb des Tageskanals ausgelöst werden.
EnableSell bool true Erlauben Sie Short-Einstiege, die durch Lücken über dem Tageskanal ausgelöst werden.
BetPoints decimal 400 Symmetrische Stop-Loss- und Take-Profit-Distanz in MetaTrader Punkten (umgerechnet in Preisschritte für StockSharp).
UpperOffsetPoints decimal 97 Über dem vorherigen Tageshoch hinzugefügter Puffer, um rückläufige Gap-Umkehrungen zu erkennen.
LowerOffsetPoints decimal 77 Der Puffer wurde unter das vorherige Tagestief subtrahiert, um bullische Gap-Umkehrungen zu erkennen.
UseMoneyManagement bool false Aktivieren Sie die Losprogression im Martingal-Stil.
MaxVolume decimal 4 Obergrenze, die auf das berechnete Volumen angewendet wird, wenn das Geldmanagement aktiv ist.
BaseVolume decimal 0.1 Die anfängliche Ordergröße wird nach einem profitablen Trade oder bei deaktiviertem Money Management verwendet.
CandleType DataType H1 Primärer Zeitrahmen zur Bewertung der Open-Gap-Bedingungen (Standard ist 1 Stunde).
DailyCandleType DataType D1 Kerzentyp, der das Hoch/Tief des Vortages liefert (Standard ist 1 Tag).

Hinweise zur Implementierung

  • Die Strategie basiert auf dem hochrangigen API von StockSharp: SubscribeCandles stellt sowohl den Handel als auch die täglichen Streams bereit, während SubscribeOrderBook den neuesten Spread für den Money-Management-Multiplikator beibehält.
  • StartProtection verwaltet sowohl die Stop-Loss- als auch die Take-Profit-Komponente, sodass jeder Einstieg sofort symmetrische Ausstiege erhält, genau wie in MT4.
  • Englische Inline-Kommentare heben jeden Entscheidungspunkt hervor, um die Wartung zu erleichtern.
  • Bei allen Berechnungen wird die Suche nach der Indikatorhistorie vermieden. Es sind nur die aktuellen Kerzenöffnungswerte erforderlich, was die Logik Time[0] / Open[0] von MetaTrader widerspiegelt.

Anwendungstipps

  • Wählen Sie einen Handelszeitraum, der zu Ihrer Studie passt. Die standardmäßigen einstündigen Kerzen replizieren das übliche MT4-Setup, es können jedoch alle von StockSharp unterstützten DataType bereitgestellt werden.
  • Stellen Sie bei der Verwendung der Geldverwaltung sicher, dass MaxVolume die Broker-Limits einhält; Der Ausrichtungshelfer begrenzt das Ergebnis auf VolumeStep, MinVolume und MaxVolume.
  • Da das System immer höchstens eine Position offen hält, lässt es sich gut mit StockSharp-Diagrammen kombinieren, die Ein-/Ausstiegsmarkierungen zur manuellen Überprüfung darstellen.
  • Testen Sie die Strategie in einer Replay-Umgebung, bevor Sie sie mit einem Live-Veranstaltungsort verbinden – der Gap-Fading-Ansatz ist aggressiv und hängt von zuverlässigen Spreads ab.
using System;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// Casino111: RSI overbought/oversold reversal with ATR stops.
/// </summary>
public class Casino111Strategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _rsiLength;
	private readonly StrategyParam<int> _atrLength;
	private readonly StrategyParam<int> _emaLength;

	private decimal _prevRsi;
	private decimal _entryPrice;

	public Casino111Strategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
			.SetDisplay("Candle Type", "Timeframe.", "General");

		_rsiLength = Param(nameof(RsiLength), 14)
			.SetDisplay("RSI Length", "RSI period.", "Indicators");

		_atrLength = Param(nameof(AtrLength), 14)
			.SetDisplay("ATR Length", "ATR period.", "Indicators");

		_emaLength = Param(nameof(EmaLength), 50)
			.SetDisplay("EMA Length", "Trend filter.", "Indicators");
	}

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

	public int RsiLength
	{
		get => _rsiLength.Value;
		set => _rsiLength.Value = value;
	}

	public int AtrLength
	{
		get => _atrLength.Value;
		set => _atrLength.Value = value;
	}

	public int EmaLength
	{
		get => _emaLength.Value;
		set => _emaLength.Value = value;
	}

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

		_prevRsi = 0;
		_entryPrice = 0;
	}

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

		_prevRsi = 0;
		_entryPrice = 0;

		var rsi = new RelativeStrengthIndex { Length = RsiLength };
		var atr = new AverageTrueRange { Length = AtrLength };
		var ema = new ExponentialMovingAverage { Length = EmaLength };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(rsi, atr, ema, ProcessCandle)
			.Start();

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

	private void ProcessCandle(ICandleMessage candle, decimal rsiVal, decimal atrVal, decimal emaVal)
	{
		if (candle.State != CandleStates.Finished)
			return;

		if (_prevRsi == 0 || atrVal <= 0)
		{
			_prevRsi = rsiVal;
			return;
		}

		var close = candle.ClosePrice;

		if (Position > 0)
		{
			if (close >= _entryPrice + atrVal * 2.5m || close <= _entryPrice - atrVal * 1.5m || rsiVal > 70)
			{
				SellMarket();
				_entryPrice = 0;
			}
		}
		else if (Position < 0)
		{
			if (close <= _entryPrice - atrVal * 2.5m || close >= _entryPrice + atrVal * 1.5m || rsiVal < 30)
			{
				BuyMarket();
				_entryPrice = 0;
			}
		}

		if (Position == 0)
		{
			if (rsiVal > 50 && _prevRsi <= 50 && close > emaVal)
			{
				_entryPrice = close;
				BuyMarket();
			}
			else if (rsiVal < 50 && _prevRsi >= 50 && close < emaVal)
			{
				_entryPrice = close;
				SellMarket();
			}
		}

		_prevRsi = rsiVal;
	}
}