Ver no GitHub

Estratégia RPM5 BullsBearsEyes

Visão geral

A RPM5 BullsBearsEyes Strategy é uma versão C# do MetaTrader 4 expert Rpm5_mt4v1. O consultor reconstruiu o oscilador BullsBearsEyes personalizado a partir das leituras Bulls Power e Bears Power e abriu uma única posição que seguiu a tendência predominante. Esta versão StockSharp reproduz o mesmo comportamento usando o API de alto nível, mantendo os parâmetros de risco originais, lógica de rastreamento e limites de sinal.

Reconstrução do indicador

  • Dois osciladores clássicos – Bulls Power e Bears Power – são calculados na série de velas configurada.
  • Sua soma é passada através do suavizador IIR de quatro estágios idêntico usado pelo indicador MT4. O fator de suavização (Gamma) controla a rapidez com que o oscilador reage.
  • A saída filtrada é transformada em um valor entre 0 e 1. Valores acima do limite central sinalizam dominância de alta, valores abaixo dele apontam para controle de baixa. Zero ou um exato aparecem quando um dos lados está completamente esgotado, correspondendo aos casos extremos do indicador original.

Regras de negociação

  1. A estratégia assina o período de tempo selecionado (5 minutos por padrão) e aguarda apenas as velas concluídas.
  2. Quando plana, avalia a proporção BullsBearsEyes:
    • Entrada longa – valor atual estritamente acima de Threshold (padrão 0,5).
    • Entrada curta – valor atual estritamente abaixo de Threshold.
    • O algoritmo mantém no máximo uma posição aberta. Os sinais opostos são ignorados até que a posição ativa seja totalmente fechada pela gestão de risco.
  3. Uma vez em uma negociação, a posição permanece intacta até que ocorra um evento de stop-loss, take-profit ou trailing stop.

Gestão de risco

  • As distâncias de stop-loss/take-profit são recriadas a partir das configurações originais de 25/150 pip. Eles são recalculados usando o instrumento PriceStep (pip) cada vez que uma nova posição é aberta.
  • ATR trailing: em cada vela concluída, o intervalo médio verdadeiro (período AtrPeriod, padrão 5) é avaliado. A distância final é igual a um pip mais AtrMultiplier × ATR. Quando o fechamento avança além dessa distância, o stop de proteção é apertado para manter a lacuna, idêntico à lógica MQL que repetidamente chamava OrderModify.
  • Os níveis de proteção são verificados antes de processar novos sinais, garantindo que as saídas sejam sempre priorizadas em relação às novas entradas, assim como na fonte EA.

Parâmetros

Nome Padrão Descrição
Bulls/Bears Period 13 Período médio para os indicadores Bulls Power e Bears Power.
Gamma 0,5 Razão de suavização IIR de quatro estágios para o oscilador BullsBearsEyes.
Threshold 0,5 Divisor entre zonas de alta (> limite) e de baixa (< limite).
ATR Period 5 Lookback usado para o trailing stop baseado em ATR.
ATR Multiplier 1,5 Multiplicador aplicado a ATR ao derivar a distância final.
Stop Loss (pips) 25 Distância de parada protetora, convertida de pips em preço.
Take Profit (pips) 150 Distância alvo de lucro, convertida de pips em preço.
Trade Volume 1 Volume de ordens de mercado utilizado para cada nova posição.
Candle Type Velas de 5 minutos Prazo processado pela estratégia.

Notas

  • O port não desenha os objetos visuais do canal diário que estavam presentes no MT4 porque eram apenas cosméticos.
  • Todos os comentários dentro do código são escritos em inglês conforme solicitado.
  • Os testes permanecem inalterados; execute as verificações de nível de solução existentes se a validação for necessária.
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>
/// RPM5 Bulls Bears Eyes strategy using Bull/Bear power with EMA filter.
/// Buy when bull power is positive and bear power crosses above threshold.
/// Sell when bear power is negative and bull power crosses below threshold.
/// </summary>
public class Rpm5BullsBearsEyesStrategy : Strategy
{
	private readonly StrategyParam<int> _emaPeriod;
	private readonly StrategyParam<int> _powerPeriod;
	private readonly StrategyParam<DataType> _candleType;

	private decimal _prevBull;
	private decimal _prevBear;
	private bool _hasPrev;

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

	public Rpm5BullsBearsEyesStrategy()
	{
		_emaPeriod = Param(nameof(EmaPeriod), 13)
			.SetDisplay("EMA Period", "EMA trend period", "Indicators");

		_powerPeriod = Param(nameof(PowerPeriod), 13)
			.SetDisplay("Power Period", "Bulls/Bears power period", "Indicators");

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

	/// <inheritdoc />
	public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
	{
		return [(Security, CandleType)];
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();

		_prevBull = 0m;
		_prevBear = 0m;
		_hasPrev = false;
	}

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);

		_hasPrev = false;

		var ema = new ExponentialMovingAverage { Length = EmaPeriod };
		var bulls = new BullPower { Length = PowerPeriod };
		var bears = new BearPower { Length = PowerPeriod };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(ema, bulls, bears, ProcessCandle)
			.Start();
	}

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

		if (!_hasPrev)
		{
			_prevBull = bullValue;
			_prevBear = bearValue;
			_hasPrev = true;
			return;
		}

		// Long: price above EMA, bull power positive, bear power crossing from negative to less negative
		var longSignal = candle.ClosePrice > emaValue && bullValue > 0 && _prevBear < 0 && bearValue > _prevBear;
		// Short: price below EMA, bear power negative, bull power crossing from positive to less positive
		var shortSignal = candle.ClosePrice < emaValue && bearValue < 0 && _prevBull > 0 && bullValue < _prevBull;

		if (Position <= 0 && longSignal)
		{
			if (Position < 0)
				BuyMarket();
			BuyMarket();
		}
		else if (Position >= 0 && shortSignal)
		{
			if (Position > 0)
				SellMarket();
			SellMarket();
		}

		_prevBull = bullValue;
		_prevBear = bearValue;
	}
}