Auf GitHub ansehen

Strategie Bollinger Supertrend

Diese Strategie kombiniert Bollinger Bands mit dem Supertrend-Indikator, um Einstiege während starker gerichteter Bewegungen zu identifizieren. Bollinger Bands messen die Volatilitätsausdehnung, während die Supertrend-Linie den übergeordneten Trend verfolgt und als Trailing-Stop fungiert.

Tests zeigen eine durchschnittliche Jahresrendite von etwa 79%. Sie funktioniert am besten auf dem Aktienmarkt.

Ein Long-Trade wird ausgelöst, wenn der Preis über dem oberen Bollinger Band schließt und über der Supertrend-Linie bleibt, was Momentum und Trendausrichtung bestätigt. Ein Short-Trade tritt auf, wenn der Preis unter dem unteren Band schließt und unter dem Supertrend-Level bleibt. Trades werden geschlossen, sobald der Preis zurück durch den Supertrend kreuzt, was darauf hindeutet, dass das Momentum nachgelassen hat.

Da das System auf Ausbrüche jenseits der normalen Volatilität wartet, eignet es sich für Trader, die anhaltende Bewegungen statt schnelle Umkehrungen erfassen möchten. Der Supertrend-Stop passt sich dynamisch an Marktschwankungen an und hilft, das Risiko ohne manuelle Eingriffe zu managen.

Details

  • Einstiegskriterien:
    • Long: Close > upper Bollinger Band && Close > Supertrend
    • Short: Close < lower Bollinger Band && Close < Supertrend
  • Long/Short: Beide Seiten.
  • Ausstiegskriterien:
    • Long: Ausstieg, wenn der Preis unter den Supertrend fällt
    • Short: Ausstieg, wenn der Preis über den Supertrend steigt
  • Stops: Ja, über Supertrend Trailing-Stop.
  • Standardwerte:
    • BollingerPeriod = 20
    • BollingerDeviation = 2
    • SupertrendPeriod = 10
    • SupertrendMultiplier = 3
    • CandleType = TimeSpan.FromMinutes(15) Ein Long schließt, wenn der Kurs unter der Supertrend-Linie schließt, ein Short, wenn er darüber schließt. Ein Einstiegssignal gegen eine offene Position dreht sie.
  • Filter:
    • Kategorie: Trend
    • Richtung: Beide
    • Indikatoren: Bollinger Bands, Supertrend
    • Stops: Ja
    • Komplexität: Mittel
    • Zeitrahmen: Intraday
    • Saisonalität: Nein
    • Neuronale Netze: Nein
    • Divergenz: Nein
    • Risikolevel: Mittel
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>
/// Bollinger Supertrend strategy.
/// A close above the upper Bollinger band that is also above the Supertrend line goes long and a close below the lower band that is also
/// below the Supertrend goes short, reversing an opposite position. The Supertrend is the trailing stop: a long closes when price closes
/// below the line and a short when it closes above it.
/// </summary>
public class BollingerSupertrendStrategy : Strategy
{
	private readonly StrategyParam<int> _bollingerPeriod;
	private readonly StrategyParam<decimal> _bollingerDeviation;
	private readonly StrategyParam<int> _supertrendPeriod;
	private readonly StrategyParam<decimal> _supertrendMultiplier;
	private readonly StrategyParam<DataType> _candleType;

	/// <summary>
	/// Period of the Bollinger Bands.
	/// </summary>
	public int BollingerPeriod
	{
		get => _bollingerPeriod.Value;
		set => _bollingerPeriod.Value = value;
	}

	/// <summary>
	/// Standard deviation multiplier of the bands.
	/// </summary>
	public decimal BollingerDeviation
	{
		get => _bollingerDeviation.Value;
		set => _bollingerDeviation.Value = value;
	}

	/// <summary>
	/// ATR period of Supertrend.
	/// </summary>
	public int SupertrendPeriod
	{
		get => _supertrendPeriod.Value;
		set => _supertrendPeriod.Value = value;
	}

	/// <summary>
	/// ATR multiplier of Supertrend.
	/// </summary>
	public decimal SupertrendMultiplier
	{
		get => _supertrendMultiplier.Value;
		set => _supertrendMultiplier.Value = value;
	}

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

	/// <summary>
	/// Constructor.
	/// </summary>
	public BollingerSupertrendStrategy()
	{
		_bollingerPeriod = Param(nameof(BollingerPeriod), 20)
			.SetGreaterThanZero()
			.SetDisplay("BB Period", "Period of the Bollinger Bands", "Bollinger");

		_bollingerDeviation = Param(nameof(BollingerDeviation), 2m)
			.SetGreaterThanZero()
			.SetDisplay("BB Deviation", "Standard deviation multiplier of the bands", "Bollinger");

		_supertrendPeriod = Param(nameof(SupertrendPeriod), 10)
			.SetGreaterThanZero()
			.SetDisplay("Supertrend Period", "ATR period of Supertrend", "Supertrend");

		_supertrendMultiplier = Param(nameof(SupertrendMultiplier), 3m)
			.SetGreaterThanZero()
			.SetDisplay("Supertrend Multiplier", "ATR multiplier of Supertrend", "Supertrend");

		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(15).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 OnStarted2(DateTime time)
	{
		base.OnStarted2(time);

		var bollinger = new BollingerBands { Length = BollingerPeriod, Width = BollingerDeviation };
		var supertrend = new SuperTrend { Length = SupertrendPeriod, Multiplier = SupertrendMultiplier };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.BindEx(bollinger, supertrend, ProcessCandle)
			.Start();

		var area = CreateChartArea();
		if (area != null)
		{
			DrawCandles(area, subscription);
			DrawIndicator(area, bollinger);
			DrawIndicator(area, supertrend);
			DrawOwnTrades(area);
		}
	}

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

		if (!bollingerValue.IsFormed || !supertrendValue.IsFormed)
			return;

		var bands = (BollingerBandsValue)bollingerValue;

		if (bands.UpBand is not decimal upper || bands.LowBand is not decimal lower || supertrendValue is not SuperTrendIndicatorValue trend)
			return;

		if (!IsFormedAndOnlineAndAllowTrading())
			return;

		var line = trend.Value;
		var close = candle.ClosePrice;

		if (close > upper && close > line && Position <= 0)
			BuyMarket(Volume + Math.Abs(Position));
		else if (close < lower && close < line && Position >= 0)
			SellMarket(Volume + Math.Abs(Position));
		else if (Position > 0 && close < line)
			SellMarket(Position);
		else if (Position < 0 && close > line)
			BuyMarket(-Position);
	}
}