Estrategia Vinicius Setup ATR
Esta estrategia combina la dirección del SuperTrend, el RSI y el volumen para identificar velas de fuerte momentum. Una señal larga ocurre cuando el precio está por encima del SuperTrend, el cuerpo de la vela supera un umbral basado en ATR, el volumen es mayor al promedio y el RSI permanece por debajo de 70. Una señal corta se activa bajo las condiciones opuestas con el RSI por encima de 30.
Detalles
- Entrada: Precio en la dirección del SuperTrend con vela fuerte y volumen alto.
- Salida: Señal opuesta.
- Indicadores: SuperTrend, RSI, ATR, SMA(Volume).
using System;
using System.Collections.Generic;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Vinicius Setup ATR Strategy.
/// Uses EMA trend direction, RSI, and ATR to find strong momentum candles.
/// </summary>
public class ViniciusSetupATRStrategy : Strategy
{
private readonly StrategyParam<int> _atrLength;
private readonly StrategyParam<int> _emaLength;
private readonly StrategyParam<int> _rsiPeriod;
private readonly StrategyParam<decimal> _minBodyPercent;
private readonly StrategyParam<DataType> _candleType;
private decimal _rsiVal;
private decimal _prevRsi;
private int _cooldown;
public int AtrLength { get => _atrLength.Value; set => _atrLength.Value = value; }
public int EmaLength { get => _emaLength.Value; set => _emaLength.Value = value; }
public int RsiPeriod { get => _rsiPeriod.Value; set => _rsiPeriod.Value = value; }
public decimal MinBodyPercent { get => _minBodyPercent.Value; set => _minBodyPercent.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public ViniciusSetupATRStrategy()
{
_atrLength = Param(nameof(AtrLength), 10)
.SetDisplay("ATR Length", "ATR period", "General")
.SetOptimize(5, 30, 1);
_emaLength = Param(nameof(EmaLength), 50)
.SetGreaterThanZero()
.SetDisplay("EMA Length", "EMA trend filter length", "General");
_rsiPeriod = Param(nameof(RsiPeriod), 14)
.SetDisplay("RSI Period", "RSI length", "General")
.SetOptimize(5, 30, 1);
_minBodyPercent = Param(nameof(MinBodyPercent), 0.5m)
.SetDisplay("Min Body %", "Minimal body size in ATR fractions", "General")
.SetOptimize(0.5m, 3m, 0.5m);
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Type of candles", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_rsiVal = 0;
_prevRsi = 0;
_cooldown = 0;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var ema = new ExponentialMovingAverage { Length = EmaLength };
var rsi = new RelativeStrengthIndex { Length = RsiPeriod };
_rsiVal = 0;
_prevRsi = 0;
_cooldown = 0;
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(rsi, (candle, r) =>
{
_prevRsi = _rsiVal;
_rsiVal = r;
})
.Bind(ema, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, ema);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal emaVal)
{
if (candle.State != CandleStates.Finished)
return;
if (_cooldown > 0)
{
_cooldown--;
return;
}
if (_rsiVal == 0 || _prevRsi == 0)
return;
var isUpTrend = candle.ClosePrice > emaVal;
var isDownTrend = candle.ClosePrice < emaVal;
var buySignal = isUpTrend && _prevRsi <= 50m && _rsiVal > 50m;
var sellSignal = isDownTrend && _prevRsi >= 50m && _rsiVal < 50m;
if (buySignal && Position <= 0)
{
BuyMarket();
_cooldown = 100;
}
else if (sellSignal && Position >= 0)
{
SellMarket();
_cooldown = 100;
}
}
}
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 vinicius_setup_atr_strategy(Strategy):
"""EMA trend direction with RSI momentum crossing 50: buy in uptrend, sell in downtrend."""
def __init__(self):
super(vinicius_setup_atr_strategy, self).__init__()
self._ema_length = self.Param("EmaLength", 50).SetGreaterThanZero().SetDisplay("EMA Length", "EMA trend filter length", "General")
self._rsi_period = self.Param("RsiPeriod", 14).SetDisplay("RSI Period", "RSI length", "General")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))).SetDisplay("Candle Type", "Timeframe", "General")
@property
def CandleType(self): return self._candle_type.Value
@CandleType.setter
def CandleType(self, value): self._candle_type.Value = value
def OnReseted(self):
super(vinicius_setup_atr_strategy, self).OnReseted()
self._rsi_val = 0
self._prev_rsi = 0
self._cooldown = 0
def OnStarted2(self, time):
super(vinicius_setup_atr_strategy, self).OnStarted2(time)
self._rsi_val = 0
self._prev_rsi = 0
self._cooldown = 0
ema = ExponentialMovingAverage()
ema.Length = self._ema_length.Value
rsi = RelativeStrengthIndex()
rsi.Length = self._rsi_period.Value
sub = self.SubscribeCandles(self.CandleType)
sub \
.Bind(rsi, self._on_rsi) \
.Bind(ema, self.OnProcess) \
.Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, sub)
self.DrawIndicator(area, ema)
self.DrawOwnTrades(area)
def _on_rsi(self, candle, r):
self._prev_rsi = self._rsi_val
self._rsi_val = float(r)
def OnProcess(self, candle, ema_val):
if candle.State != CandleStates.Finished:
return
if self._cooldown > 0:
self._cooldown -= 1
return
if self._rsi_val == 0 or self._prev_rsi == 0:
return
ev = float(ema_val)
close = float(candle.ClosePrice)
is_up = close > ev
is_down = close < ev
buy_signal = is_up and self._prev_rsi <= 50 and self._rsi_val > 50
sell_signal = is_down and self._prev_rsi >= 50 and self._rsi_val < 50
if buy_signal and self.Position <= 0:
self.BuyMarket()
self._cooldown = 100
elif sell_signal and self.Position >= 0:
self.SellMarket()
self._cooldown = 100
def CreateClone(self):
return vinicius_setup_atr_strategy()