Strategie Kolier SuperTrend
Strategie basierend auf dem Kolier SuperTrend-Indikator, der ATR-Bänder zur Erkennung von Trendumkehrungen verwendet.
Der Indikator zeichnet dynamische Unterstützungs- und Widerstandsniveaus, die vom ATR abgeleitet werden. Eine bullische Umkehr tritt auf, wenn der Preis über dem unteren Band schließt und die Linie unter den Preis kippt. Eine bärische Umkehr tritt auf, wenn der Preis unter dem oberen Band schließt.
Durch das Verfolgen dieses adaptiven Trails versucht die Strategie, starke Trends zu reiten und gleichzeitig geschützt zu bleiben, wenn das Momentum nachlässt.
Details
- Einstiegskriterien: Preis kreuzt die SuperTrend-Linie.
- Long/Short: Beide Richtungen.
- Ausstiegskriterien: Entgegengesetzter Crossover.
- Stops: Nein.
- Standardwerte:
Period= 10Multiplier= 3.0mCandleType= TimeSpan.FromHours(4)
- Filter:
- Kategorie: Trend
- Richtung: Beide
- Indikatoren: ATR, SuperTrend
- Stops: Nein
- Komplexität: Grundlegend
- Zeitrahmen: Swing (4h)
- 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>
/// Kolier SuperTrend strategy based on ATR bands.
/// Enters long when price crosses above the SuperTrend line and short when crossing below.
/// </summary>
public class KolierSuperTrendStrategy : Strategy
{
private readonly StrategyParam<int> _period;
private readonly StrategyParam<decimal> _multiplier;
private readonly StrategyParam<DataType> _candleType;
private AverageTrueRange _atr;
private bool _prevPriceAbove;
private decimal _prevSupertrend;
private bool _isInitialized;
public int Period { get => _period.Value; set => _period.Value = value; }
public decimal Multiplier { get => _multiplier.Value; set => _multiplier.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public KolierSuperTrendStrategy()
{
_period = Param(nameof(Period), 10)
.SetDisplay("ATR Period", "ATR period for SuperTrend", "Indicators")
.SetOptimize(5, 20, 1);
_multiplier = Param(nameof(Multiplier), 3.0m)
.SetDisplay("ATR Multiplier", "ATR multiplier for SuperTrend", "Indicators")
.SetOptimize(2.0m, 4.0m, 0.5m);
_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();
_prevPriceAbove = false;
_prevSupertrend = 0m;
_isInitialized = false;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_atr = new AverageTrueRange { Length = Period };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle)
{
if (candle.State != CandleStates.Finished)
return;
var atrResult = _atr.Process(candle);
if (!atrResult.IsFormed)
return;
var atrValue = atrResult.ToDecimal();
var median = (candle.HighPrice + candle.LowPrice) / 2m;
var upper = median + Multiplier * atrValue;
var lower = median - Multiplier * atrValue;
decimal supertrend;
if (!_isInitialized)
{
supertrend = candle.ClosePrice > median ? lower : upper;
_prevSupertrend = supertrend;
_prevPriceAbove = candle.ClosePrice > supertrend;
_isInitialized = true;
return;
}
if (_prevSupertrend <= candle.HighPrice)
supertrend = Math.Max(lower, _prevSupertrend);
else if (_prevSupertrend >= candle.LowPrice)
supertrend = Math.Min(upper, _prevSupertrend);
else
supertrend = candle.ClosePrice > _prevSupertrend ? lower : upper;
var priceAbove = candle.ClosePrice > supertrend;
var crossUp = priceAbove && !_prevPriceAbove;
var crossDown = !priceAbove && _prevPriceAbove;
if (crossUp && Position <= 0)
{
if (Position < 0) BuyMarket();
BuyMarket();
}
else if (crossDown && Position >= 0)
{
if (Position > 0) SellMarket();
SellMarket();
}
_prevSupertrend = supertrend;
_prevPriceAbove = priceAbove;
}
}
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 AverageTrueRange, CandleIndicatorValue
from StockSharp.Algo.Strategies import Strategy
class kolier_super_trend_strategy(Strategy):
"""
Kolier SuperTrend: ATR-based trend following.
Enters long when price crosses above SuperTrend, short when below.
"""
def __init__(self):
super(kolier_super_trend_strategy, self).__init__()
self._period = self.Param("Period", 10) \
.SetDisplay("ATR Period", "ATR period for SuperTrend", "Indicators")
self._multiplier = self.Param("Multiplier", 3.0) \
.SetDisplay("ATR Multiplier", "ATR multiplier for SuperTrend", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))) \
.SetDisplay("Candle Type", "Type of candles", "General")
self._atr = None
self._prev_price_above = False
self._prev_supertrend = 0.0
self._is_initialized = False
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(kolier_super_trend_strategy, self).OnReseted()
self._prev_price_above = False
self._prev_supertrend = 0.0
self._is_initialized = False
def OnStarted2(self, time):
super(kolier_super_trend_strategy, self).OnStarted2(time)
self._atr = AverageTrueRange()
self._atr.Length = self._period.Value
self.Indicators.Add(self._atr)
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(self._process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawOwnTrades(area)
def _process_candle(self, candle):
if candle.State != CandleStates.Finished:
return
atr_inp = CandleIndicatorValue(self._atr, candle)
atr_result = self._atr.Process(atr_inp)
if not atr_result.IsFormed:
return
atr_val = float(atr_result)
high = float(candle.HighPrice)
low = float(candle.LowPrice)
close = float(candle.ClosePrice)
median = (high + low) / 2.0
mult = self._multiplier.Value
upper = median + mult * atr_val
lower = median - mult * atr_val
if not self._is_initialized:
supertrend = lower if close > median else upper
self._prev_supertrend = supertrend
self._prev_price_above = close > supertrend
self._is_initialized = True
return
if self._prev_supertrend <= high:
supertrend = max(lower, self._prev_supertrend)
elif self._prev_supertrend >= low:
supertrend = min(upper, self._prev_supertrend)
else:
supertrend = lower if close > self._prev_supertrend else upper
price_above = close > supertrend
cross_up = price_above and not self._prev_price_above
cross_down = not price_above and self._prev_price_above
if cross_up and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
elif cross_down and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._prev_supertrend = supertrend
self._prev_price_above = price_above
def CreateClone(self):
return kolier_super_trend_strategy()