Combines Parabolic SAR signals from multiple timeframes. Long trades trigger when price stays above the SAR levels selected by the parameters. Short trades appear when price falls below the chosen SARs. Optional stop loss, trailing stop and take profit are available.
Details
Entry Criteria:
Long: Price above SAR according to LongSource setting.
Short: Price below SAR according to ShortSource setting.
Exit Criteria:
Opposite SAR crossover or protection triggers.
Indicators:
Parabolic SAR on current timeframe
Optional Parabolic SAR on higher and lower timeframes
Stops: Optional stop loss, trailing stop, take profit via StartProtection.
Default Values:
Acceleration = 0.02
MaxAcceleration = 0.2
StopLossPercent = 1
TrailingPercent = 0.5
TakeProfitPercent = 2
Filters:
Timeframe: main 5m, higher 1d, lower 1m
Indicators: Parabolic SAR
Stops: optional
Complexity: Moderate
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>
/// Parabolic SAR-style strategy using EMA and RSI.
/// </summary>
public class MultiTimeframeParabolicSarStrategy : Strategy
{
private readonly StrategyParam<int> _emaLength;
private readonly StrategyParam<int> _rsiLength;
private readonly StrategyParam<DataType> _candleType;
public int EmaLength { get => _emaLength.Value; set => _emaLength.Value = value; }
public int RsiLength { get => _rsiLength.Value; set => _rsiLength.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public MultiTimeframeParabolicSarStrategy()
{
_emaLength = Param(nameof(EmaLength), 20)
.SetGreaterThanZero()
.SetDisplay("EMA", "EMA period", "Indicators");
_rsiLength = Param(nameof(RsiLength), 14)
.SetGreaterThanZero()
.SetDisplay("RSI", "RSI period", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(2).TimeFrame())
.SetDisplay("Candle Type", "Type of candles", "General");
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var ema = new ExponentialMovingAverage { Length = EmaLength };
var rsi = new RelativeStrengthIndex { Length = RsiLength };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(ema, rsi, (candle, emaVal, rsiVal) =>
{
if (candle.State != CandleStates.Finished)
return;
if (!ema.IsFormed || !rsi.IsFormed)
return;
// Buy when price above EMA and RSI confirms uptrend
if (candle.ClosePrice > emaVal && rsiVal > 50 && Position <= 0)
BuyMarket();
// Sell when price below EMA and RSI confirms downtrend
else if (candle.ClosePrice < emaVal && rsiVal < 50 && Position > 0)
SellMarket();
})
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, ema);
DrawOwnTrades(area);
}
}
}
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 ExponentialMovingAverage, RelativeStrengthIndex
from StockSharp.Algo.Strategies import Strategy
class multi_timeframe_parabolic_sar_strategy(Strategy):
def __init__(self):
super(multi_timeframe_parabolic_sar_strategy, self).__init__()
self._ema_length = self.Param("EmaLength", 20) \
.SetGreaterThanZero() \
.SetDisplay("EMA", "EMA period", "Indicators")
self._rsi_length = self.Param("RsiLength", 14) \
.SetGreaterThanZero() \
.SetDisplay("RSI", "RSI period", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(2))) \
.SetDisplay("Candle Type", "Type of candles", "General")
@property
def candle_type(self):
return self._candle_type.Value
@candle_type.setter
def candle_type(self, value):
self._candle_type.Value = value
def OnReseted(self):
super(multi_timeframe_parabolic_sar_strategy, self).OnReseted()
def OnStarted2(self, time):
super(multi_timeframe_parabolic_sar_strategy, self).OnStarted2(time)
self._ema = ExponentialMovingAverage()
self._ema.Length = self._ema_length.Value
self._rsi = RelativeStrengthIndex()
self._rsi.Length = self._rsi_length.Value
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(self._ema, self._rsi, self.OnProcess).Start()
def OnProcess(self, candle, ema_val, rsi_val):
if candle.State != CandleStates.Finished:
return
if not self._ema.IsFormed or not self._rsi.IsFormed:
return
ev = float(ema_val)
rv = float(rsi_val)
close = float(candle.ClosePrice)
if close > ev and rv > 50.0 and self.Position <= 0:
self.BuyMarket()
elif close < ev and rv < 50.0 and self.Position > 0:
self.SellMarket()
def CreateClone(self):
return multi_timeframe_parabolic_sar_strategy()