Ver en GitHub

ColorMETRO XRSX Strategy

This strategy is a StockSharp implementation inspired by the original MQL5 Expert Advisor "Exp_ColorMETRO_XRSX". It uses two smoothed moving averages to detect trend changes. A long position is opened when the fast average crosses above the slow average, while a short position is opened when the fast average crosses below the slow average.

Parameters

  • Fast Period – period of the fast moving average.
  • Slow Period – period of the slow moving average.
  • Candle Type – time frame of candles used for calculations.

How It Works

  1. The strategy subscribes to the selected candle series.
  2. Two Sma indicators with different periods are calculated on the close price.
  3. When the fast SMA crosses above the slow SMA, any short position is closed and a long position is opened.
  4. When the fast SMA crosses below the slow SMA, any long position is closed and a short position is opened.
  5. The previous values of the averages are stored to detect crossings only once.

Notes

  • The strategy uses the high level API with Bind for indicator processing.
  • StartProtection is enabled to manage protective mechanisms.
  • This implementation is a simplified translation and does not use the original custom indicator.
using System;
using System.Linq;
using System.Collections.Generic;

using Ecng.Common;
using Ecng.Collections;
using Ecng.Serialization;

using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;

namespace StockSharp.Samples.Strategies;

/// <summary>
/// Strategy based on the cross of two smoothed lines inspired by the ColorMETRO XRSX indicator.
/// Opens a long position when the fast line crosses above the slow line and
/// opens a short position when the fast line crosses below the slow line.
/// </summary>
public class ColorMetroXrsxStrategy : Strategy
{
	private readonly StrategyParam<int> _fastPeriod;
	private readonly StrategyParam<int> _slowPeriod;
	private readonly StrategyParam<DataType> _candleType;

	private decimal? _prevFast;
	private decimal? _prevSlow;

	/// <summary>
	/// Fast moving average period.
	/// </summary>
	public int FastPeriod
	{
		get => _fastPeriod.Value;
		set => _fastPeriod.Value = value;
	}

	/// <summary>
	/// Slow moving average period.
	/// </summary>
	public int SlowPeriod
	{
		get => _slowPeriod.Value;
		set => _slowPeriod.Value = value;
	}

	/// <summary>
	/// Candle type.
	/// </summary>
	public DataType CandleType
	{
		get => _candleType.Value;
		set => _candleType.Value = value;
	}

	/// <summary>
	/// Initializes a new instance of the <see cref="ColorMetroXrsxStrategy"/> class.
	/// </summary>
	public ColorMetroXrsxStrategy()
	{
		_fastPeriod = Param(nameof(FastPeriod), 10)
			.SetGreaterThanZero()
			.SetDisplay("Fast Period", "Fast moving average length", "Parameters")
			;

		_slowPeriod = Param(nameof(SlowPeriod), 30)
			.SetGreaterThanZero()
			.SetDisplay("Slow Period", "Slow moving average length", "Parameters")
			;

		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
			.SetDisplay("Candle Type", "Type of candles to process", "General");
	}

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

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

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

		var fast = new ExponentialMovingAverage { Length = FastPeriod };
		var slow = new ExponentialMovingAverage { Length = SlowPeriod };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(fast, slow, ProcessCandle)
			.Start();

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

	}

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

		if (!IsFormedAndOnlineAndAllowTrading())
			return;

		if (_prevFast is decimal prevFast && _prevSlow is decimal prevSlow)
		{
			if (prevFast <= prevSlow && fast > slow && Position <= 0)
				BuyMarket();

			if (prevFast >= prevSlow && fast < slow && Position >= 0)
				SellMarket();
		}

		_prevFast = fast;
		_prevSlow = slow;
	}
}