Ver no GitHub

Estratégia Magna Rapax Copper

Esta estratégia replica o sistema de médias móveis "arco-íris" do especialista MQL original. Utiliza onze médias móveis exponenciais juntamente com filtros MACD e ADX.

Como funciona

  • Calcular EMA(2), EMA(3), EMA(5), EMA(8), EMA(13), EMA(21), EMA(34), EMA(55), EMA(89), EMA(144) e EMA(233) sobre preços de fechamento.
  • Calcular MACD (Rápido, Lento, Sinal) e usar a linha de sinal.
  • Calcular ADX para medir a força da tendência.
  • Comprar quando:
    • A linha de sinal MACD está acima de zero.
    • Todas as EMAs estão estritamente ascendentes (cada EMA mais rápida acima da mais lenta).
    • O valor ADX está acima do limiar.
  • Vender quando:
    • A linha de sinal MACD está abaixo de zero.
    • Todas as EMAs estão estritamente descendentes.
    • O valor ADX está acima do limiar.

As posições são invertidas quando um sinal oposto aparece.

Parâmetros

Nome Descrição
FastMacd Período de EMA rápida para MACD.
SlowMacd Período de EMA lenta para MACD.
SignalPeriod Período da linha de sinal para MACD.
AdxPeriod Período para o indicador ADX.
AdxThreshold Valor mínimo de ADX necessário para operar.
CandleType Período de velas utilizado nos cálculos.

Observações

  • A estratégia usa ordens de mercado via BuyMarket e SellMarket.
  • Apenas uma posição é mantida por vez; um sinal oposto inverte a posição.
  • Esta é uma conversão direta da estratégia MQL original sem a lógica opcional de martingale.
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;
	}
}