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= 10Multiplier= 3.0mCandleType= 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;
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan, Math
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import AverageTrueRange
from StockSharp.Algo.Strategies import Strategy
class supertrend_strategy(Strategy):
"""
Strategy based on Supertrend indicator.
Enters long when price crosses above Supertrend, short when price crosses below.
"""
def __init__(self):
super(supertrend_strategy, self).__init__()
self._period = self.Param("Period", 300).SetDisplay("Period", "Period for Supertrend calculation", "Indicators")
self._multiplier = self.Param("Multiplier", 50.0).SetDisplay("Multiplier", "Multiplier for Supertrend calculation", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(1))).SetDisplay("Candle Type", "Type of candles to use", "General")
self._prev_is_price_above = False
self._prev_supertrend = 0.0
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(supertrend_strategy, self).OnReseted()
self._prev_is_price_above = False
self._prev_supertrend = 0.0
def OnStarted2(self, time):
super(supertrend_strategy, self).OnStarted2(time)
atr = AverageTrueRange()
atr.Length = self._period.Value
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(atr, self._process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawOwnTrades(area)
def _process_candle(self, candle, atr_val):
if candle.State != CandleStates.Finished:
return
atr_v = float(atr_val)
mult = float(self._multiplier.Value)
median = float(candle.HighPrice + candle.LowPrice) / 2.0
basic_upper = median + mult * atr_v
basic_lower = median - mult * atr_v
if self._prev_supertrend == 0:
st = basic_lower if float(candle.ClosePrice) > median else basic_upper
self._prev_supertrend = st
self._prev_is_price_above = float(candle.ClosePrice) > st
return
high = float(candle.HighPrice)
low = float(candle.LowPrice)
close = float(candle.ClosePrice)
if self._prev_supertrend <= high:
st = max(basic_lower, self._prev_supertrend)
elif self._prev_supertrend >= low:
st = min(basic_upper, self._prev_supertrend)
else:
st = basic_lower if close > self._prev_supertrend else basic_upper
is_above = close > st
crossed_above = is_above and not self._prev_is_price_above
crossed_below = not is_above and self._prev_is_price_above
if crossed_above and self.Position <= 0:
self.BuyMarket(self.Volume + abs(self.Position))
elif crossed_below and self.Position >= 0:
self.SellMarket(self.Volume + abs(self.Position))
self._prev_supertrend = st
self._prev_is_price_above = is_above
def CreateClone(self):
return supertrend_strategy()