Ver no GitHub

Fibonacci Estratégia de retração de entradas potenciais

Visão geral

A Fibonacci estratégia de retração de entradas potenciais recria o MetaTrader especialista EA_PUB_FibonacciPotentialEntries. O algoritmo espera por cotações de nível 1 ao vivo e, em seguida, coloca duas ordens pendentes em torno dos níveis de retração Fibonacci fornecidos manualmente. Quando a meta de lucro compartilhado é atingida, a estratégia aumenta 50% de cada posição e move o stop de proteção para o ponto de equilíbrio para a quantidade restante.

Mapeamento da lógica original

  • Ordens de entrada – Duas ordens de limite são emitidas assim que o melhor preço de compra e o melhor preço de venda estiverem disponíveis:
    • Primeira ordem: colocada na retração de 50% (P50Level). O stop-loss está ancorado três spreads abaixo (modo de alta) ou acima (modo de baixa) do nível de 61%.
    • Segunda ordem: colocada na retração de 61% (P61Level) com o stop-loss definido a três spreads do ponto médio entre os níveis de 61% e 100%.
  • Viés de direção – A entrada bType original se torna o parâmetro MarketBias (Bull para limites de compra, Bear para limites de venda).
  • Alocação de risco – A primeira negociação sempre arrisca 0.7% do patrimônio do portfólio. A segunda negociação consome a parcela restante de RiskPercent (max(RiskPercent - 0.7, 0)), mantendo a divisão usada por EA.
  • Cálculo de volume – O risco é traduzido para o tamanho da posição por meio de Portfolio.CurrentValue (com substitutos para CurrentBalance e BeginValue) junto com a etapa de preço, custo da etapa e multiplicador do instrumento.
  • Take-profit parcial – Quando o preço ultrapassa TargetLevel, cada negociação preenchida envia uma ordem de mercado para fechar metade do seu volume aberto. Posteriormente, a ordem stop é movida para o preço de entrada registrado, correspondendo à sequência OrderClose + OrderModify de EA.

Parâmetros

Nome Descrição
P50Level Preço atribuído à retração Fibonacci de 50%.
P61Level Preço atribuído à retração Fibonacci de 61,8%.
P100Level Preço atribuído à retração Fibonacci de 100% (usado para o stop do ponto médio).
TargetLevel Meta de lucro compartilhado para ambas as negociações.
RiskPercent Orçamento total de risco em percentagem do capital próprio (deve ser ≥ 0,7).
MarketBias Escolhe campanha longa (Bull) ou curta (Bear).

Detalhes de execução

  1. Assine cotações de nível 1 via SubscribeLevel1() e aguarde valores de compra/venda positivos.
  2. Calcule spread, níveis de stop e tamanhos de posição. Os pedidos são enviados uma vez por execução e não serão recriados automaticamente posteriormente (mesmo comportamento do especialista MQL).
  3. Após o preenchimento, a estratégia registra o preço médio de entrada, coloca a ordem de stop apropriada e rastreia o volume aberto por perna.
  4. Quando o mercado imprime além de TargetLevel, a estratégia envia uma ordem de mercado de fechamento parcial por perna e subsequentemente move o stop para o ponto de equilíbrio para a quantidade restante.
  5. As ordens stop são canceladas quando não resta volume ou quando a estratégia é interrompida.

Notas e limitações

  • O stop loss é regenerado sempre que o tamanho da posição muda. Se a corretora rejeitar ordens stop, verifique as permissões do conector e ajuste as configurações específicas da bolsa de acordo.
  • O take-profit não é registrado como ordem pendente. Em vez disso, o algoritmo espelha o EA monitorando o nível de preços e gerenciando as saídas em tempo real.
  • Como os pedidos são criados apenas uma vez, reinicie a estratégia para atualizar os pedidos pendentes após a alteração dos parâmetros (idêntico ao fluxo de trabalho MetaTrader).
namespace StockSharp.Samples.Strategies;

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

/// <summary>
/// Fibonacci Retracement Entries strategy: EMA trend with Fibonacci retracement levels.
/// Buys on retracement to 61.8% in uptrend, sells on retracement to 38.2% in downtrend.
/// </summary>
public class FibonacciPotentialEntriesRetracementStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _emaPeriod;
	private readonly StrategyParam<int> _lookback;
	private readonly StrategyParam<int> _signalCooldownCandles;

	private decimal _high;
	private decimal _low;
	private int _barCount;
	private int _candlesSinceTrade;

	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
	public int EmaPeriod { get => _emaPeriod.Value; set => _emaPeriod.Value = value; }
	public int Lookback { get => _lookback.Value; set => _lookback.Value = value; }
	public int SignalCooldownCandles { get => _signalCooldownCandles.Value; set => _signalCooldownCandles.Value = value; }

	public FibonacciPotentialEntriesRetracementStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(30).TimeFrame())
			.SetDisplay("Candle Type", "Candle timeframe", "General");
		_emaPeriod = Param(nameof(EmaPeriod), 50)
			.SetGreaterThanZero()
			.SetDisplay("EMA Period", "EMA period", "Indicators");
		_lookback = Param(nameof(Lookback), 50)
			.SetGreaterThanZero()
			.SetDisplay("Lookback", "Lookback for high/low", "General");
		_signalCooldownCandles = Param(nameof(SignalCooldownCandles), 6)
			.SetGreaterThanZero()
			.SetDisplay("Signal Cooldown", "Bars to wait between trades", "Trading");
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_high = 0;
		_low = decimal.MaxValue;
		_barCount = 0;
		_candlesSinceTrade = SignalCooldownCandles;
	}

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_high = 0;
		_low = decimal.MaxValue;
		_barCount = 0;
		_candlesSinceTrade = SignalCooldownCandles;
		var ema = new ExponentialMovingAverage { Length = EmaPeriod };
		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(ema, ProcessCandle).Start();
	}

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

		if (_candlesSinceTrade < SignalCooldownCandles)
			_candlesSinceTrade++;

		if (candle.HighPrice > _high) _high = candle.HighPrice;
		if (candle.LowPrice < _low) _low = candle.LowPrice;
		_barCount++;

		if (_barCount < 20) return;

		var range = _high - _low;
		if (range <= 0) return;

		var close = candle.ClosePrice;
		var fib618 = _high - range * 0.618m;
		var fib382 = _high - range * 0.382m;
		if (close > emaValue && close <= fib618 && Position <= 0 && _candlesSinceTrade >= SignalCooldownCandles)
		{
			BuyMarket();
			_candlesSinceTrade = 0;
		}
		else if (close < emaValue && close >= fib382 && Position >= 0 && _candlesSinceTrade >= SignalCooldownCandles)
		{
			SellMarket();
			_candlesSinceTrade = 0;
		}
	}
}