Ver no GitHub

5/8 EMA Estratégia de proteção cruzada

Visão geral

A 5/8 EMA estratégia de proteção cruzada replica o MetaTrader consultor especialista 5_8macrossv2.mq4 comparando duas médias móveis configuráveis no mesmo símbolo. Um cruzamento de alta da média móvel rápida acima da lenta abre posições longas, enquanto um cruzamento de baixa abre posições curtas. A versão portada segue StockSharp padrões de alto nível e adiciona gerenciamento opcional de take-profit, stop-loss e trailing-stop.

Lógica de negociação

  • Duas médias móveis são calculadas na assinatura da vela selecionada. Por padrão, uma MM exponencial de 5 períodos sobre preços de fechamento é comparada a uma MM exponencial de 8 períodos sobre preços de abertura.
  • Quando a MM rápida cruza acima da MM lenta na última vela finalizada, a estratégia abre ou reverte para uma posição longa. Se uma posição curta estiver ativa, seu volume será incluído na nova ordem de compra de mercado para mudar de direção.
  • Quando a MM rápida cruza abaixo da MM lenta, a estratégia abre ou reverte para uma posição curta usando a mesma lógica de normalização de volume.
  • Os parâmetros de deslocamento MA emulam o deslocamento horizontal original. Valores positivos atrasam o sinal por esse número de velas fechadas; valores negativos são arredondados para zero porque os valores deslocados para frente não estão disponíveis em dados em tempo real.

Gestão de risco

  • As distâncias de Take-profit e stop-loss são expressas em pips (etapas de preço). Quando uma posição longa é aberta, os níveis de proteção são colocados acima e abaixo do preço de entrada, respectivamente; os espelhos lógicos para shorts.
  • Trailing stop (também em pips) estreita constantemente o nível de proteção à medida que o preço se move a favor da posição. Para posições compradas, o trailing stop apenas se move para cima; para shorts, ele apenas se move para baixo.
  • Se qualquer condição de proteção for atendida em uma vela finalizada (take-profit de altos acertos, stop-loss de acertos baixos ou nível de trailing), a estratégia sai da posição com uma ordem de mercado e redefine seu estado interno.

Parâmetros

Nome Tipo Padrão Descrição
TradeVolume decimal 0.1 Volume de pedidos para novas entradas. A estratégia adiciona o tamanho absoluto da posição ao reverter.
TakeProfitPips decimal 40 Distância da entrada em pips para fechamento da posição com lucro. Defina como 0 para desativar.
StopLossPips decimal 0 Distância da entrada em pips para stop loss de proteção. Defina como 0 para desativar.
TrailingStopPips decimal 0 Distância do trailing-stop em pips. Defina como 0 para desativar.
FastPeriod int 5 Período da média móvel rápida.
FastShift int -1 Mudança horizontal para o MA rápido. Valores negativos são tratados como zero nesta porta.
FastMethod MovingAverageMethod Exponential Algoritmo de suavização para MA rápido (Simple, Exponencial, Smoothed, LinearWeighted).
FastPrice AppliedPrice Close Preço da vela usado para o MA rápido.
SlowPeriod int 8 Período da média móvel lenta.
SlowShift int 0 Deslocamento horizontal para o MA lento.
SlowMethod MovingAverageMethod Exponential Algoritmo de suavização para MA lento.
SlowPrice AppliedPrice Open Preço da vela usado para o MA lento.
CandleType DataType TimeSpan.FromMinutes(30).TimeFrame() Série de velas usadas para cálculos.

Notas

  • A conversão mantém a lógica focada nas velas finalizadas para evitar sinais prematuros.
  • Trailing stops e metas de lucro são calculadas com Security.PriceStep; se um símbolo não o definir, os parâmetros de risco permanecem inativos.
  • A versão Python é omitida intencionalmente de acordo com os requisitos da tarefa.
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>
/// 5/8 MA Cross Protect strategy - EMA(5) and EMA(8) crossover.
/// Buys when EMA(5) crosses above EMA(8).
/// Sells when EMA(5) crosses below EMA(8).
/// </summary>
public class FiveEightMaCrossProtectStrategy : 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 FiveEightMaCrossProtectStrategy()
	{
		_fastPeriod = Param(nameof(FastPeriod), 5)
			.SetDisplay("Fast EMA", "Fast EMA period", "Indicators");

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

		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).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 subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(fast, slow, ProcessCandle)
			.Start();
	}

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

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

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

		_prevFast = fast;
		_prevSlow = slow;
	}
}