Auf GitHub ansehen

TCPivot Stop-Strategie

Diese Strategie handelt Ausbrüche durch die tägliche Pivot-Linie. Sie berechnet klassische Floor-Trader-Pivot-Level aus dem Hoch, Tief und Schlusskurs des Vortages. Eine Long-Position wird eröffnet, wenn der Schlusskurs den Pivot von unten nach oben kreuzt. Eine Short-Position wird eröffnet, wenn der Schlusskurs den Pivot von oben nach unten kreuzt.

Nach dem Einstieg verwendet das System eines der Support- oder Resistance-Level sowohl als Kursziel als auch als Stop-Loss. Das Level wird über den Parameter Target Level ausgewählt:

  • 1 – verwendet Support1/Resistance1.
  • 2 – verwendet Support2/Resistance2.
  • 3 – verwendet Support3/Resistance3.

Wenn Intraday Only aktiviert ist, werden alle offenen Positionen um 23:00 Plattformzeit geschlossen.

Details

  • Einstiegskriterien
    • Long: vorheriger Schlusskurs ≤ Pivot und aktueller Schlusskurs > Pivot.
    • Short: vorheriger Schlusskurs ≥ Pivot und aktueller Schlusskurs < Pivot.
  • Ausstiegskriterien
    • Long: Schluss ≥ ausgewähltes Resistance-Level oder Schluss ≤ ausgewähltes Support-Level.
    • Short: Schluss ≤ ausgewähltes Support-Level oder Schluss ≥ ausgewähltes Resistance-Level.
    • Wenn Intraday Only aktiv ist, werden alle Positionen um 23:00 geschlossen.
  • Indikatoren: nur klassische Pivot-Berechnung.
  • Zeitrahmen: konfigurierbar; Standard 5-Minuten-Kerzen.
  • Stops: Stop-Loss und Take-Profit aus dem gewählten Pivot-Level.
using System;
using System.Collections.Generic;

using Ecng.Common;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// Pivot-based breakout strategy.
/// Buys when close crosses above calculated pivot, sells when it crosses below.
/// Uses support/resistance levels for exits.
/// </summary>
public class TcpPivotStopStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;

	private decimal _pivot;
	private decimal _res1, _sup1;
	private decimal _prevClose;
	private decimal _prevHigh;
	private decimal _prevLow;
	private int _barCount;

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

	public TcpPivotStopStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
			.SetDisplay("Candle Type", "Time frame", "General");
	}

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

	protected override void OnReseted()
	{
		base.OnReseted();
		_pivot = _res1 = _sup1 = 0;
		_prevClose = _prevHigh = _prevLow = 0;
		_barCount = 0;
	}

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		SubscribeCandles(CandleType).Bind(ProcessCandle).Start();
	}

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

		_barCount++;

		// Recalculate pivot every 12 bars (~2 days for 4h candles)
		if (_barCount % 12 == 0 && _prevHigh > 0)
		{
			_pivot = (_prevHigh + _prevLow + _prevClose) / 3m;
			_res1 = 2m * _pivot - _prevLow;
			_sup1 = 2m * _pivot - _prevHigh;
		}

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

		var close = candle.ClosePrice;

		if (_pivot > 0 && _prevClose > 0)
		{
			// Cross above pivot => long
			if (_prevClose <= _pivot && close > _pivot && Position <= 0)
			{
				if (Position < 0) BuyMarket();
				BuyMarket();
			}
			// Cross below pivot => short
			else if (_prevClose >= _pivot && close < _pivot && Position >= 0)
			{
				if (Position > 0) SellMarket();
				SellMarket();
			}
			// Exit long at resistance or support
			else if (Position > 0 && (close >= _res1 || close <= _sup1))
			{
				SellMarket();
			}
			// Exit short at support or resistance
			else if (Position < 0 && (close <= _sup1 || close >= _res1))
			{
				BuyMarket();
			}
		}

		_prevClose = close;
	}
}