Estrategia Larry Connors RSI 3
Estrategia de reversión a la media basada en las reglas RSI de Larry Connors.
La estrategia compra cuando el precio está por encima de la SMA de 200 períodos y el RSI de 2 períodos ha caído tres días seguidos desde por encima del nivel de activación hasta territorio de sobreventa. Las posiciones se cierran cuando el RSI sube por encima del nivel de sobrecompra.
Detalles
- Criterios de entrada: Cierre por encima de la SMA y RSI de 2 períodos cayendo tres días desde por encima del activador hasta la sobreventa.
- Largo/Corto: Solo largos.
- Criterios de salida: RSI por encima del nivel de sobrecompra.
- Stops: No.
- Valores predeterminados:
RsiPeriod= 2SmaPeriod= 200DropTrigger= 60mOversoldLevel= 10mOverboughtLevel= 70mCandleType= TimeSpan.FromDays(1)
- Filtros:
- Categoría: Reversión a la media
- Dirección: Largo
- Indicadores: RSI, SMA
- Stops: No
- Complejidad: Básico
- Marco temporal: Diario
- Estacionalidad: No
- Redes neuronales: No
- Divergencia: No
- Nivel de riesgo: Bajo
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>
/// Larry Connors RSI 3 strategy.
/// Combines a long-term trend filter with short-term RSI exhaustion.
/// </summary>
public class LarryConnorsRsi3Strategy : Strategy
{
private readonly StrategyParam<int> _rsiPeriod;
private readonly StrategyParam<int> _smaPeriod;
private readonly StrategyParam<decimal> _dropTrigger;
private readonly StrategyParam<decimal> _oversoldLevel;
private readonly StrategyParam<decimal> _overboughtLevel;
private readonly StrategyParam<int> _maxEntries;
private readonly StrategyParam<int> _cooldownBars;
private readonly StrategyParam<DataType> _candleType;
private decimal _rsiPrev1;
private decimal _rsiPrev2;
private int _entriesExecuted;
private int _barsSinceSignal;
/// <summary>
/// RSI period.
/// </summary>
public int RsiPeriod
{
get => _rsiPeriod.Value;
set => _rsiPeriod.Value = value;
}
/// <summary>
/// SMA period.
/// </summary>
public int SmaPeriod
{
get => _smaPeriod.Value;
set => _smaPeriod.Value = value;
}
/// <summary>
/// RSI trigger level for drop start.
/// </summary>
public decimal DropTrigger
{
get => _dropTrigger.Value;
set => _dropTrigger.Value = value;
}
/// <summary>
/// RSI oversold level.
/// </summary>
public decimal OversoldLevel
{
get => _oversoldLevel.Value;
set => _oversoldLevel.Value = value;
}
/// <summary>
/// RSI overbought level.
/// </summary>
public decimal OverboughtLevel
{
get => _overboughtLevel.Value;
set => _overboughtLevel.Value = value;
}
/// <summary>
/// Candle type.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Maximum entries per run.
/// </summary>
public int MaxEntries
{
get => _maxEntries.Value;
set => _maxEntries.Value = value;
}
/// <summary>
/// Minimum bars between orders.
/// </summary>
public int CooldownBars
{
get => _cooldownBars.Value;
set => _cooldownBars.Value = value;
}
/// <summary>
/// Initializes a new instance of <see cref="LarryConnorsRsi3Strategy"/>.
/// </summary>
public LarryConnorsRsi3Strategy()
{
_rsiPeriod = Param(nameof(RsiPeriod), 2)
.SetDisplay("RSI Period", "Period for RSI calculation", "Indicators")
.SetOptimize(2, 5, 1);
_smaPeriod = Param(nameof(SmaPeriod), 50)
.SetDisplay("SMA Period", "Period for trend SMA", "Indicators")
.SetOptimize(50, 300, 50);
_dropTrigger = Param(nameof(DropTrigger), 20m)
.SetDisplay("Drop Trigger", "RSI level required before drop", "Strategy")
.SetOptimize(50m, 70m, 5m);
_oversoldLevel = Param(nameof(OversoldLevel), 50m)
.SetDisplay("Oversold Level", "RSI oversold threshold", "Strategy")
.SetOptimize(5m, 20m, 1m);
_overboughtLevel = Param(nameof(OverboughtLevel), 70m)
.SetDisplay("Overbought Level", "RSI exit threshold", "Strategy")
.SetOptimize(60m, 80m, 5m);
_maxEntries = Param(nameof(MaxEntries), 45)
.SetDisplay("Max Entries", "Maximum entries per run", "Risk");
_cooldownBars = Param(nameof(CooldownBars), 20)
.SetDisplay("Cooldown Bars", "Minimum bars between orders", "Risk");
_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 OnReseted()
{
base.OnReseted();
_rsiPrev1 = 0m;
_rsiPrev2 = 0m;
_entriesExecuted = 0;
_barsSinceSignal = 0;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_entriesExecuted = 0;
_barsSinceSignal = CooldownBars;
var sma = new SimpleMovingAverage { Length = SmaPeriod };
var rsi = new RelativeStrengthIndex { Length = RsiPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(sma, rsi, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, sma);
DrawIndicator(area, rsi);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal smaValue, decimal rsiValue)
{
if (candle.State != CandleStates.Finished)
return;
_barsSinceSignal++;
var condition3 = rsiValue > 0 && rsiValue < OversoldLevel;
if (condition3 && Position <= 0 && _entriesExecuted < MaxEntries && _barsSinceSignal >= CooldownBars)
{
BuyMarket();
_entriesExecuted++;
_barsSinceSignal = 0;
}
else if (rsiValue > OverboughtLevel && Position > 0)
{
SellMarket();
_barsSinceSignal = 0;
}
_rsiPrev2 = _rsiPrev1;
_rsiPrev1 = rsiValue;
}
}
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 SimpleMovingAverage, RelativeStrengthIndex
from StockSharp.Algo.Strategies import Strategy
class larry_connors_rsi_3_strategy(Strategy):
def __init__(self):
super(larry_connors_rsi_3_strategy, self).__init__()
self._rsi_period = self.Param("RsiPeriod", 2) \
.SetDisplay("RSI Period", "Period for RSI calculation", "Indicators")
self._sma_period = self.Param("SmaPeriod", 50) \
.SetDisplay("SMA Period", "Period for trend SMA", "Indicators")
self._oversold_level = self.Param("OversoldLevel", 50.0) \
.SetDisplay("Oversold Level", "RSI oversold threshold", "Strategy")
self._overbought_level = self.Param("OverboughtLevel", 70.0) \
.SetDisplay("Overbought Level", "RSI exit threshold", "Strategy")
self._max_entries = self.Param("MaxEntries", 45) \
.SetDisplay("Max Entries", "Maximum entries per run", "Risk")
self._cooldown_bars = self.Param("CooldownBars", 20) \
.SetDisplay("Cooldown Bars", "Minimum bars between orders", "Risk")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))) \
.SetDisplay("Candle Type", "Type of candles to use", "General")
self._entries_executed = 0
self._bars_since_signal = 0
@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(larry_connors_rsi_3_strategy, self).OnReseted()
self._entries_executed = 0
self._bars_since_signal = 0
def OnStarted2(self, time):
super(larry_connors_rsi_3_strategy, self).OnStarted2(time)
self._entries_executed = 0
self._bars_since_signal = self._cooldown_bars.Value
sma = SimpleMovingAverage()
sma.Length = self._sma_period.Value
rsi = RelativeStrengthIndex()
rsi.Length = self._rsi_period.Value
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(sma, rsi, self.OnProcess).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, sma)
self.DrawIndicator(area, rsi)
self.DrawOwnTrades(area)
def OnProcess(self, candle, sma_val, rsi_val):
if candle.State != CandleStates.Finished:
return
self._bars_since_signal += 1
rv = float(rsi_val)
oversold = float(self._oversold_level.Value)
overbought = float(self._overbought_level.Value)
cond = rv > 0.0 and rv < oversold
if cond and self.Position <= 0 and self._entries_executed < self._max_entries.Value and self._bars_since_signal >= self._cooldown_bars.Value:
self.BuyMarket()
self._entries_executed += 1
self._bars_since_signal = 0
elif rv > overbought and self.Position > 0:
self.SellMarket()
self._bars_since_signal = 0
def CreateClone(self):
return larry_connors_rsi_3_strategy()