Auf GitHub ansehen

TCPivotStop Floor Breakout-Strategie

Überblick

Die TCPivotStop Floor Breakout Strategy ist eine direkte Portierung des MetaTrader-Expertenberaters gpfTCPivotStop. Die Logik dreht sich um klassische Floor-Pivot-Berechnungen, die am vorherigen Handelstag durchgeführt wurden. Zu Beginn jeder neuen täglichen Sitzung lautet die Strategie:

  1. Fasst die Höchst-, Tiefst- und Schlusskurse des Vortages zusammen, um den Pivotpunkt sowie die ersten drei Unterstützungs- und Widerstandsstufen zu berechnen.
  2. Überprüft, ob der letzte abgeschlossene Stundenbalken den Pivot von oben oder unten gekreuzt hat.
  3. Eröffnet eine Marktorder in Richtung des Crossovers und fügt gleichzeitig Stop-Loss- und Take-Profit-Levels hinzu, die diese widerspiegeln Verhalten des ursprünglichen Experten.

Es kann jeweils nur eine Position aktiv sein. Die optionale Sitzungsverwaltung ermöglicht eine Reduzierung der Belichtung, wenn ein neuer Tag beginnt.

Handelsregeln

  • Zeitrahmen – Entwickelt für 1-Stunden-Kerzen (konfigurierbar).
  • Pivot-Berechnung – Verwendet den Höchst-, Tiefst- und Schlusskurs des Vortages, um Pivot, R1, R2, R3, S1, S2, S3 zu berechnen.
  • Eintrittsbedingungen
    • Geben Sie short ein, wenn der letzte abgeschlossene Balken unterhalb des Pivots schloss, während der vorherige Balken darüber schloss.
    • Geben Sie long ein, wenn der letzte abgeschlossene Balken über dem Pivot schloss, während der vorherige Balken darunter schloss.
  • Positionsgröße – Feste Losgröße, definiert durch den Parameter OrderVolume.
  • Ausstiegsbedingungen
    • Stop-Loss- und Take-Profit-Preise werden den klassischen Pivot-Levels zugeordnet.
    • Wenn das Flag CloseAtSessionEnd aktiviert ist, liquidiert die Strategie offene Trades, bevor die nächste Sitzung beginnt.
    • Schutzniveaus werden auf Kerzenhochs/-tiefs überwacht und bei Erreichen mit Marktaufträgen ausgeführt.

Parameter

Name Beschreibung Standard
OrderVolume Handelsgröße für Markteintritte. 0.1
TakeProfitTarget Wählt aus, welche Pivot-Stufe als Gewinnziel fungiert (1 = am nächsten, 3 = am weitesten entfernt). 1
CloseAtSessionEnd Schließen Sie alle offenen Positionen, sobald eine neue tägliche Sitzung beginnt. false
CandleType Für alle Berechnungen verwendeter Zeitrahmen (standardmäßig stündlich). H1

Notizen

  • Die Strategie führt Aufträge nur einmal pro Tag aus, wenn ein neuer Pivot-Satz verfügbar ist, genau wie die Quelle EA, die auf dem ausgelöst wird erster Tick der täglichen Sitzung.
  • Die MetaTrader-Version berechnete die Losgrößen anhand der Kontomargenhistorie neu. Dieser Port hält die Positionsgröße fest und delegiert die Geldverwaltung bei Bedarf an andere Komponenten.
  • Schutzaufträge werden durch die Überwachung von Kerzenextremen und das Senden von Marktaufträgen nachgeahmt, sobald ein Schwellenwert überschritten wird.

Dateien

  • CS/TcpFloorPivotBreakoutStrategy.cs – C#-Implementierung der Handelslogik.
  • README.md – Englische Dokumentation (diese Datei).
  • README_zh.md – Vereinfachte chinesische Übersetzung.
  • README_ru.md – Russische Übersetzung.
using System;

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

namespace StockSharp.Samples.Strategies;

public class TcpFloorPivotBreakoutStrategy : Strategy
{
	private readonly StrategyParam<int> _channelPeriod;
	private readonly StrategyParam<int> _cooldownCandles;
	private readonly StrategyParam<DataType> _candleType;

	private decimal _prevClose;
	private decimal _prevMid;
	private bool _hasPrev;
	private int _cooldownRemaining;

	public int ChannelPeriod { get => _channelPeriod.Value; set => _channelPeriod.Value = value; }
	public int CooldownCandles { get => _cooldownCandles.Value; set => _cooldownCandles.Value = value; }
	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }

	public TcpFloorPivotBreakoutStrategy()
	{
		_channelPeriod = Param(nameof(ChannelPeriod), 48).SetDisplay("Channel Period", "Channel lookback", "Indicators");
		_cooldownCandles = Param(nameof(CooldownCandles), 150).SetDisplay("Cooldown", "Candles between signals", "General");
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame()).SetDisplay("Candle Type", "Candle timeframe", "General");
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_prevClose = default;
		_prevMid = default;
		_hasPrev = default;
		_cooldownRemaining = default;
	}

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_prevClose = 0;
		_prevMid = 0;
		_hasPrev = false;
		_cooldownRemaining = 0;

		var highest = new Highest { Length = ChannelPeriod };
		var lowest = new Lowest { Length = ChannelPeriod };
		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(highest, lowest, ProcessCandle).Start();
	}

	private void ProcessCandle(ICandleMessage candle, decimal highest, decimal lowest)
	{
		if (candle.State != CandleStates.Finished) return;
		var close = candle.ClosePrice;
		var mid = (highest + lowest) / 2;
		if (!_hasPrev) { _prevClose = close; _prevMid = mid; _hasPrev = true; return; }

		if (_cooldownRemaining > 0)
		{
			_cooldownRemaining--;
			_prevClose = close;
			_prevMid = mid;
			return;
		}

		if (_prevClose <= _prevMid && close > mid && Position <= 0)
		{
			if (Position < 0) BuyMarket();
			BuyMarket();
			_cooldownRemaining = CooldownCandles;
		}
		else if (_prevClose >= _prevMid && close < mid && Position >= 0)
		{
			if (Position > 0) SellMarket();
			SellMarket();
			_cooldownRemaining = CooldownCandles;
		}
		_prevClose = close;
		_prevMid = mid;
	}
}