Ver en GitHub

Estrategia ColorMETRO

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;
	}
}