Esta estrategia opera basándose en el indicador ColorMETRO, que construye líneas escalonadas rápidas y lentas alrededor del RSI.
Se abre una posición larga cuando la línea rápida cruza por encima de la línea lenta. Se abre una posición corta cuando la línea rápida cruza por debajo de la línea lenta. Las posiciones opuestas se cierran con las mismas señales.
Parámetros
Candle Type – tipo de vela utilizado para los cálculos.
RSI Period – período para el cálculo del RSI.
Fast Step – tamaño del paso para la línea rápida.
Slow Step – tamaño del paso para la línea lenta.
Stop Loss – distancia en puntos para la protección de stop-loss.
Take Profit – distancia en puntos para la protección de take-profit.
Allow Buy – permiso para abrir posiciones largas.
Allow Sell – permiso para abrir posiciones cortas.
Close Long – permiso para cerrar posiciones largas.
Close Short – permiso para cerrar posiciones cortas.
La estrategia usa StartProtection para gestionar los niveles de stop-loss y take-profit.
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>
/// ColorMETRO strategy using RSI crossover with 50 level.
/// Buys when RSI crosses above 50, sells when below 50.
/// </summary>
public class ColorMetroStrategy : Strategy
{
private readonly StrategyParam<int> _rsiPeriod;
private readonly StrategyParam<DataType> _candleType;
private decimal? _prevRsi;
public int RsiPeriod { get => _rsiPeriod.Value; set => _rsiPeriod.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public ColorMetroStrategy()
{
_rsiPeriod = Param(nameof(RsiPeriod), 14)
.SetGreaterThanZero()
.SetDisplay("RSI Period", "RSI calculation period", "Indicator");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Type of candles", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevRsi = null;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var rsi = new RelativeStrengthIndex { Length = RsiPeriod };
SubscribeCandles(CandleType)
.Bind(rsi, ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle, decimal rsiValue)
{
if (candle.State != CandleStates.Finished)
return;
if (_prevRsi is null)
{
_prevRsi = rsiValue;
return;
}
var crossUp = _prevRsi < 50m && rsiValue > 50m;
var crossDown = _prevRsi > 50m && rsiValue < 50m;
if (crossUp && Position <= 0)
{
if (Position < 0) BuyMarket();
BuyMarket();
}
else if (crossDown && Position >= 0)
{
if (Position > 0) SellMarket();
SellMarket();
}
_prevRsi = 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, Math
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import RelativeStrengthIndex
from StockSharp.Algo.Strategies import Strategy
class color_metro_strategy(Strategy):
def __init__(self):
super(color_metro_strategy, self).__init__()
self._rsi_period = self.Param("RsiPeriod", 14) \
.SetDisplay("RSI Period", "RSI calculation period", "Indicator")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Type of candles", "General")
self._prev_rsi = None
@property
def RsiPeriod(self):
return self._rsi_period.Value
@RsiPeriod.setter
def RsiPeriod(self, value):
self._rsi_period.Value = value
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
def OnStarted2(self, time):
super(color_metro_strategy, self).OnStarted2(time)
rsi = RelativeStrengthIndex()
rsi.Length = self.RsiPeriod
self.SubscribeCandles(self.CandleType) \
.Bind(rsi, self.ProcessCandle) \
.Start()
def ProcessCandle(self, candle, rsi_value):
if candle.State != CandleStates.Finished:
return
rsi_val = float(rsi_value)
if self._prev_rsi is None:
self._prev_rsi = rsi_val
return
cross_up = self._prev_rsi < 50.0 and rsi_val > 50.0
cross_down = self._prev_rsi > 50.0 and rsi_val < 50.0
if cross_up and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
elif cross_down and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._prev_rsi = rsi_val
def OnReseted(self):
super(color_metro_strategy, self).OnReseted()
self._prev_rsi = None
def CreateClone(self):
return color_metro_strategy()