Die Strategie implementiert den Brake Parabolic-Indikator, der eine parabolische Barriere ober- oder unterhalb des Preises projiziert. Wenn die Barriere durchbrochen wird, kehrt sich der Trend um und eine neue Position in Richtung des Ausbruchs wird eröffnet. Der Algorithmus verfolgt den Extrempreis mit einer Kurve, die durch die Parameter A, B und Shift definiert ist.
Tests zeigen eine durchschnittliche Jahresrendite von etwa 48%. Am besten funktioniert die Strategie in Trendmärkten auf höheren Zeitrahmen.
Das System wartet darauf, dass die Barriere die Seite wechselt. Ein bullischer Flip schließt alle Short-Positionen und eröffnet eine neue Long-Position. Ein bärischer Flip schließt alle Long-Positionen und eröffnet eine Short-Position. Während eines Trends werden entgegengesetzte Positionen geschlossen, wenn der Indikator die Richtung bestätigt.
Details
Einstiegskriterien:
Long: Barriere wechselt von oberhalb des Preises zu unterhalb des Preises.
Short: Barriere wechselt von unterhalb des Preises zu oberhalb des Preises.
Long/Short: Beide Richtungen.
Ausstiegskriterien: Entgegengesetztes Signal oder Indikator bestätigt Gegentrend.
Stops: Keine festen Stops; Ausstiege basieren auf Barriereumkehr.
Standardwerte:
A = 1.5
B = 1.0
BeginShift = 10
CandleType = 4-Stunden-Zeitrahmen
Filter:
Kategorie: Trend
Richtung: Beide
Indikatoren: Benutzerdefiniert
Stops: Nein
Komplexität: Moderat
Zeitrahmen: Swing
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>
/// Parabolic SAR crossover strategy.
/// </summary>
public class BrakeParabolicStrategy : Strategy
{
private readonly StrategyParam<decimal> _sarStep;
private readonly StrategyParam<decimal> _sarMax;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevClose;
private decimal _prevSar;
private bool _hasPrev;
public decimal SarStep { get => _sarStep.Value; set => _sarStep.Value = value; }
public decimal SarMax { get => _sarMax.Value; set => _sarMax.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public BrakeParabolicStrategy()
{
_sarStep = Param(nameof(SarStep), 0.02m)
.SetDisplay("SAR Step", "Acceleration step", "Indicators");
_sarMax = Param(nameof(SarMax), 0.2m)
.SetDisplay("SAR Max", "Maximum acceleration", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Candle type", "General");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
protected override void OnReseted()
{
base.OnReseted();
_prevClose = 0;
_prevSar = 0;
_hasPrev = false;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var sar = new ParabolicSar { AccelerationStep = SarStep, AccelerationMax = SarMax };
SubscribeCandles(CandleType)
.Bind(sar, ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle, decimal sarVal)
{
if (candle.State != CandleStates.Finished) return;
var close = candle.ClosePrice;
if (!_hasPrev)
{
_prevClose = close;
_prevSar = sarVal;
_hasPrev = true;
return;
}
var crossUp = _prevClose <= _prevSar && close > sarVal;
var crossDown = _prevClose >= _prevSar && close < sarVal;
if (crossUp && Position <= 0)
{
if (Position < 0) BuyMarket();
BuyMarket();
}
else if (crossDown && Position >= 0)
{
if (Position > 0) SellMarket();
SellMarket();
}
_prevClose = close;
_prevSar = sarVal;
}
}
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 ParabolicSar
from StockSharp.Algo.Strategies import Strategy
class brake_parabolic_strategy(Strategy):
def __init__(self):
super(brake_parabolic_strategy, self).__init__()
self._sar_step = self.Param("SarStep", 0.02) .SetDisplay("SAR Step", "Acceleration step", "Indicators")
self._sar_max = self.Param("SarMax", 0.2) .SetDisplay("SAR Max", "Maximum acceleration", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) .SetDisplay("Candle Type", "Candle type", "General")
self._prev_close = 0.0
self._prev_sar = 0.0
self._has_prev = False
@property
def sar_step(self):
return self._sar_step.Value
@property
def sar_max(self):
return self._sar_max.Value
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(brake_parabolic_strategy, self).OnReseted()
self._prev_close = 0.0
self._prev_sar = 0.0
self._has_prev = False
def OnStarted2(self, time):
super(brake_parabolic_strategy, self).OnStarted2(time)
sar = ParabolicSar()
sar.AccelerationStep = self.sar_step
sar.AccelerationMax = self.sar_max
self.SubscribeCandles(self.candle_type).Bind(sar, self.process_candle).Start()
def process_candle(self, candle, sar_val):
if candle.State != CandleStates.Finished:
return
close = float(candle.ClosePrice)
sv = float(sar_val)
if not self._has_prev:
self._prev_close = close
self._prev_sar = sv
self._has_prev = True
return
cross_up = self._prev_close <= self._prev_sar and close > sv
cross_down = self._prev_close >= self._prev_sar and close < sv
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_close = close
self._prev_sar = sv
def CreateClone(self):
return brake_parabolic_strategy()