Auf GitHub ansehen

Strategie Super Trend

Strategie basierend auf dem Supertrend-Indikator.

Tests zeigen eine durchschnittliche jährliche Rendite von etwa 67%. Die Strategie funktioniert am besten im Aktienmarkt.

Super Trend berechnet eine dynamische Linie aus dem ATR, die zwischen Unterstützung und Widerstand wechselt. Ein Preisübergang darüber macht die Tendenz bullisch, und ein Übergang darunter macht sie bärisch. Der Trade endet, wenn die Linie umkehrt.

Indem die Strategie dieser adaptiven Linie folgt, versucht sie, anhaltende Bewegungen zu erfassen und gleichzeitig Fehlsignale zu minimieren. Da das Stop-Level dem Preis folgt, werden Gewinne gesichert, sobald das Momentum nachlässt.

Details

  • Einstiegskriterien: Signale basierend auf ATR, Supertrend.
  • Long/Short: Beide Richtungen.
  • Ausstiegskriterien: Gegensätzliches Signal.
  • Stops: Nein.
  • Standardwerte:
    • Period = 10
    • Multiplier = 3.0m
    • CandleType = TimeSpan.FromMinutes(5)
  • Filter:
    • Kategorie: Trend
    • Richtung: Beide
    • Indikatoren: ATR, Supertrend
    • Stops: Nein
    • Komplexität: Grundlegend
    • Zeitrahmen: Intraday (5m)
    • Saisonalität: Nein
    • Neuronale Netze: Nein
    • Divergenz: Nein
    • Risikolevel: Mittel
using System;
using System.Linq;
using System.Collections.Generic;

using Ecng.Common;
using Ecng.Collections;
using Ecng.Serialization;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// Strategy based on Supertrend indicator.
/// It enters long position when price is above Supertrend line and short position when price is below Supertrend line.
/// </summary>
public class SupertrendStrategy : Strategy
{
	private readonly StrategyParam<int> _period;
	private readonly StrategyParam<decimal> _multiplier;
	private readonly StrategyParam<DataType> _candleType;

	// Current state tracking
	private bool _prevIsPriceAboveSupertrend;
	private decimal _prevSupertrendValue;

	/// <summary>
	/// Period for Supertrend calculation.
	/// </summary>
	public int Period
	{
		get => _period.Value;
		set => _period.Value = value;
	}

	/// <summary>
	/// Multiplier for Supertrend calculation.
	/// </summary>
	public decimal Multiplier
	{
		get => _multiplier.Value;
		set => _multiplier.Value = value;
	}

	/// <summary>
	/// Candle type.
	/// </summary>
	public DataType CandleType
	{
		get => _candleType.Value;
		set => _candleType.Value = value;
	}

	/// <summary>
	/// Initialize the Supertrend strategy.
	/// </summary>
	public SupertrendStrategy()
	{
		_period = Param(nameof(Period), 300)
			.SetDisplay("Period", "Period for Supertrend calculation", "Indicators")

			.SetOptimize(7, 21, 2);

		_multiplier = Param(nameof(Multiplier), 50.0m)
			.SetDisplay("Multiplier", "Multiplier for Supertrend calculation", "Indicators")

			.SetOptimize(2.0m, 4.0m, 0.5m);

		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(1).TimeFrame())
			.SetDisplay("Candle Type", "Type of candles to use", "General");
	}

	/// <inheritdoc />
	public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
	{
		return [(Security, CandleType)];
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_prevIsPriceAboveSupertrend = false;
		_prevSupertrendValue = 0;

	}

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);

		// Create custom supertrend indicator
		// Since StockSharp doesn't have a built-in Supertrend indicator,
		// we'll use ATR to calculate the basic components
		var atr = new AverageTrueRange { Length = Period };

		// Create subscription
		var subscription = SubscribeCandles(CandleType);
		
		// We'll process candles manually and calculate Supertrend in the handler
		subscription
			.Bind(atr, ProcessCandle)
			.Start();

		// Setup chart visualization if available
		var area = CreateChartArea();
		if (area != null)
		{
			DrawCandles(area, subscription);
			DrawOwnTrades(area);
		}
	}

	private void ProcessCandle(ICandleMessage candle, decimal atrValue)
	{
		// Skip unfinished candles
		if (candle.State != CandleStates.Finished)
			return;

		// Check if strategy is ready to trade
		if (!IsFormedAndOnlineAndAllowTrading())
			return;

		// Calculate Supertrend components
		var medianPrice = (candle.HighPrice + candle.LowPrice) / 2;
		var basicUpperBand = medianPrice + Multiplier * atrValue;
		var basicLowerBand = medianPrice - Multiplier * atrValue;

		// We need to track previous values to implement the Supertrend logic
		decimal supertrendValue;

		// If this is the first processed candle, initialize values
		if (_prevSupertrendValue == 0)
		{
			supertrendValue = candle.ClosePrice > medianPrice ? basicLowerBand : basicUpperBand;
			_prevSupertrendValue = supertrendValue;
			_prevIsPriceAboveSupertrend = candle.ClosePrice > supertrendValue;
			return;
		}

		// Determine current Supertrend value based on previous value and current price
		if (_prevSupertrendValue <= candle.HighPrice)
		{
			// Previous Supertrend was resistance
			supertrendValue = Math.Max(basicLowerBand, _prevSupertrendValue);
		}
		else if (_prevSupertrendValue >= candle.LowPrice)
		{
			// Previous Supertrend was support
			supertrendValue = Math.Min(basicUpperBand, _prevSupertrendValue);
		}
		else
		{
			// Price crossed the Supertrend
			supertrendValue = candle.ClosePrice > _prevSupertrendValue ? basicLowerBand : basicUpperBand;
		}

		// Check if price is above or below Supertrend
		var isPriceAboveSupertrend = candle.ClosePrice > supertrendValue;
		
		// Detect crossovers
		var isCrossedAbove = isPriceAboveSupertrend && !_prevIsPriceAboveSupertrend;
		var isCrossedBelow = !isPriceAboveSupertrend && _prevIsPriceAboveSupertrend;

		// Trading logic
		if (isCrossedAbove && Position <= 0)
		{
			// Price crossed above Supertrend - Buy signal
			var volume = Volume + Math.Abs(Position);
			BuyMarket(volume);
			LogInfo($"Buy signal: Price ({candle.ClosePrice}) crossed above Supertrend ({supertrendValue})");
		}
		else if (isCrossedBelow && Position >= 0)
		{
			// Price crossed below Supertrend - Sell signal
			var volume = Volume + Math.Abs(Position);
			SellMarket(volume);
			LogInfo($"Sell signal: Price ({candle.ClosePrice}) crossed below Supertrend ({supertrendValue})");
		}

		// Update state for the next candle
		_prevSupertrendValue = supertrendValue;
		_prevIsPriceAboveSupertrend = isPriceAboveSupertrend;
	}
}