Strategie TradingView Supertrend Flip
Strategie basierend auf Supertrend-Indikator-Flips mit Volumenbestätigung
Tests zeigen eine durchschnittliche jährliche Rendite von etwa 79%. Am besten funktioniert sie auf dem Aktienmarkt.
TradingView Supertrend Flip emuliert die Farbwechsel des beliebten Indikators. Ein Wechsel von Rot zu Grün signalisiert einen Long-Einstieg und Grün zu Rot einen Short-Einstieg. Die Strategie steigt beim nächsten Flip aus.
Volumenbestätigung kann verwendet werden, um Fehlsignale in dünn gehandelten Perioden zu vermeiden. Indem nur bei Flips mit unterstützendem Volumen gehandelt wird, zielt die Methode auf zuverlässigere Umkehrungen ab.
Details
- Einstiegskriterien: Signale basierend auf ATR, Supertrend.
- Long/Short: Beide Richtungen.
- Ausstiegskriterien: Entgegengesetztes Signal.
- Stops: Nein.
- Standardwerte:
SupertrendPeriod= 10SupertrendMultiplier= 3.0mVolumeAvgPeriod= 20CandleType= TimeSpan.FromMinutes(5)
- Filter:
- Kategorie: Trend
- Richtung: Beide
- Indikatoren: ATR, Supertrend
- Stops: Nein
- Komplexität: Grundlegend
- Zeitrahmen: Intraday (5m)
- Saisonalität: Nein
- Neural Networks: 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>
/// Strategy based on Supertrend indicator flips.
/// Detects when Supertrend direction changes and trades accordingly.
/// </summary>
public class TradingViewSupertrendFlipStrategy : Strategy
{
private readonly StrategyParam<int> _supertrendPeriod;
private readonly StrategyParam<decimal> _supertrendMultiplier;
private readonly StrategyParam<int> _volumeAvgPeriod;
private readonly StrategyParam<bool> _useVolumeFilter;
private readonly StrategyParam<DataType> _candleType;
private SimpleMovingAverage _volumeAverage;
private bool _prevIsUpTrend;
private bool _hasPrevValues;
/// <summary>
/// Period for Supertrend calculation.
/// </summary>
public int SupertrendPeriod
{
get => _supertrendPeriod.Value;
set => _supertrendPeriod.Value = value;
}
/// <summary>
/// Multiplier for Supertrend calculation.
/// </summary>
public decimal SupertrendMultiplier
{
get => _supertrendMultiplier.Value;
set => _supertrendMultiplier.Value = value;
}
public int VolumeAvgPeriod { get => _volumeAvgPeriod.Value; set => _volumeAvgPeriod.Value = value; }
public bool UseVolumeFilter { get => _useVolumeFilter.Value; set => _useVolumeFilter.Value = value; }
/// <summary>
/// Candle type.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Initialize the TradingView Supertrend Flip strategy.
/// </summary>
public TradingViewSupertrendFlipStrategy()
{
_supertrendPeriod = Param(nameof(SupertrendPeriod), 10)
.SetGreaterThanZero()
.SetDisplay("Supertrend Period", "Period for Supertrend calculation", "Indicators")
.SetOptimize(7, 14, 1);
_supertrendMultiplier = Param(nameof(SupertrendMultiplier), 3.0m)
.SetGreaterThanZero()
.SetDisplay("Supertrend Multiplier", "Multiplier for Supertrend", "Indicators")
.SetOptimize(3.0m, 5.0m, 0.5m);
_volumeAvgPeriod = Param(nameof(VolumeAvgPeriod), 20).SetGreaterThanZero();
_useVolumeFilter = Param(nameof(UseVolumeFilter), true);
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).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();
_volumeAverage = null;
_prevIsUpTrend = default;
_hasPrevValues = default;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_volumeAverage = new SimpleMovingAverage { Length = VolumeAvgPeriod };
var supertrend = new SuperTrend
{
Length = SupertrendPeriod,
Multiplier = SupertrendMultiplier
};
var subscription = SubscribeCandles(CandleType);
subscription
.BindEx(supertrend, ProcessCandle, allowEmpty: true)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, supertrend);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, IIndicatorValue supertrendValue)
{
if (candle.State != CandleStates.Finished)
return;
// Feed volume during Supertrend warm-up, using the current bar in the 20-bar SMA.
var volumeValue = _volumeAverage.Process(new DecimalIndicatorValue(_volumeAverage, candle.TotalVolume, candle.OpenTime) { IsFinal = true });
if (!supertrendValue.IsFormed || supertrendValue.IsEmpty || !IsFormedAndOnlineAndAllowTrading())
return;
// The native direction preserves inclusive flips when the close equals a band.
var isUpTrend = ((SuperTrendIndicatorValue)supertrendValue).IsUpTrend;
var confirmed = !UseVolumeFilter || (_volumeAverage.IsFormed && candle.TotalVolume > volumeValue.GetValue<decimal>());
if (!_hasPrevValues)
{
_hasPrevValues = true;
_prevIsUpTrend = isUpTrend;
return;
}
// Detect flip
var isFlippedBullish = isUpTrend && !_prevIsUpTrend;
var isFlippedBearish = !isUpTrend && _prevIsUpTrend;
_prevIsUpTrend = isUpTrend;
if (isFlippedBullish && Position <= 0)
{
if (confirmed)
BuyMarket(Volume + Math.Abs(Position));
else if (Position < 0m)
BuyMarket(Math.Abs(Position));
}
else if (isFlippedBearish && Position >= 0)
{
if (confirmed)
SellMarket(Volume + Math.Abs(Position));
else if (Position > 0m)
SellMarket(Math.Abs(Position));
}
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
clr.AddReference("StockSharp.BusinessEntities")
from System import TimeSpan, Decimal, Math
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import SuperTrend, SimpleMovingAverage, DecimalIndicatorValue
from StockSharp.Algo.Strategies import Strategy
class tradingview_supertrend_flip_strategy(Strategy):
"""
Strategy based on Supertrend indicator flips.
Detects when Supertrend direction changes and trades accordingly.
"""
def __init__(self):
super(tradingview_supertrend_flip_strategy, self).__init__()
self._supertrend_period = self.Param("SupertrendPeriod", 10).SetGreaterThanZero().SetDisplay("Supertrend Period", "Period for Supertrend calculation", "Indicators")
self._supertrend_multiplier = self.Param("SupertrendMultiplier", 3.0).SetGreaterThanZero().SetDisplay("Supertrend Multiplier", "Multiplier for Supertrend", "Indicators")
self._volume_avg_period = self.Param("VolumeAvgPeriod", 20).SetGreaterThanZero()
self._use_volume_filter = self.Param("UseVolumeFilter", True)
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))).SetDisplay("Candle Type", "Type of candles to use", "General")
self._volume_average = None
self._prev_is_up_trend = False
self._has_prev_values = False
@property
def candle_type(self):
return self._candle_type.Value
def GetWorkingSecurities(self):
return [(self.Security, self.candle_type)]
def OnReseted(self):
super(tradingview_supertrend_flip_strategy, self).OnReseted()
self._volume_average = None
self._prev_is_up_trend = False
self._has_prev_values = False
def OnStarted2(self, time):
super(tradingview_supertrend_flip_strategy, self).OnStarted2(time)
self._volume_average = SimpleMovingAverage()
self._volume_average.Length = int(self._volume_avg_period.Value)
supertrend = SuperTrend()
supertrend.Length = self._supertrend_period.Value
supertrend.Multiplier = Decimal(self._supertrend_multiplier.Value)
subscription = self.SubscribeCandles(self.candle_type)
subscription.BindEx(supertrend, self._process_candle, allowEmpty=True).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, supertrend)
self.DrawOwnTrades(area)
def _process_candle(self, candle, st_val):
if candle.State != CandleStates.Finished:
return
volume_input = DecimalIndicatorValue(self._volume_average, candle.TotalVolume, candle.OpenTime)
volume_input.IsFinal = True
volume_value = self._volume_average.Process(volume_input)
if not st_val.IsFormed or st_val.IsEmpty or not self.IsFormedAndOnlineAndAllowTrading():
return
is_up_trend = st_val.IsUpTrend
confirmed = not bool(self._use_volume_filter.Value) or (
self._volume_average.IsFormed and candle.TotalVolume > volume_value.GetValue[Decimal](None))
if not self._has_prev_values:
self._has_prev_values = True
self._prev_is_up_trend = is_up_trend
return
flipped_bullish = is_up_trend and not self._prev_is_up_trend
flipped_bearish = not is_up_trend and self._prev_is_up_trend
self._prev_is_up_trend = is_up_trend
if flipped_bullish and self.Position <= 0:
if confirmed:
self.BuyMarket(self.Volume + Math.Abs(self.Position))
elif self.Position < 0:
self.BuyMarket(Math.Abs(self.Position))
elif flipped_bearish and self.Position >= 0:
if confirmed:
self.SellMarket(self.Volume + Math.Abs(self.Position))
elif self.Position > 0:
self.SellMarket(Math.Abs(self.Position))
def CreateClone(self):
return tradingview_supertrend_flip_strategy()