Ver no GitHub

Estratégia Elite eFibo Trader v2.1

Visão geral

Elite eFibo Trader v2.1 recria o consultor especialista MetaTrader que empilha pedidos do tamanho de Fibonacci em uma direção enquanto compartilha um stop de proteção comum. A porta StockSharp mantém o comportamento original: uma única ordem de mercado lança uma sequência de ordens stop espaçadas por LevelDistancePips, e cada nível preenchido aumenta a exposição de acordo com a progressão Fibonacci. A estratégia fecha imediatamente toda a cesta assim que o stop compartilhado é tocado ou quando o lucro flutuante atinge MoneyTakeProfit.

O algoritmo é intencionalmente direcional. Defina OpenBuy como true (e OpenSell como false) para negociar retrocessos de alta ou gire os interruptores para executar a variante de baixa. Apenas uma escada está ativa por vez, espelhando a lógica de ciclo único do script MQL4.

Requisitos de dados

  • Assina o fluxo de negociação para recuperar o preço de execução mais recente usado para colocação em escada, lógica de rastreamento e avaliação de lucro de dinheiro.
  • Baseia-se nos metadados de segurança (PriceStep, StepPrice, VolumeStep) para traduzir entradas de pip no estilo MetaTrader em preços de câmbio e tamanhos de lote.

Construção de escada

  1. Quando não há exposição e a negociação é permitida, a estratégia verifica as mudanças de direção. Exatamente um entre OpenBuy ou OpenSell deve ser verdadeiro; caso contrário, nenhuma escada será iniciada.
  2. O primeiro nível Fibonacci é aberto no mercado. Os níveis subsequentes são programados como ordens stop compensadas em LevelDistancePips * pipSize do preço de referência registrado quando a escada começa.
  3. Os volumes vêm dos parâmetros Level1VolumeLevel14Volume e são normalizados para a segurança VolumeStep.
  4. Todos os níveis herdam o mesmo deslocamento de parada: StopLossPips * pipSize. O preço stop é calculado por preenchimento e posteriormente reduzido para que cada ordem ativa compartilhe o nível de proteção mais próximo.

Parar o gerenciamento

  • Cada ordem preenchida armazena seu preço de entrada e seu stop inicial derivado do deslocamento do pip.
  • Em cada tick de negociação, a estratégia reavalia todas as paradas abertas e as alinha com o valor mais apertado em toda a escada (parada mais alta para posições compradas, parada mais baixa para posições vendidas) para imitar as repetidas chamadas OrderModify de MetaTrader.
  • Quando o último preço de negociação cruza qualquer stop partilhado, a estratégia cancela as restantes ordens pendentes e fecha todo o cabaz com ordens de mercado.

Gestão de dinheiro

  • O lucro não realizado é calculado a partir dos instrumentos PriceStep e StepPrice para que a meta de caixa espelhe as leituras de OrderProfit() de MetaTrader.
  • Se o lucro flutuante atingir ou exceder MoneyTakeProfit, todas as posições serão fechadas e as ordens pendentes serão canceladas imediatamente.
  • Quando TradeAgainAfterProfit é false, a estratégia permanece ociosa após atingir a meta de dinheiro até que seja reiniciada manualmente.

Parâmetros

Nome Descrição
OpenBuy Permitir que a estratégia construa uma escada de alta (deve ser exclusiva com OpenSell).
OpenSell Permitir que a estratégia construa uma escada de baixa (deve ser exclusiva com OpenBuy).
TradeAgainAfterProfit Retomar a negociação após o fechamento da cesta com o lucro líquido.
LevelDistancePips Distância em MetaTrader pips entre ordens de stop consecutivas.
StopLossPips Distância em MetaTrader pips usada para derivar a parada de proteção para cada nível preenchido.
MoneyTakeProfit Meta de lucro em dinheiro que fecha toda a cesta.
Level1VolumeLevel14Volume Volumes usados para cada nível Fibonacci; definido como zero para pular um nível.

Notas de implementação

  • A conversão do pip segue a convenção MetaTrader: se o símbolo tiver 3 ou 5 casas decimais, o pip efetivo é igual a PriceStep * 10.
  • StartProtection() é chamado uma vez durante a inicialização para ativar as verificações de segurança StockSharp integradas.
  • A lógica de parada compartilhada mantém intencionalmente todos os pedidos sincronizados; uma vez que um stop mais apertado aparece, ele é propagado para todos os níveis ativos.
  • Os pedidos pendentes são limpos automaticamente sempre que a escada é plana, replicando as múltiplas chamadas subCloseAllPending() encontradas no código MQL.

Dicas de uso

  • Certifique-se de que PriceStep, StepPrice e VolumeStep estejam configurados no instrumento; caso contrário, as conversões de pip ou as metas monetárias podem ser imprecisas.
  • Os sistemas de média podem acumular grandes exposições rapidamente. Verifique os limites de volume e os requisitos de margem antes de executar a estratégia ao vivo.
  • Desative TradeAgainAfterProfit para reproduzir o comportamento único em que EA para de negociar após fechar uma cesta lucrativa.
using System;

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

namespace StockSharp.Samples.Strategies;

public class EliteEfiboTraderV21Strategy : Strategy
{
	private readonly StrategyParam<int> _emaPeriod;
	private readonly StrategyParam<int> _cooldownCandles;
	private readonly StrategyParam<DataType> _candleType;

	private decimal _prevClose;
	private decimal _prevEma;
	private bool _hasPrev;
	private int _cooldownRemaining;

	public int EmaPeriod { get => _emaPeriod.Value; set => _emaPeriod.Value = value; }
	public int CooldownCandles { get => _cooldownCandles.Value; set => _cooldownCandles.Value = value; }
	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }

	public EliteEfiboTraderV21Strategy()
	{
		_emaPeriod = Param(nameof(EmaPeriod), 50).SetDisplay("EMA Period", "EMA lookback", "Indicators");
		_cooldownCandles = Param(nameof(CooldownCandles), 200).SetDisplay("Cooldown", "Candles between signals", "General");
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame()).SetDisplay("Candle Type", "Candle timeframe", "General");
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_prevClose = default;
		_prevEma = default;
		_hasPrev = default;
		_cooldownRemaining = default;
	}

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_prevClose = 0;
		_prevEma = 0;
		_hasPrev = false;
		_cooldownRemaining = 0;

		var ema = new ExponentialMovingAverage { Length = EmaPeriod };
		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(ema, ProcessCandle).Start();
	}

	private void ProcessCandle(ICandleMessage candle, decimal ema)
	{
		if (candle.State != CandleStates.Finished) return;
		var close = candle.ClosePrice;
		if (!_hasPrev) { _prevClose = close; _prevEma = ema; _hasPrev = true; return; }

		if (_cooldownRemaining > 0)
		{
			_cooldownRemaining--;
			_prevClose = close;
			_prevEma = ema;
			return;
		}

		if (_prevClose <= _prevEma && close > ema && Position <= 0)
		{
			if (Position < 0) BuyMarket();
			BuyMarket();
			_cooldownRemaining = CooldownCandles;
		}
		else if (_prevClose >= _prevEma && close < ema && Position >= 0)
		{
			if (Position > 0) SellMarket();
			SellMarket();
			_cooldownRemaining = CooldownCandles;
		}
		_prevClose = close;
		_prevEma = ema;
	}
}