Ver en GitHub

Estrategia Magna Rapax Copper

Esta estrategia replica el sistema de medias móviles "arcoíris" del experto MQL original. Utiliza once medias móviles exponenciales junto con filtros MACD y ADX.

Cómo funciona

  • Calcular EMA(2), EMA(3), EMA(5), EMA(8), EMA(13), EMA(21), EMA(34), EMA(55), EMA(89), EMA(144) y EMA(233) sobre precios de cierre.
  • Calcular MACD (Rápido, Lento, Señal) y usar la línea de señal.
  • Calcular ADX para medir la fuerza de la tendencia.
  • Comprar cuando:
    • La línea de señal MACD está por encima de cero.
    • Todas las EMA están estrictamente ascendentes (cada EMA más rápida por encima de la más lenta).
    • El valor ADX está por encima del umbral.
  • Vender cuando:
    • La línea de señal MACD está por debajo de cero.
    • Todas las EMA están estrictamente descendentes.
    • El valor ADX está por encima del umbral.

Las posiciones se invierten cuando aparece una señal opuesta.

Parámetros

Nombre Descripción
FastMacd Período de EMA rápida para MACD.
SlowMacd Período de EMA lenta para MACD.
SignalPeriod Período de la línea de señal para MACD.
AdxPeriod Período para el indicador ADX.
AdxThreshold Valor mínimo de ADX requerido para operar.
CandleType Marco temporal de velas utilizado para los cálculos.

Notas

  • La estrategia usa órdenes de mercado mediante BuyMarket y SellMarket.
  • Solo se mantiene una posición a la vez; una señal opuesta invierte la posición.
  • Esta es una conversión directa de la estrategia MQL original sin la lógica opcional de martingala.
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>
/// EMA rainbow trend following strategy.
/// </summary>
public class MagnaRapaxCopperStrategy : Strategy
{
	private readonly StrategyParam<int> _fastPeriod;
	private readonly StrategyParam<int> _slowPeriod;
	private readonly StrategyParam<DataType> _candleType;

	private decimal _prevFast;
	private decimal _prevSlow;
	private bool _hasPrev;

	public int FastPeriod { get => _fastPeriod.Value; set => _fastPeriod.Value = value; }
	public int SlowPeriod { get => _slowPeriod.Value; set => _slowPeriod.Value = value; }
	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }

	public MagnaRapaxCopperStrategy()
	{
		_fastPeriod = Param(nameof(FastPeriod), 13)
			.SetGreaterThanZero()
			.SetDisplay("Fast Period", "Fast EMA period", "Indicators");

		_slowPeriod = Param(nameof(SlowPeriod), 34)
			.SetGreaterThanZero()
			.SetDisplay("Slow Period", "Slow EMA period", "Indicators");

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

	public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
		=> [(Security, CandleType)];

	protected override void OnReseted()
	{
		base.OnReseted();
		_prevFast = 0;
		_prevSlow = 0;
		_hasPrev = false;
	}

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);

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

		SubscribeCandles(CandleType)
			.Bind(fast, slow, ProcessCandle)
			.Start();
	}

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

		if (!_hasPrev)
		{
			_prevFast = fastVal;
			_prevSlow = slowVal;
			_hasPrev = true;
			return;
		}

		var crossUp = _prevFast <= _prevSlow && fastVal > slowVal;
		var crossDown = _prevFast >= _prevSlow && fastVal < slowVal;

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

		_prevFast = fastVal;
		_prevSlow = slowVal;
	}
}