Início
/
Exemplos de estratégias
Ver no GitHub
MTF RSI SAR Strategy
This strategy combines Relative Strength Index (RSI) readings across four timeframes, Parabolic SAR , and Bollinger Bands to capture trend continuation after short pullbacks. Signals are generated on 5‑minute candles while higher timeframes act as confirmation filters.
Concept
RSI filter – 5, 15, 30 and 60 minute RSI values must all be above 50 for long entries or below 50 for short entries. This multi‑timeframe confirmation aims to align trades with the broader trend.
Parabolic SAR filter – Parabolic SAR values on 5, 15 and 30 minute charts must be below the current candle for longs or above for shorts. This ensures that price is trending in the desired direction.
Bollinger Band trigger – On the 5‑minute chart the candle close must break the upper band for longs or the lower band for shorts. Bollinger Bands provide an overbought/oversold trigger.
Entry and exit – A long position is opened when all active filters point up. A short position is opened when all active filters point down. The opposite signal closes an open position.
Any of the three filters can be individually disabled via parameters, allowing the strategy to operate with RSI only, Bollinger Bands only, SAR only, or any combination of the above.
Parameters
UseRsi – enable RSI filter (default: true).
UseBollinger – enable Bollinger Band trigger (default: true).
UseSar – enable Parabolic SAR filter (default: true).
RsiPeriod – RSI calculation period (default: 14).
BollingerPeriod – number of bars for Bollinger Bands (default: 20).
BollingerWidth – width (standard deviation multiplier) for Bollinger Bands (default: 2).
SarStep – acceleration factor for Parabolic SAR (default: 0.02).
SarMax – maximum acceleration factor for Parabolic SAR (default: 0.2).
CandleType – base candle timeframe, 5 minutes by default.
Trading Rules
Long : all enabled filters provide bullish signals.
Short : all enabled filters provide bearish signals.
Exit : opposite signal closes the position.
Notes
Strategy operates on one security with four candle subscriptions: 5, 15, 30 and 60 minute timeframes.
Designed as an educational example of multi‑timeframe confirmation using StockSharp's high‑level API.
There are no fixed stop‑loss or profit targets; risk management should be added externally if required.
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>
/// RSI and Parabolic SAR strategy.
/// Buys when RSI below oversold and SAR below price; sells on opposite.
/// </summary>
public class MtfRsiSarStrategy : Strategy
{
private readonly StrategyParam<int> _rsiPeriod;
private readonly StrategyParam<decimal> _rsiOversold;
private readonly StrategyParam<decimal> _rsiOverbought;
private readonly StrategyParam<DataType> _candleType;
public int RsiPeriod { get => _rsiPeriod.Value; set => _rsiPeriod.Value = value; }
public decimal RsiOversold { get => _rsiOversold.Value; set => _rsiOversold.Value = value; }
public decimal RsiOverbought { get => _rsiOverbought.Value; set => _rsiOverbought.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public MtfRsiSarStrategy()
{
_rsiPeriod = Param(nameof(RsiPeriod), 14)
.SetGreaterThanZero()
.SetDisplay("RSI Period", "RSI period", "Indicators");
_rsiOversold = Param(nameof(RsiOversold), 35m)
.SetDisplay("RSI Oversold", "RSI oversold level", "Indicators");
_rsiOverbought = Param(nameof(RsiOverbought), 65m)
.SetDisplay("RSI Overbought", "RSI overbought level", "Indicators");
_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 OnStarted2(DateTime time)
{
base.OnStarted2(time);
var rsi = new RelativeStrengthIndex { Length = RsiPeriod };
var sar = new ParabolicSar();
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(rsi, sar, ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle, decimal rsi, decimal sar)
{
if (candle.State != CandleStates.Finished)
return;
var close = candle.ClosePrice;
// Buy: RSI oversold + SAR below price
if (rsi < RsiOversold && sar < close)
{
if (Position < 0)
BuyMarket();
if (Position <= 0)
BuyMarket();
}
// Sell: RSI overbought + SAR above price
else if (rsi > RsiOverbought && sar > close)
{
if (Position > 0)
SellMarket();
if (Position >= 0)
SellMarket();
}
// Exit long when RSI overbought
else if (Position > 0 && rsi > RsiOverbought)
{
SellMarket();
}
// Exit short when RSI oversold
else if (Position < 0 && rsi < RsiOversold)
{
BuyMarket();
}
}
}
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, RelativeStrengthIndex
from StockSharp.Algo.Strategies import Strategy
class mtf_rsi_sar_strategy(Strategy):
def __init__(self):
super(mtf_rsi_sar_strategy, self).__init__()
self._rsi_period = self.Param("RsiPeriod", 14) \
.SetDisplay("RSI Period", "RSI period", "Indicators")
self._rsi_oversold = self.Param("RsiOversold", 35.0) \
.SetDisplay("RSI Oversold", "RSI oversold level", "Indicators")
self._rsi_overbought = self.Param("RsiOverbought", 65.0) \
.SetDisplay("RSI Overbought", "RSI overbought level", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Type of candles", "General")
@property
def rsi_period(self):
return self._rsi_period.Value
@property
def rsi_oversold(self):
return self._rsi_oversold.Value
@property
def rsi_overbought(self):
return self._rsi_overbought.Value
@property
def candle_type(self):
return self._candle_type.Value
def OnStarted2(self, time):
super(mtf_rsi_sar_strategy, self).OnStarted2(time)
rsi = RelativeStrengthIndex()
rsi.Length = self.rsi_period
sar = ParabolicSar()
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(rsi, sar, self.on_process).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawOwnTrades(area)
def on_process(self, candle, rsi, sar):
if candle.State != CandleStates.Finished:
return
close = candle.ClosePrice
# Buy: RSI oversold + SAR below price
if rsi < self.rsi_oversold and sar < close:
if self.Position < 0:
self.BuyMarket()
if self.Position <= 0:
self.BuyMarket()
# Sell: RSI overbought + SAR above price
elif rsi > self.rsi_overbought and sar > close:
if self.Position > 0:
self.SellMarket()
if self.Position >= 0:
self.SellMarket()
# Exit long when RSI overbought
elif self.Position > 0 and rsi > self.rsi_overbought:
self.SellMarket()
# Exit short when RSI oversold
elif self.Position < 0 and rsi < self.rsi_oversold:
self.BuyMarket()
def CreateClone(self):
return mtf_rsi_sar_strategy()