Ver no GitHub

Estratégia MultiTimeframeEmaAlignmentStrategy

Visão geral

O MultiTimeframeEmaAlignmentStrategy é uma porta StockSharp do MetaTrader 4 consultor especialista 1h-4h-1d.mq4 da pasta MQL/7713. O robô original alinha médias móveis exponenciais rápidas e lentas em três períodos de tempo e aplica gerenciamento de dinheiro protetor por meio de níveis de stop loss fixo, takeprofit e trailing stop. Esta versão C# segue a mesma ideia de alto nível enquanto aproveita as ligações de indicadores e auxiliares de pedidos de alto nível de StockSharp.

Lógica de negociação

  • A estratégia subscreve três séries de velas simultaneamente: M1 (timeframe do sinal), M5 (filtro de médio prazo) e M30 (confirmação de tendência de timeframe superior).
  • Cada série alimenta um par de médias móveis exponenciais (EMA) com comprimentos configuráveis (padrão 8 e 64).
  • Uma configuração otimista exige que o EMA rápido fique acima do EMA lento em todos os três períodos de tempo. Além disso, o EMA rápida não deve perder impulso (valor atual maior ou igual ao valor anterior e também acima do valor ShiftDepth barras atrás).
  • Uma configuração de baixa exige que o EMA rápido permaneça abaixo do EMA lento em todos os três períodos de tempo, com o EMA rápido diminuindo em momentum.
  • As ordens são acionadas no fechamento da vela M1 quando as verificações de alinhamento e impulso são satisfeitas. Sinais longos são permitidos somente quando nenhuma posição longa está aberta (ou uma posição curta existente é fechada primeiro) e vice-versa.

Esta interpretação recria a intenção das condições MT4 com o API de alto nível de StockSharp. As comparações de MQL "MA shift" são emuladas por meio do buffer ShiftDepth que rastreia os valores de EMA algumas velas atrás e garante que o impulso seja consistente com a direção de entrada.

Gestão de risco

  • O tamanho da posição é controlado pelo parâmetro TradeVolume (padrão 3 lotes como o EA original).
  • As distâncias opcionais de stop loss e takeprofit são fornecidas em pips. Eles são convertidos em preços por meio do PriceStep do instrumento (volta para 0.0001 quando ausente).
  • O trailing stop replica o comportamento do EA, movendo o preço stop para mais perto do mercado sempre que a negociação avança o suficiente.
  • Os parâmetros de risco podem ser alternados de forma independente, correspondendo aos sinalizadores StopLossMode, TakeProfitMode e TrailingStopMode do script MQL.

Parâmetros

Parâmetro Descrição Padrão
TradeVolume Volume do pedido usado por BuyMarket / SellMarket. Espelha a entrada Lots. 3
FastLength EMA período para a linha rápida. 8
SlowLength EMA período para a linha lenta. 64
ShiftDepth Número de velas históricas usadas para emular as comparações de deslocamento da média móvel MQL. 3
UseStopLoss Ativa stop loss fixo. true
StopLossPips Distância de stop loss expressa em pips. 75
UseTakeProfit Permite obter lucro. true
TakeProfitPips Distância Take Profit expressa em pips. 150
UseTrailingStop Permite o gerenciamento de trailing stop. true
TrailingStopPips Distância final em pips. 30
M1CandleType Tipo de vela para o período do sinal (padrão 1 minuto). 1m
M5CandleType Tipo de vela para o filtro de médio prazo (padrão 5 minutos). 5m
M30CandleType Tipo de vela para o período de tempo superior (padrão 30 minutos). 30m

Notas de uso

  1. Anexe a estratégia a um instrumento e garanta que os dados históricos estejam disponíveis para todos os três períodos para permitir que os buffers EMA sejam preenchidos.
  2. O parâmetro ShiftDepth deve permanecer pelo menos 2 para que a estratégia possa validar o impulso de curto prazo.
  3. Quando UseTrailingStop está ativo sem UseStopLoss, a lógica final ainda inicializa um valor de parada quando a negociação se move a favor.
  4. Como StockSharp é executado no fechamento da vela, os resultados podem diferir ligeiramente da execução tick a tick da versão MT4, especialmente em mercados voláteis. O comportamento central de alinhamento de tendências permanece intacto.

Notas de conversão

  • Os cálculos dos indicadores dependem exclusivamente do mecanismo Bind de StockSharp; nenhuma coleta manual de histórico de indicadores é usada.
  • O gerenciamento de pedidos é implementado com ajudantes de alto nível (BuyMarket, SellMarket) e rastreamento interno de preços em vez de chamadas diretas OrderSend.
  • Notificações por email e controles de deslizamento do script MQL são omitidos porque estão fora do escopo de StockSharp.

Arquivos

  • CS/MultiTimeframeEmaAlignmentStrategy.cs – principal implementação da estratégia C#.
  • README_ru.md – Documentação russa.
  • README_zh.md – documentação chinesa.
using System;
using System.Collections.Generic;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// Multi-Timeframe EMA Alignment strategy - fast/slow EMA crossover with trend EMA filter.
/// Buys when fast EMA crosses above slow EMA while close is above trend EMA.
/// Sells when fast EMA crosses below slow EMA while close is below trend EMA.
/// </summary>
public class MultiTimeframeEmaAlignmentStrategy : Strategy
{
	private readonly StrategyParam<int> _fastPeriod;
	private readonly StrategyParam<int> _slowPeriod;
	private readonly StrategyParam<int> _trendPeriod;
	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 int TrendPeriod { get => _trendPeriod.Value; set => _trendPeriod.Value = value; }
	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }

	public MultiTimeframeEmaAlignmentStrategy()
	{
		_fastPeriod = Param(nameof(FastPeriod), 10)
			.SetDisplay("Fast EMA", "Fast EMA period", "Indicators");

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

		_trendPeriod = Param(nameof(TrendPeriod), 100)
			.SetDisplay("Trend EMA", "Trend EMA period", "Indicators");

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

	public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities() => [(Security, CandleType)];
	protected override void OnReseted() { base.OnReseted(); _prevFast = 0m; _prevSlow = 0m; _hasPrev = false; }

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

		_hasPrev = false;

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

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

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

		var close = candle.ClosePrice;

		if (!_hasPrev)
		{
			_prevFast = fast;
			_prevSlow = slow;
			_hasPrev = true;
			return;
		}

		if (_prevFast <= _prevSlow && fast > slow && close > trend && Position <= 0)
		{
			if (Position < 0)
				BuyMarket();
			BuyMarket();
		}
		else if (_prevFast >= _prevSlow && fast < slow && close < trend && Position >= 0)
		{
			if (Position > 0)
				SellMarket();
			SellMarket();
		}

		_prevFast = fast;
		_prevSlow = slow;
	}
}