Verwendet den Parabolic SAR-Indikator mit konfigurierbarem Schritt und maximaler Beschleunigung.
Kauft, wenn der Preis über dem SAR schließt und zuvor darunter war.
Verkauft, wenn der Preis unter dem SAR schließt und zuvor darüber war.
Der optionale Umkehrparameter invertiert die Kauf-/Verkaufssignale.
Die Option SarClose schließt die bestehende Position, wenn der SAR auf die entgegengesetzte Seite wechselt.
Feste Take-Profit- und Stop-Loss-Abstände in Preiseinheiten. Trailing Stop kann aktiviert werden.
Parameter
SarStep – Schritt des Beschleunigungsfaktors.
SarMax – maximaler Beschleunigungsfaktor.
StopLoss – anfänglicher Stop-Loss-Abstand.
TakeProfit – Take-Profit-Abstand.
Trailing – Trailing Stop aktivieren.
TrailStop – Trailing-Stop-Abstand bei aktiviertem Trailing.
SarClose – Position bei SAR-Umkehr schließen.
Reverse – Trading-Signale invertieren.
CandleType – Kerzentyp für Berechnungen.
Hinweise
Die Strategie verwendet die High-Level-API mit Kerzenabonnements und Indikator-Bindung. Der Schutz wird mit optionalem Trailing Stop gestartet, Ausstiege erfolgen per Marktorder.
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 strategy - opens long when price crosses above SAR, short when below.
/// </summary>
public class PsarBug6Strategy : Strategy
{
private readonly StrategyParam<decimal> _sarStep;
private readonly StrategyParam<decimal> _sarMax;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevSar;
private decimal _prevClose;
private bool _initialized;
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 PsarBug6Strategy()
{
_sarStep = Param(nameof(SarStep), 0.02m)
.SetDisplay("SAR Step", "Acceleration factor step", "Indicator");
_sarMax = Param(nameof(SarMax), 0.2m)
.SetDisplay("SAR Max", "Maximum acceleration factor", "Indicator");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Type of candles", "General");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
protected override void OnReseted()
{
base.OnReseted();
_prevSar = 0;
_prevClose = 0;
_initialized = false;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var psar = new ParabolicSar
{
AccelerationStep = SarStep,
AccelerationMax = SarMax
};
var subscription = SubscribeCandles(CandleType);
subscription.Bind(psar, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal sar)
{
if (candle.State != CandleStates.Finished)
return;
if (!_initialized)
{
_prevSar = sar;
_prevClose = candle.ClosePrice;
_initialized = true;
return;
}
var close = candle.ClosePrice;
var crossUp = close > sar && _prevClose <= _prevSar;
var crossDown = close < sar && _prevClose >= _prevSar;
if (crossUp && Position <= 0)
{
if (Position < 0) BuyMarket();
BuyMarket();
}
else if (crossDown && Position >= 0)
{
if (Position > 0) SellMarket();
SellMarket();
}
_prevSar = sar;
_prevClose = close;
}
}
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 psar_bug6_strategy(Strategy):
def __init__(self):
super(psar_bug6_strategy, self).__init__()
self._sar_step = self.Param("SarStep", 0.02) \
.SetDisplay("SAR Step", "Acceleration factor step", "Indicator")
self._sar_max = self.Param("SarMax", 0.2) \
.SetDisplay("SAR Max", "Maximum acceleration factor", "Indicator")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Type of candles", "General")
self._prev_sar = 0.0
self._prev_close = 0.0
self._initialized = 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(psar_bug6_strategy, self).OnReseted()
self._prev_sar = 0.0
self._prev_close = 0.0
self._initialized = False
def OnStarted2(self, time):
super(psar_bug6_strategy, self).OnStarted2(time)
psar = ParabolicSar()
psar.AccelerationStep = self.sar_step
psar.AccelerationMax = self.sar_max
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(psar, self.on_process).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawOwnTrades(area)
def on_process(self, candle, sar):
if candle.State != CandleStates.Finished:
return
if not self._initialized:
self._prev_sar = sar
self._prev_close = candle.ClosePrice
self._initialized = True
return
close = candle.ClosePrice
cross_up = close > sar and self._prev_close <= self._prev_sar
cross_down = close < sar and self._prev_close >= self._prev_sar
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_sar = sar
self._prev_close = close
def CreateClone(self):
return psar_bug6_strategy()