Auf GitHub ansehen

Gap-Reversion-Strategie

Überblick

Die Gap-Reversion-Strategie ist eine direkte Portierung des MetaTrader 4 Expertenberaters gaps.mq4. Das System überwacht 15-Minuten-Kerzen und Toilette ks für das Öffnen von Lücken, die außerhalb des Hoch-/Tief-Bereichs der vorherigen Kerze auftreten. Wenn eine solche Lücke auftritt, wird die Strategie sofort, z Bringt den Markt in die Richtung der erwarteten Mean-Reversion-Bewegung.

Die StockSharp-Version folgt der ursprünglichen Logik und stützt sich dabei auf das High-Level-Kerzenabonnement API. Das gesamte Handelsmanagement ist Dies erfolgt mit Marktaufträgen und es werden keine festen Schutzaufträge erteilt, was das Verhalten im MQL-Code widerspiegelt.

Handelsregeln

  1. Abonnieren Sie 15-Minuten-Kerzen (konfigurierbar über den Parameter CandleType).
  2. Behalten Sie das Hoch und Tief der zuvor abgeschlossenen Kerze bei.
  3. Wenn eine neue Kerze beginnt:
    • Berechnen Sie den Lückenpuffer: (MinGapSize + spreadInSteps) * pointValue.
    • Wenn der Eröffnungspreis über previousHigh + gapBuffer liegt, eröffnen Sie eine Short-Position.
    • Wenn der Eröffnungspreis unter previousLow - gapBuffer liegt, eröffnen Sie eine Long-Position.
  4. Es ist nur ein Trade pro Kerze erlaubt. Sobald eine Order aufgegeben wurde, wartet die Strategie auf die nächste Kerze, bevor sie eine neue Kerze generiert ignal.

Die Spread-Komponente verwendet den aktuell besten Geld-/Briefkurs, sofern verfügbar. Wenn keine Kursdaten bereitgestellt werden, fällt die Strategie auf eine Sünde zurück gle-Preisschritt als konservativer Puffer.

Parameter

Parameter Standard Beschreibung
MinGapSize 1 Mindestlückengröße in Preisschritten, die vor dem Absenden einer Bestellung überschritten werden muss.
GapVolume 0.1 Auftragsvolumen für durch Lücken ausgelöste Markteintritte.
CandleType 15m TimeFrame Für Berechnungen verwendeter Kerzentyp (standardmäßig 15-Minuten-Kerzen).

Alle Parameter sind als StrategyParam<T> registriert und unterstützen die Optimierung im StockSharp Designer oder anderen Tools.

Implementierungshinweise

  • Verwendet SubscribeCandles mit Bind, um nur fertige Kerzen zu verarbeiten.
  • Merkt sich den Bereich der vorherigen Kerze, um eine Neuberechnung der Datenreihen zu vermeiden.
  • Blockiert doppelte Orders auf derselben Kerze, indem die Öffnungszeit des Balkens verfolgt wird, der den Handel ausgelöst hat.
  • Die Diagrammausgabe zeichnet die abonnierten Kerzen und die Strategiegeschäfte zur schnellen visuellen Überprüfung.

Unterschiede zur MQL-Version

  • Take-Profit- und Stop-Loss-Level wurden im ursprünglichen EA nicht richtig festgelegt (der MQL-Code hat Werte an die falschen Parameter übergeben) . Der Port StockSharp behält daher das Verhalten bei, dass er ohne Schutzbefehle ausgeführt wird.
  • Bei der Spread-Verarbeitung werden jetzt Geld-/Briefkurse in Echtzeit überprüft, sofern verfügbar, wodurch ein anpassungsfähigerer Puffer bereitgestellt wird.

Anforderungen

  • StockSharp API mit Zugriff auf Kerzendaten für das ausgewählte Instrument.
  • Kurse der Stufe 1 sind optional, verbessern jedoch die Spread-Erkennung.
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>
/// Gap Reversion strategy - detects gap openings and trades mean reversion.
/// Buys when candle opens below previous low (gap down reversion).
/// Sells when candle opens above previous high (gap up reversion).
/// Uses EMA as trend filter for exits.
/// </summary>
public class GapReversionStrategy : Strategy
{
	private readonly StrategyParam<int> _emaPeriod;
	private readonly StrategyParam<DataType> _candleType;

	private decimal _prevHigh;
	private decimal _prevLow;
	private bool _hasPrev;

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

	public GapReversionStrategy()
	{
		_emaPeriod = Param(nameof(EmaPeriod), 20)
			.SetDisplay("EMA Period", "EMA trend filter", "Indicators");

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

	public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities() => [(Security, CandleType)];
	protected override void OnReseted() { base.OnReseted(); _prevHigh = 0m; _prevLow = 0m; _hasPrev = false; }

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

		_hasPrev = false;

		var ema = new ExponentialMovingAverage { Length = EmaPeriod };

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

		StartProtection(
			takeProfit: new Unit(2, UnitTypes.Percent),
			stopLoss: new Unit(1, UnitTypes.Percent)
		);
	}

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

		if (!_hasPrev)
		{
			_prevHigh = candle.HighPrice;
			_prevLow = candle.LowPrice;
			_hasPrev = true;
			return;
		}

		var open = candle.OpenPrice;
		var close = candle.ClosePrice;

		// Gap down reversion - open below previous low, expect bounce
		if (open < _prevLow && close > ema && Position == 0)
			BuyMarket();
		// Gap up reversion - open above previous high, expect pullback
		else if (open > _prevHigh && close < ema && Position == 0)
			SellMarket();

		_prevHigh = candle.HighPrice;
		_prevLow = candle.LowPrice;
	}
}