Ver no GitHub

Estratégia MACross

A estratégia replica o comportamento do consultor especialista MQL/34176/MACross.mq4 original usando o StockSharp API de alto nível. Ele negocia um único instrumento em um cruzamento de média móvel e mantém todos os controles de risco expressos em pips e patrimônio líquido.

Lógica de negociação

  1. Duas médias móveis simples (SMA) são construídas com base no tipo de vela configurado:
    • FastPeriod reage rapidamente às mudanças de preço.
    • SlowPeriod suaviza a tendência de longo prazo.
  2. No fechamento de cada vela finalizada, as médias rápida e lenta são comparadas:
    • Um cruzamento de alta (cruzamento rápido acima do lento) abre uma posição longa. Qualquer venda ativa é achatada primeiro.
    • Um cruzamento de baixa (cruzamento rápido abaixo do lento) abre uma posição curta após fechar uma posição longa existente.
  3. Cada entrada utiliza um volume de mercado fixo derivado de LotSize e alinhado com os limites do instrumento (VolumeStep, MinVolume, MaxVolume).
  4. Depois que a posição é aberta, a estratégia rastreia duas metas de risco medidas em pips. O tamanho do pip é inferido automaticamente de Security.Decimals (ou PriceStep como substituto):
    • TakeProfitPips define a distância até a meta de lucro. Acertá-lo provoca uma saída do mercado na direção atual.
    • StopLossPips define a distância de parada protetora. Quebrá-lo fecha a posição imediatamente.
  5. A negociação pode ser pausada pelo guarda MinEquity. Quando o valor atual da carteira está abaixo do limite a estratégia continua gerenciando a posição ativa mas não permite novas entradas.

Todos os cálculos funcionam apenas em velas finalizadas, correspondendo totalmente ao consultor especialista original que esperou por uma nova barra antes de avaliar as médias móveis.

Visualização

Quando um painel de gráfico está disponível, a estratégia traça:

  • Insira velas da série assinada.
  • Os SMAs rápidos e lentos.
  • Negociações próprias para destacar entradas e saídas acionadas pelas regras de cruzamento.

Parâmetros

Nome Tipo Padrão Descrição
FastPeriod int 8 Comprimento do SMA rápido que gera sinais de cruzamento.
SlowPeriod int 20 Comprimento da lenta SMA usada como linha de tendência de referência.
TakeProfitPips decimal 20 Distância alvo de lucro expressa em pips. O tamanho do pip é inferido a partir dos decimais do instrumento.
StopLossPips decimal 20 Distância de parada protetora em pips. Usa o mesmo cálculo do tamanho do pip que a meta de lucro.
LotSize decimal 1 Volume básico do pedido. A estratégia arredonda para o tamanho permitido mais próximo antes de enviar ordens de mercado.
MinEquity decimal 100 Patrimônio mínimo da conta. Novas negociações são bloqueadas enquanto o valor da carteira estiver abaixo deste nível.
CandleType DataType TimeSpan.FromMinutes(1).TimeFrame() Série de velas usada para cálculos SMA e avaliação de sinal.

Diferenças vs. versão MQL

  • O especialista original MQL passou os preços de stop loss e take-profit para OrderSend como zero. A porta StockSharp emula o mesmo comportamento com saídas manuais que monitoram o preço de fechamento de cada vela finalizada.
  • A validação de patrimônio (cekMinEquity) agora lê Portfolio.CurrentValue e Portfolio.BeginValue em vez de AccountEquity(), mas preserva a lógica de limite.
  • A detecção do tamanho do pip espelha o auxiliar GetPipPoint: cotações de 2 ou 3 dígitos usam 0,01, cotações de 4 ou 5 dígitos usam 0,0001, caso contrário, PriceStep é usado.

A estratégia resultante pode ser otimizada por meio de todos os parâmetros expostos e combina perfeitamente com StockSharp gráficos e infraestrutura de gerenciamento de risco.

namespace StockSharp.Samples.Strategies;

using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;

/// <summary>
/// MA Cross strategy: SMA crossover.
/// Buys when fast SMA crosses above slow SMA, sells on cross below.
/// </summary>
public class MacrossStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _fastPeriod;
	private readonly StrategyParam<int> _slowPeriod;

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

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

	public MacrossStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(60).TimeFrame())
			.SetDisplay("Candle Type", "Candle timeframe", "General");
		_fastPeriod = Param(nameof(FastPeriod), 10)
			.SetGreaterThanZero()
			.SetDisplay("Fast SMA", "Fast SMA period", "Indicators");
		_slowPeriod = Param(nameof(SlowPeriod), 30)
			.SetGreaterThanZero()
			.SetDisplay("Slow SMA", "Slow SMA period", "Indicators");
	}

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

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_prevFast = 0;
		_prevSlow = 0;
		_hasPrev = false;
		var fast = new ExponentialMovingAverage { Length = FastPeriod };
		var slow = new ExponentialMovingAverage { Length = SlowPeriod };
		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(fast, slow, ProcessCandle).Start();
	}

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

		if (_hasPrev)
		{
			if (_prevFast <= _prevSlow && fastValue > slowValue && Position <= 0)
				BuyMarket();
			else if (_prevFast >= _prevSlow && fastValue < slowValue && Position >= 0)
				SellMarket();
		}
		else
		{
			if (fastValue > slowValue && Position <= 0)
				BuyMarket();
			else if (fastValue < slowValue && Position >= 0)
				SellMarket();
		}

		_prevFast = fastValue;
		_prevSlow = slowValue;
		_hasPrev = true;
	}
}