Ver no GitHub

Estratégia EurGbp EA

Visão geral

A estratégia EurGbp EA espelha o expert advisor original do MetaTrader comparando o momentum MACD horário de EUR/USD e GBP/USD enquanto negocia no instrumento primário configurado (normalmente EUR/GBP). A abordagem explora a força relativa entre os principais pares de euro e libra para antecipar movimentos no par cruzado.

Indicadores

  • MACD (12, 26, 9) em EUR/USD (sinal e histograma).
  • MACD (12, 26, 9) em GBP/USD (sinal e histograma).

Ambos os indicadores são avaliados no mesmo timeframe selecionado pelo parâmetro Candle Type (padrão de 1 hora).

Lógica de negociação

  1. Assinar candles do ativo negociado mais EUR/USD e GBP/USD.
  2. Calcular sinal e histograma MACD para ambos os pares de referência.
  3. Condição de compra:
    • Histograma EUR/USD < histograma GBP/USD, e
    • Sinal EUR/USD > sinal GBP/USD,
    • Nenhuma posição comprada existente (ou uma posição vendida existente que será zerada).
  4. Condição de venda:
    • Histograma GBP/USD < histograma EUR/USD, e
    • Sinal GBP/USD > sinal EUR/USD,
    • Nenhuma posição vendida existente (ou uma posição comprada existente que será zerada).
  5. Apenas uma operação por barra em cada direção é permitida para evitar entradas duplicadas.
  6. Ordens de stop-loss e take-profit são anexadas imediatamente após a entrada usando as distâncias em pontos configuradas.

Parâmetros

Nome Descrição Padrão
Candle Type Timeframe para todas as assinaturas de candles. 1 hora
EURUSD Security Instrumento que fornece candles EUR/USD. Deve ser definido
GBPUSD Security Instrumento que fornece candles GBP/USD. Deve ser definido
Volume Volume da ordem (lotes). 0.01
Stop Loss Stop protetor em passos de preço. 75
Take Profit Meta de lucro em passos de preço. 46

Gestão de risco

  • Stop Loss e Take Profit são medidos em passos de preço do ativo negociado. Garanta que o ativo tenha um valor PriceStep válido.
  • A proteção começa automaticamente quando a estratégia inicia (StartProtection).
  • Se qualquer distância for zero, a respectiva ordem protetora é ignorada.

Notas de uso

  • Atribua o ativo principal de negociação à instância da estratégia antes de iniciar (por exemplo, EUR/GBP).
  • Configure EURUSD Security e GBPUSD Security para referenciar fontes de dados disponíveis na sua conexão.
  • A estratégia exige dados sincronizados para os três ativos no timeframe selecionado para gerar sinais com confiabilidade.
  • Apenas ordens a mercado são usadas. Posições opostas existentes são fechadas enviando o volume inverso.

Notas de conversão

  • As entradas originais _Lots, _SL, _TP, _MagicNumber, _Comment, _OnlyOneOpenedPos e _AutoDigits são mapeadas para parâmetros StockSharp ou comportamento integrado.
  • Rotinas auxiliares de fechamento de ordens da versão MQL são substituídas pela gestão de ordens protetoras de alto nível do StockSharp.
  • Tratamento de erros e laços de nova tentativa do código MQL são omitidos porque o modelo de execução StockSharp já gerencia estados de ordens e retentativas.
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;

public class EurGbpEaStrategy : Strategy
{
	private readonly StrategyParam<int> _fastPeriod;
	private readonly StrategyParam<int> _slowPeriod;
	private readonly StrategyParam<int> _stopLossPoints;
	private readonly StrategyParam<int> _takeProfitPoints;

	private ExponentialMovingAverage _fast;
	private ExponentialMovingAverage _slow;

	private decimal _prevFast;
	private decimal _prevSlow;
	private decimal _entryPrice;
	private int _cooldown;

	public int FastPeriod { get => _fastPeriod.Value; set => _fastPeriod.Value = value; }
	public int SlowPeriod { get => _slowPeriod.Value; set => _slowPeriod.Value = value; }
	public int StopLossPoints { get => _stopLossPoints.Value; set => _stopLossPoints.Value = value; }
	public int TakeProfitPoints { get => _takeProfitPoints.Value; set => _takeProfitPoints.Value = value; }

	public EurGbpEaStrategy()
	{
		_fastPeriod = Param(nameof(FastPeriod), 14).SetGreaterThanZero().SetDisplay("Fast Period", "Fast EMA period", "Indicator");
		_slowPeriod = Param(nameof(SlowPeriod), 50).SetGreaterThanZero().SetDisplay("Slow Period", "Slow EMA period", "Indicator");
		_stopLossPoints = Param(nameof(StopLossPoints), 200).SetNotNegative().SetDisplay("Stop Loss", "Stop-loss in price steps", "Risk");
		_takeProfitPoints = Param(nameof(TakeProfitPoints), 400).SetNotNegative().SetDisplay("Take Profit", "Take-profit in price steps", "Risk");
	}

	public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
	{
		yield return (Security, TimeSpan.FromMinutes(5).TimeFrame());
	}

	protected override void OnReseted()
	{
		base.OnReseted();
		_fast = null; _slow = null;
		_prevFast = 0; _prevSlow = 0; _entryPrice = 0; _cooldown = 0;
	}

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_fast = new ExponentialMovingAverage { Length = FastPeriod };
		_slow = new ExponentialMovingAverage { Length = SlowPeriod };
		var subscription = SubscribeCandles(TimeSpan.FromMinutes(5).TimeFrame());
		subscription.Bind(_fast, _slow, ProcessCandle);
		subscription.Start();
	}

	private void ProcessCandle(ICandleMessage candle, decimal fastValue, decimal slowValue)
	{
		if (candle.State != CandleStates.Finished) return;
		if (!_fast.IsFormed || !_slow.IsFormed) { _prevFast = fastValue; _prevSlow = slowValue; return; }
		if (_cooldown > 0) { _cooldown--; _prevFast = fastValue; _prevSlow = slowValue; return; }

		var close = candle.ClosePrice;
		var step = Security?.PriceStep ?? 1m;

		if (Position > 0 && _entryPrice > 0)
		{
			if (StopLossPoints > 0 && close <= _entryPrice - StopLossPoints * step) { SellMarket(); _entryPrice = 0; _cooldown = 100; _prevFast = fastValue; _prevSlow = slowValue; return; }
			if (TakeProfitPoints > 0 && close >= _entryPrice + TakeProfitPoints * step) { SellMarket(); _entryPrice = 0; _cooldown = 100; _prevFast = fastValue; _prevSlow = slowValue; return; }
		}
		else if (Position < 0 && _entryPrice > 0)
		{
			if (StopLossPoints > 0 && close >= _entryPrice + StopLossPoints * step) { BuyMarket(); _entryPrice = 0; _cooldown = 100; _prevFast = fastValue; _prevSlow = slowValue; return; }
			if (TakeProfitPoints > 0 && close <= _entryPrice - TakeProfitPoints * step) { BuyMarket(); _entryPrice = 0; _cooldown = 100; _prevFast = fastValue; _prevSlow = slowValue; return; }
		}

		if (_prevFast <= _prevSlow && fastValue > slowValue && Position <= 0)
		{ if (Position < 0) BuyMarket(); BuyMarket(); _entryPrice = close; _cooldown = 100; }
		else if (_prevFast >= _prevSlow && fastValue < slowValue && Position >= 0)
		{ if (Position > 0) SellMarket(); SellMarket(); _entryPrice = close; _cooldown = 100; }

		_prevFast = fastValue; _prevSlow = slowValue;
	}
}