Strategie Parabolic Sar Rsi
Strategie, die den Parabolic SAR zur Bestimmung der Trendrichtung und den RSI zur Einstiegsbestätigung mit überkauften/überverkauften Bedingungen kombiniert.
Tests zeigen eine durchschnittliche jährliche Rendite von etwa 166%. Sie funktioniert am besten im Aktienmarkt.
Hier skizziert der Parabolic SAR den vorherrschenden Trend und der RSI misst die Erschöpfung. Trades werden eröffnet, sobald beide Indikatoren dieselbe Richtung signalisieren.
Die Kombination ist attraktiv für diejenigen, die Trailing Stops mögen, da SAR auch einen dynamischen Ausstieg bietet. Die Stop-Platzierung folgt der SAR-Kurve.
Details
- Einstiegskriterien:
- Long:
Close > SAR && RSI < RsiOversold - Short:
Close < SAR && RSI > RsiOverbought
- Long:
- Long/Short: Beide
- Ausstiegskriterien:
- Long:
Close < SAR - Short:
Close > SAR
- Long:
- Stops: Verwendet Parabolic SAR als Trailing Stop
- Standardwerte:
SarAf= 0.02mSarMaxAf= 0.2mRsiPeriod= 14RsiOversold= 30mRsiOverbought= 70mCandleType= TimeSpan.FromMinutes(5).TimeFrame() Ein Einstiegssignal gegen eine offene Position dreht sie.
- Filter:
- Kategorie: Mean Reversion
- Richtung: Beide
- Indikatoren: Parabolic SAR, Parabolic SAR, RSI
- Stops: Ja
- Komplexität: Mittel
- Zeitrahmen: Mittelfristig
- 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 RSI strategy.
/// A close above the Parabolic SAR with RSI below RsiOversold goes long and a close below the SAR with RSI above RsiOverbought goes short,
/// reversing an opposite position. The SAR is the trailing stop: a long closes when price closes below it and a short when price closes above it.
/// </summary>
public class ParabolicSarRsiStrategy : Strategy
{
private readonly StrategyParam<decimal> _sarAf;
private readonly StrategyParam<decimal> _sarMaxAf;
private readonly StrategyParam<int> _rsiPeriod;
private readonly StrategyParam<decimal> _rsiOversold;
private readonly StrategyParam<decimal> _rsiOverbought;
private readonly StrategyParam<DataType> _candleType;
/// <summary>
/// Initial acceleration factor of the SAR.
/// </summary>
public decimal SarAf
{
get => _sarAf.Value;
set => _sarAf.Value = value;
}
/// <summary>
/// Maximum acceleration factor of the SAR.
/// </summary>
public decimal SarMaxAf
{
get => _sarMaxAf.Value;
set => _sarMaxAf.Value = value;
}
/// <summary>
/// Period of RSI.
/// </summary>
public int RsiPeriod
{
get => _rsiPeriod.Value;
set => _rsiPeriod.Value = value;
}
/// <summary>
/// RSI level for longs.
/// </summary>
public decimal RsiOversold
{
get => _rsiOversold.Value;
set => _rsiOversold.Value = value;
}
/// <summary>
/// RSI level for shorts.
/// </summary>
public decimal RsiOverbought
{
get => _rsiOverbought.Value;
set => _rsiOverbought.Value = value;
}
/// <summary>
/// Candle type.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Constructor.
/// </summary>
public ParabolicSarRsiStrategy()
{
_sarAf = Param(nameof(SarAf), 0.02m)
.SetGreaterThanZero()
.SetDisplay("SAR Acceleration", "Initial acceleration factor of the SAR", "SAR");
_sarMaxAf = Param(nameof(SarMaxAf), 0.2m)
.SetGreaterThanZero()
.SetDisplay("SAR Max Acceleration", "Maximum acceleration factor of the SAR", "SAR");
_rsiPeriod = Param(nameof(RsiPeriod), 14)
.SetGreaterThanZero()
.SetDisplay("RSI Period", "Period of RSI", "RSI");
_rsiOversold = Param(nameof(RsiOversold), 30m)
.SetDisplay("RSI Oversold", "RSI level for longs", "RSI");
_rsiOverbought = Param(nameof(RsiOverbought), 70m)
.SetDisplay("RSI Overbought", "RSI level for shorts", "RSI");
_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 OnStarted2(DateTime time)
{
base.OnStarted2(time);
var sar = new ParabolicSar
{
Acceleration = SarAf,
AccelerationMax = SarMaxAf,
};
var rsi = new RelativeStrengthIndex { Length = RsiPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.BindEx(sar, rsi, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, sar);
DrawOwnTrades(area);
var oscillators = CreateChartArea();
if (oscillators != null)
{
DrawIndicator(oscillators, rsi);
}
}
}
private void ProcessCandle(ICandleMessage candle, IIndicatorValue sarValue, IIndicatorValue rsiValue)
{
if (candle.State != CandleStates.Finished)
return;
// The first SAR value is formed but empty.
if (!sarValue.IsFormed || sarValue.IsEmpty || !rsiValue.IsFormed)
return;
var sar = sarValue.GetValue<decimal>();
var rsi = rsiValue.GetValue<decimal>();
var close = candle.ClosePrice;
if (!IsFormedAndOnlineAndAllowTrading())
return;
if (close > sar && rsi < RsiOversold && Position <= 0)
BuyMarket(Volume + Math.Abs(Position));
else if (close < sar && rsi > RsiOverbought && Position >= 0)
SellMarket(Volume + Math.Abs(Position));
else if (Position > 0 && close < sar)
SellMarket(Position);
else if (Position < 0 && close > sar)
BuyMarket(-Position);
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan, Decimal
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import ParabolicSar, RelativeStrengthIndex
from StockSharp.Algo.Strategies import Strategy
class parabolic_sar_rsi_strategy(Strategy):
"""
Parabolic SAR RSI strategy.
A close above the Parabolic SAR with RSI below RsiOversold goes long and a close below the SAR with RSI above RsiOverbought goes short,
reversing an opposite position. The SAR is the trailing stop: a long closes when price closes below it and a short when price closes above it.
"""
def __init__(self):
super(parabolic_sar_rsi_strategy, self).__init__()
self._sar_af = self.Param("SarAf", 0.02).SetGreaterThanZero().SetDisplay("SAR Acceleration", "Initial acceleration factor of the SAR", "SAR")
self._sar_max_af = self.Param("SarMaxAf", 0.2).SetGreaterThanZero().SetDisplay("SAR Max Acceleration", "Maximum acceleration factor of the SAR", "SAR")
self._rsi_period = self.Param("RsiPeriod", 14).SetGreaterThanZero().SetDisplay("RSI Period", "Period of RSI", "RSI")
self._rsi_oversold = self.Param("RsiOversold", 30.0).SetDisplay("RSI Oversold", "RSI level for longs", "RSI")
self._rsi_overbought = self.Param("RsiOverbought", 70.0).SetDisplay("RSI Overbought", "RSI level for shorts", "RSI")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))).SetDisplay("Candle Type", "Type of candles to use", "General")
@property
def candle_type(self):
return self._candle_type.Value
def OnStarted2(self, time):
super(parabolic_sar_rsi_strategy, self).OnStarted2(time)
sar = ParabolicSar()
sar.Acceleration = Decimal(self._sar_af.Value)
sar.AccelerationMax = Decimal(self._sar_max_af.Value)
rsi = RelativeStrengthIndex()
rsi.Length = self._rsi_period.Value
subscription = self.SubscribeCandles(self.candle_type)
subscription.BindEx(sar, rsi, self._process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, sar)
self.DrawOwnTrades(area)
oscillators = self.CreateChartArea()
if oscillators is not None:
self.DrawIndicator(oscillators, rsi)
def _process_candle(self, candle, sar_value, rsi_value):
if candle.State != CandleStates.Finished:
return
# The first SAR value is formed but empty.
if not sar_value.IsFormed or sar_value.IsEmpty or not rsi_value.IsFormed:
return
sar = sar_value.GetValue[Decimal](None)
rsi = rsi_value.GetValue[Decimal](None)
close = candle.ClosePrice
if not self.IsFormedAndOnlineAndAllowTrading():
return
if close > sar and rsi < Decimal(self._rsi_oversold.Value) and self.Position <= 0:
self.BuyMarket(self.Volume + abs(self.Position))
elif close < sar and rsi > Decimal(self._rsi_overbought.Value) and self.Position >= 0:
self.SellMarket(self.Volume + abs(self.Position))
elif self.Position > 0 and close < sar:
self.SellMarket(self.Position)
elif self.Position < 0 and close > sar:
self.BuyMarket(-self.Position)
def CreateClone(self):
return parabolic_sar_rsi_strategy()