Ver en GitHub

Estrategia Color Zerolag JJRSX

Esta estrategia replica la lógica del experto ColorZerolagJJRSX de MetaTrader. Utiliza dos osciladores RSI suavizados para aproximar el indicador ColorZerolagJJRSX original. El cruce de las líneas rápida y lenta genera señales de trading.

Cómo funciona

  • Cuando el oscilador rápido cruza por debajo del oscilador lento, la estrategia cierra cualquier posición corta y opcionalmente abre una nueva posición larga.
  • Cuando el oscilador rápido cruza por encima del oscilador lento, la estrategia cierra cualquier posición larga y opcionalmente abre una nueva posición corta.
  • Los niveles de stop-loss y take-profit de protección se aplican mediante el mecanismo integrado StartProtection.

Parámetros

Nombre Descripción
FastPeriod Período de la línea JJRSX rápida.
SlowPeriod Período de la línea JJRSX lenta.
BuyOpen Permitir apertura de posiciones largas.
SellOpen Permitir apertura de posiciones cortas.
BuyClose Cerrar posiciones largas existentes ante señal opuesta.
SellClose Cerrar posiciones cortas existentes ante señal opuesta.
StopLoss Nivel de stop-loss en unidades de precio.
TakeProfit Nivel de take-profit en unidades de precio.
CandleType Marco temporal utilizado para los cálculos.

Notas

  • La implementación utiliza indicadores integrados y la API Bind de alto nivel.
  • El volumen se toma de la propiedad Volume de la estrategia.
  • No se proporciona versión en Python para esta estrategia.

Referencias

El código MQL original se encuentra en MQL/13854 dentro de este repositorio.

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>
/// Strategy based on crossing of two RSI lines (fast and slow).
/// </summary>
public class ColorZerolagJjrsxStrategy : Strategy
{
	private readonly StrategyParam<int> _fastPeriod;
	private readonly StrategyParam<int> _slowPeriod;
	private readonly StrategyParam<decimal> _stopLossPct;
	private readonly StrategyParam<decimal> _takeProfitPct;
	private readonly StrategyParam<DataType> _candleType;

	private decimal? _prevFast;
	private decimal? _prevSlow;

	public int FastPeriod { get => _fastPeriod.Value; set => _fastPeriod.Value = value; }
	public int SlowPeriod { get => _slowPeriod.Value; set => _slowPeriod.Value = value; }
	public decimal StopLossPct { get => _stopLossPct.Value; set => _stopLossPct.Value = value; }
	public decimal TakeProfitPct { get => _takeProfitPct.Value; set => _takeProfitPct.Value = value; }
	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }

	public ColorZerolagJjrsxStrategy()
	{
		_fastPeriod = Param(nameof(FastPeriod), 8)
			.SetGreaterThanZero()
			.SetDisplay("Fast Period", "Fast RSI period", "Indicator");

		_slowPeriod = Param(nameof(SlowPeriod), 21)
			.SetGreaterThanZero()
			.SetDisplay("Slow Period", "Slow RSI period", "Indicator");

		_stopLossPct = Param(nameof(StopLossPct), 2m)
			.SetDisplay("Stop Loss %", "Stop loss percentage", "Risk");

		_takeProfitPct = Param(nameof(TakeProfitPct), 3m)
			.SetDisplay("Take Profit %", "Take profit percentage", "Risk");

		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
			.SetDisplay("Candle Type", "Time frame for indicator", "General");
	}

	/// <inheritdoc />
	public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
	{
		return [(Security, CandleType)];
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_prevFast = null;
		_prevSlow = null;
	}

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);

		var fastRsi = new RelativeStrengthIndex { Length = FastPeriod };
		var slowRsi = new RelativeStrengthIndex { Length = SlowPeriod };

		StartProtection(
			takeProfit: new Unit(TakeProfitPct, UnitTypes.Percent),
			stopLoss: new Unit(StopLossPct, UnitTypes.Percent),
			useMarketOrders: true);

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(fastRsi, slowRsi, ProcessCandle)
			.Start();

		var area = CreateChartArea();
		if (area != null)
		{
			DrawCandles(area, subscription);
			DrawIndicator(area, fastRsi);
			DrawIndicator(area, slowRsi);
			DrawOwnTrades(area);
		}
	}

	private void ProcessCandle(ICandleMessage candle, decimal fast, decimal slow)
	{
		if (candle.State != CandleStates.Finished)
			return;

		if (_prevFast is null || _prevSlow is null)
		{
			_prevFast = fast;
			_prevSlow = slow;
			return;
		}

		var crossDown = _prevFast > _prevSlow && fast < slow;
		var crossUp = _prevFast < _prevSlow && fast > slow;

		if (crossDown && Position <= 0)
		{
			if (Position < 0) BuyMarket();
			BuyMarket();
		}
		else if (crossUp && Position >= 0)
		{
			if (Position > 0) SellMarket();
			SellMarket();
		}

		_prevFast = fast;
		_prevSlow = slow;
	}
}