Auf GitHub ansehen

TCPivot-Sitzungsstoppstrategie

Überblick

Die TCPivot Session Stop-Strategie ist eine direkte Portierung des MetaTrader 4 Expert Advisors gpfTCPivotStop. Der Handel erfolgt um das klassische tägliche Pivot-Level, das vom vorherigen Handelstag berechnet wird. Die Strategie:

  • Berechnet den Drehpunkt, drei Widerstands- und drei Unterstützungsniveaus aus dem Hoch, Tief und Schluss des Vortages.
  • Wartet darauf, dass der aktuelle Schlusskurs das Pivot-Level von unten (Long-Setup) oder von oben (Short-Setup) kreuzt.
  • Eröffnet eine Marktposition in Richtung des Ausbruchs und weist einen Stop-Loss und einen Take-Profit auf der ausgewählten Pivot-Ebene zu.
  • Erzwingt optional das Schließen der Position zu Beginn einer bestimmten Sitzungsstunde, um den ursprünglichen Intraday-Ausstieg zu emulieren.

Die Implementierung basiert auf dem High-Level StockSharp API. Die Größe der Positionen wird mit der Eigenschaft Volume der Basisklasse Strategy bestimmt.

Parameter

Name Beschreibung Standard
TargetLevel Pivot-Stufe für Stop-Loss und Take-Profit (1, 2 oder 3). 1
CloseAtSessionStart Wenn aktiviert, werden offene Positionen geschlossen, wenn die konfigurierte Stunde beginnt. false
SessionCloseHour Sitzungsstunde (0–23), ausgewertet, wenn CloseAtSessionStart aktiviert ist. 0
CandleType Zeitrahmen, der die Handelssignale speist. H1

Handelslogik

  1. Abonnieren Sie stündliche (oder konfigurierte) Kerzen für Signale und tägliche Kerzen für die Pivot-Berechnung.
  2. Berechnen Sie nach Abschluss jeder täglichen Kerze die klassischen Pivot-Levels:
    • Pivot = (High + Low + Close) / 3
    • R1 = 2 * Pivot - Low, S1 = 2 * Pivot - High
    • R2 = Pivot + (R1 - S1), S2 = Pivot - (R1 - S1)
    • R3 = High + 2 * (Pivot - Low), S3 = Low - 2 * (High - Pivot)
  3. Wenn eine Signalkerze endet:
    • Wenn CloseAtSessionStart aktiviert ist und die Kerze bei SessionCloseHour öffnet, wird die Position sofort abgeflacht.
    • Wenn flach und der vorherige Schlusskurs unter dem Pivot lag, während der aktuelle Schlusskurs darüber liegt, geben Sie eine Long-Position ein, wobei das Ziel/der Stopp durch TargetLevel ausgewählt wird.
    • Wenn flach und der vorherige Schlusskurs über dem Pivot lag, während der aktuelle Schlusskurs darunter liegt, gehen Sie mit dem gespiegelten Ziel/Stopp in den Short-Kurs.
    • Wenn Sie sich bereits in einer Position befinden, beenden Sie die Position, wenn der Schlusskurs das konfigurierte Stop-Loss- oder Take-Profit-Niveau erreicht.

Notizen

  • Die Strategie nutzt StartProtection() zur Integration in die integrierten Risikokontrollen der Plattform. Stop-Loss- und Take-Profit-Exits werden innerhalb der Strategielogik explizit behandelt.
  • Die MetaTrader-Version enthielt optionale E-Mail-Benachrichtigungen und dynamische Positionsgrößenbestimmung basierend auf dem Kontorisiko. Diese Funktionen sind nicht Teil des StockSharp-Ports; Nutzen Sie bei Bedarf die Benachrichtigungs- und Geldverwaltungsmodule der Plattform.
  • Der ursprüngliche Fachberater schloss Geschäfte um Mitternacht ab, als isTradeDay aktiviert wurde. Dieses Verhalten wird durch CloseAtSessionStart + SessionCloseHour reproduziert (auf 0 gesetzt, um Mitternacht nachzuahmen).
using System;



using StockSharp.Algo.Indicators;

using StockSharp.Algo.Strategies;

using StockSharp.BusinessEntities;

using StockSharp.Messages;



namespace StockSharp.Samples.Strategies;



public class TcpPivotSessionStopStrategy : Strategy

{

	private readonly StrategyParam<int> _fastPeriod;

	private readonly StrategyParam<int> _slowPeriod;

	private readonly StrategyParam<DataType> _candleType;



	private decimal _prevFast; private decimal _prevSlow; private bool _hasPrev;

	private int _cooldown;



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

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

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



	public TcpPivotSessionStopStrategy()

	{

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

		_slowPeriod = Param(nameof(SlowPeriod), 21).SetDisplay("Slow EMA", "Slow EMA period", "Indicators");

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

	}



	/// <inheritdoc />

	protected override void OnReseted()

	{

		base.OnReseted();

		_prevFast = default;

		_prevSlow = default;

		_hasPrev = default;

		_cooldown = default;

	}



	/// <inheritdoc />

	protected override void OnStarted2(DateTime time)

	{

		base.OnStarted2(time);

		_hasPrev = false;

		var fast = new ExponentialMovingAverage { Length = FastPeriod };

		var slow = new ExponentialMovingAverage { Length = SlowPeriod };

		var subscription = SubscribeCandles(CandleType);

		subscription.Bind(fast, slow, ProcessCandle).Start();

	}



	private void ProcessCandle(ICandleMessage candle, decimal fast, decimal slow)

	{

		if (candle.State != CandleStates.Finished) return;

		if (!IsFormedAndOnlineAndAllowTrading()) return;

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

		if (_cooldown > 0)

		{

			_cooldown--;

			_prevFast = fast; _prevSlow = slow;

			return;

		}



		if (_prevFast <= _prevSlow && fast > slow && Position <= 0)

		{

			var volume = Volume + Math.Abs(Position);

			BuyMarket(volume);

			_cooldown = 2;

		}

		else if (_prevFast >= _prevSlow && fast < slow && Position >= 0)

		{

			var volume = Volume + Math.Abs(Position);

			SellMarket(volume);

			_cooldown = 2;

		}

		_prevFast = fast; _prevSlow = slow;

	}

}