Der Supertrend-Indikator kombiniert ATR und Preis, um eine gleitende Unterstützung oder einen gleitenden Widerstand zu erzeugen. Wenn die Supertrend-Linie von oberhalb auf unterhalb des Preises wechselt oder umgekehrt, deutet dies auf eine mögliche Trendwende hin. Diese Strategie handelt diese Wechsel.
Tests zeigen eine durchschnittliche Jahresrendite von etwa 151%. Am besten funktioniert die Strategie am Aktienmarkt.
Auf jeder Kerze aktualisiert eine ATR-basierte Berechnung das Supertrend-Niveau. Ein Wechsel von oberhalb des Preises auf unterhalb löst einen Long-Einstieg aus, während eine Bewegung von unterhalb auf oberhalb einen Short erzeugt. Das Code-Beispiel verzichtet auf explizite Stops, daher sind Ausstiege ermessensbasiert oder werden von einem separaten Risikomodul verwaltet.
Der Indikator kann schnell auf Volatilität reagieren, daher kombinieren Trader ihn oft mit zusätzlichen Filtern, um Fehlsignale zu reduzieren.
Details
Einstiegskriterien: Supertrend wechselt die Seite relativ zum Preis.
Long/Short: Beide.
Ausstiegskriterien: Manueller oder externer Stop.
Stops: Nicht definiert.
Standardwerte:
Period = 10
Multiplier = 3.0
CandleType = 15 minute
Filter:
Kategorie: Trendfolge
Richtung: Beide
Indikatoren: Supertrend
Stops: Optional
Komplexität: Grundlegend
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>
/// Supertrend Reversal strategy.
/// Uses the built-in SuperTrend indicator.
/// Enters long when SuperTrend flips to uptrend (below price).
/// Enters short when SuperTrend flips to downtrend (above price).
/// Uses cooldown to control trade frequency.
/// </summary>
public class SupertrendReversalStrategy : Strategy
{
private readonly StrategyParam<int> _period;
private readonly StrategyParam<decimal> _multiplier;
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _cooldownBars;
private bool? _prevIsUpTrend;
private int _cooldown;
/// <summary>
/// ATR period for SuperTrend.
/// </summary>
public int Period
{
get => _period.Value;
set => _period.Value = value;
}
/// <summary>
/// ATR multiplier for SuperTrend.
/// </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>
/// Cooldown bars.
/// </summary>
public int CooldownBars
{
get => _cooldownBars.Value;
set => _cooldownBars.Value = value;
}
/// <summary>
/// Constructor.
/// </summary>
public SupertrendReversalStrategy()
{
_period = Param(nameof(Period), 10)
.SetRange(7, 20)
.SetDisplay("Period", "ATR period for SuperTrend", "SuperTrend");
_multiplier = Param(nameof(Multiplier), 3.0m)
.SetRange(2.0m, 4.0m)
.SetDisplay("Multiplier", "ATR multiplier for SuperTrend", "SuperTrend");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(1).TimeFrame())
.SetDisplay("Candle Type", "Type of candles to use", "General");
_cooldownBars = Param(nameof(CooldownBars), 500)
.SetRange(1, 1000)
.SetDisplay("Cooldown Bars", "Bars to wait between trades", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevIsUpTrend = null;
_cooldown = default;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevIsUpTrend = null;
_cooldown = 0;
var superTrend = new SuperTrend
{
Length = Period,
Multiplier = Multiplier
};
var subscription = SubscribeCandles(CandleType);
subscription
.BindEx(superTrend, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, superTrend);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, IIndicatorValue stValue)
{
if (candle.State != CandleStates.Finished)
return;
if (!stValue.IsFormed)
return;
var stTyped = (SuperTrendIndicatorValue)stValue;
var isUpTrend = stTyped.IsUpTrend;
if (_prevIsUpTrend == null)
{
_prevIsUpTrend = isUpTrend;
return;
}
if (_cooldown > 0)
{
_cooldown--;
_prevIsUpTrend = isUpTrend;
return;
}
// SuperTrend flipped to uptrend = bullish
var flippedUp = _prevIsUpTrend == false && isUpTrend;
// SuperTrend flipped to downtrend = bearish
var flippedDown = _prevIsUpTrend == true && !isUpTrend;
if (Position == 0 && flippedUp)
{
BuyMarket();
_cooldown = CooldownBars;
}
else if (Position == 0 && flippedDown)
{
SellMarket();
_cooldown = CooldownBars;
}
else if (Position > 0 && flippedDown)
{
SellMarket();
_cooldown = CooldownBars;
}
else if (Position < 0 && flippedUp)
{
BuyMarket();
_cooldown = CooldownBars;
}
_prevIsUpTrend = isUpTrend;
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import SuperTrend
from StockSharp.Algo.Strategies import Strategy
class supertrend_reversal_strategy(Strategy):
"""
Supertrend Reversal strategy.
Enters long when SuperTrend flips to uptrend (below price).
Enters short when SuperTrend flips to downtrend (above price).
Uses cooldown to control trade frequency.
"""
def __init__(self):
super(supertrend_reversal_strategy, self).__init__()
self._period = self.Param("Period", 10).SetDisplay("Period", "ATR period for SuperTrend", "SuperTrend")
self._multiplier = self.Param("Multiplier", 3.0).SetDisplay("Multiplier", "ATR multiplier for SuperTrend", "SuperTrend")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(1))).SetDisplay("Candle Type", "Type of candles to use", "General")
self._cooldown_bars = self.Param("CooldownBars", 500).SetDisplay("Cooldown Bars", "Bars to wait between trades", "General")
self._prev_is_up_trend = None
self._cooldown = 0
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(supertrend_reversal_strategy, self).OnReseted()
self._prev_is_up_trend = None
self._cooldown = 0
def OnStarted2(self, time):
super(supertrend_reversal_strategy, self).OnStarted2(time)
self._prev_is_up_trend = None
self._cooldown = 0
st = SuperTrend()
st.Length = self._period.Value
st.Multiplier = self._multiplier.Value
subscription = self.SubscribeCandles(self.candle_type)
subscription.BindEx(st, self._process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, st)
self.DrawOwnTrades(area)
def _process_candle(self, candle, st_iv):
if candle.State != CandleStates.Finished:
return
if not st_iv.IsFormed:
return
is_up_trend = st_iv.IsUpTrend
if self._prev_is_up_trend is None:
self._prev_is_up_trend = is_up_trend
return
if self._cooldown > 0:
self._cooldown -= 1
self._prev_is_up_trend = is_up_trend
return
cd = self._cooldown_bars.Value
# SuperTrend flipped to uptrend = bullish
flipped_up = self._prev_is_up_trend == False and is_up_trend
# SuperTrend flipped to downtrend = bearish
flipped_down = self._prev_is_up_trend == True and not is_up_trend
if self.Position == 0 and flipped_up:
self.BuyMarket()
self._cooldown = cd
elif self.Position == 0 and flipped_down:
self.SellMarket()
self._cooldown = cd
elif self.Position > 0 and flipped_down:
self.SellMarket()
self._cooldown = cd
elif self.Position < 0 and flipped_up:
self.BuyMarket()
self._cooldown = cd
self._prev_is_up_trend = is_up_trend
def CreateClone(self):
return supertrend_reversal_strategy()