Ver no GitHub

Estratégia Três Indicadores

Visão geral

Esta estratégia é uma conversão do StockSharp do expert original "Three indicators" do MQL5. Ela avalia três osciladores clássicos — MACD, Oscilador Estocástico e RSI — em cada candle finalizado do período selecionado. Somente quando todos os filtros se alinham a estratégia entra em uma posição, garantindo que cada operação siga uma confirmação multi-indicador consistente.

Lógica de trading

  1. Filtro de direção do candle – compara o preço de abertura do candle finalizado atual com o da abertura anterior. Uma abertura mais alta favorece operações compradas, uma abertura mais baixa favorece vendidas.
  2. Filtro de inclinação MACD – observa a inclinação da linha principal MACD (diferença entre o valor MACD principal atual e o anterior). Um MACD em queda favorece posições compradas, um MACD em alta favorece vendidas, exatamente como no expert de origem.
  3. Filtro de viés estocástico – verifica se o valor %D está abaixo ou acima do ponto médio 50. Valores abaixo de 50 apoiam comprados, valores acima de 50 apoiam vendidos.
  4. Filtro de viés RSI – usa o valor RSI relativo a 50. Valores abaixo de 50 autorizam comprados, valores acima de 50 autorizam vendidos.

Somente se todos os quatro filtros apoiarem a mesma direção a estratégia abrirá uma nova operação. Se um sinal oposto aparecer enquanto uma posição está aberta, a estratégia reverte imediatamente enviando uma única ordem de mercado que fecha a exposição existente e abre a nova direção, espelhando o comportamento da lógica MQL original.

Parâmetros

Parâmetro Descrição
CandleType Período dos candles fornecidos à estratégia. Padrão: 1 minuto.
TradeVolume Volume usado ao abrir uma posição ou reverter para o lado oposto.
MacdFastPeriod Comprimento da EMA rápida no cálculo MACD.
MacdSlowPeriod Comprimento da EMA lenta no cálculo MACD.
MacdSignalPeriod Comprimento da EMA para a linha de sinal MACD.
MacdPriceType Preço aplicado ao indicador MACD (Close, Open, High, Low, Median, Typical, Weighted).
StochasticKPeriod Período de retrocesso para a linha %K.
StochasticDPeriod Período de suavização para a linha %D.
StochasticSlowing Suavização adicional aplicada a %K antes do cálculo de %D.
RsiPeriod Período de média usado pelo filtro RSI.
RsiPriceType Preço aplicado ao alimentar o indicador RSI.

Indicadores

  • MACD (Convergência/Divergência de Médias Móveis) – configurado com os comprimentos rápido, lento e de sinal especificados pelo usuário.
  • Oscilador Estocástico – usa a implementação do StockSharp com comprimentos %K/%D e suavização configuráveis.
  • Índice de Força Relativa (RSI) – fornece a confirmação de impulso final.

Notas de comportamento

  • A estratégia processa apenas candles finalizados, melhorando a estabilidade em comparação com o gatilho baseado em ticks do expert original.
  • A pausa de 30 segundos presente na versão MQL é removida; as reversões são emitidas imediatamente com a ordem de mercado combinada.
  • A suavização estocástica usa a implementação de média móvel padrão do StockSharp, que corresponde à suavização padrão baseada em SMA do script original.
  • A seleção de fonte de preço para MACD e RSI é fornecida através do enum IndicatorAppliedPrice, correspondendo às opções disponíveis no MetaTrader (Close, Open, High, Low, Median, Typical, Weighted).

Gerenciamento de risco

Nenhuma ordem de stop-loss ou take-profit é colocada automaticamente. O gerenciamento de posição é conduzido exclusivamente pela lógica de reversão multi-indicador. Adicionar controles de risco externos se necessário.

Dicas de uso

  1. Selecionar o instrumento e período desejados através de CandleType.
  2. Ajustar os parâmetros do indicador para se adequar à volatilidade do mercado e frequência de sinais.
  3. Monitorar os objetos de gráfico adicionados pela estratégia (candles mais os três indicadores) para validar o alinhamento de sinais.
  4. Combinar com gerenciamento de dinheiro externo se stops fixos ou alvos de lucro forem necessários.
namespace StockSharp.Samples.Strategies;

using System;

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

/// <summary>
/// Combines MACD, Stochastic Oscillator, and RSI filters.
/// All three indicators must agree on direction to enter a trade.
/// </summary>
public class ThreeIndicatorsStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _macdFastPeriod;
	private readonly StrategyParam<int> _macdSlowPeriod;
	private readonly StrategyParam<int> _macdSignalPeriod;
	private readonly StrategyParam<int> _stochasticKPeriod;
	private readonly StrategyParam<int> _stochasticDPeriod;
	private readonly StrategyParam<int> _rsiPeriod;
	private readonly StrategyParam<int> _signalCooldownBars;

	private decimal? _previousOpen;
	private decimal? _previousMacdMain;
	private int _previousCompositeSignal;
	private int _cooldownRemaining;

	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
	public int MacdFastPeriod { get => _macdFastPeriod.Value; set => _macdFastPeriod.Value = value; }
	public int MacdSlowPeriod { get => _macdSlowPeriod.Value; set => _macdSlowPeriod.Value = value; }
	public int MacdSignalPeriod { get => _macdSignalPeriod.Value; set => _macdSignalPeriod.Value = value; }
	public int StochasticKPeriod { get => _stochasticKPeriod.Value; set => _stochasticKPeriod.Value = value; }
	public int StochasticDPeriod { get => _stochasticDPeriod.Value; set => _stochasticDPeriod.Value = value; }
	public int RsiPeriod { get => _rsiPeriod.Value; set => _rsiPeriod.Value = value; }
	public int SignalCooldownBars { get => _signalCooldownBars.Value; set => _signalCooldownBars.Value = value; }

	public ThreeIndicatorsStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame())
			.SetDisplay("Candle type", "Primary timeframe", "General");

		_macdFastPeriod = Param(nameof(MacdFastPeriod), 11)
			.SetDisplay("MACD fast", "Fast EMA length", "MACD");

		_macdSlowPeriod = Param(nameof(MacdSlowPeriod), 53)
			.SetDisplay("MACD slow", "Slow EMA length", "MACD");

		_macdSignalPeriod = Param(nameof(MacdSignalPeriod), 26)
			.SetDisplay("MACD signal", "Signal smoothing", "MACD");

		_stochasticKPeriod = Param(nameof(StochasticKPeriod), 40)
			.SetDisplay("Stochastic %K", "%K length", "Stochastic");

		_stochasticDPeriod = Param(nameof(StochasticDPeriod), 23)
			.SetDisplay("Stochastic %D", "%D smoothing", "Stochastic");

		_rsiPeriod = Param(nameof(RsiPeriod), 14)
			.SetDisplay("RSI period", "RSI length", "RSI");

		_signalCooldownBars = Param(nameof(SignalCooldownBars), 2)
			.SetNotNegative()
			.SetDisplay("Signal Cooldown Bars", "Closed candles to wait before a new entry", "General");
	}

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

		_previousOpen = null;
		_previousMacdMain = null;
		_previousCompositeSignal = 0;
		_cooldownRemaining = 0;
	}

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

		_previousOpen = null;
		_previousMacdMain = null;
		_previousCompositeSignal = 0;
		_cooldownRemaining = 0;

		var macd = new MovingAverageConvergenceDivergenceSignal();
		macd.Macd.ShortMa.Length = MacdFastPeriod;
		macd.Macd.LongMa.Length = MacdSlowPeriod;
		macd.SignalMa.Length = MacdSignalPeriod;

		var stochastic = new StochasticOscillator();
		stochastic.K.Length = StochasticKPeriod;
		stochastic.D.Length = StochasticDPeriod;

		var rsi = new RelativeStrengthIndex { Length = RsiPeriod };

		var subscription = SubscribeCandles(CandleType);

		subscription
			.BindEx(macd, stochastic, rsi, ProcessCandle)
			.Start();

		var area = CreateChartArea();
		if (area != null)
		{
			DrawCandles(area, subscription);
			DrawOwnTrades(area);
		}
	}

	private void ProcessCandle(ICandleMessage candle, IIndicatorValue macdValue, IIndicatorValue stochValue, IIndicatorValue rsiValue)
	{
		if (candle.State != CandleStates.Finished)
			return;

		if (!macdValue.IsFinal || !stochValue.IsFinal || !rsiValue.IsFinal)
			return;

		if (_cooldownRemaining > 0)
			_cooldownRemaining--;

		if (!macdValue.IsFormed || !stochValue.IsFormed || !rsiValue.IsFormed)
			return;

		var macdVal = (MovingAverageConvergenceDivergenceSignalValue)macdValue;
		var macdMain = macdVal.Macd ?? 0m;

		var stoch = (StochasticOscillatorValue)stochValue;
		var stochasticD = stoch.D ?? 50m;

		var rsi = rsiValue.GetValue<decimal>();

		if (_previousOpen == null || _previousMacdMain == null)
		{
			_previousOpen = candle.OpenPrice;
			_previousMacdMain = macdMain;
			return;
		}

		// Candle direction
		var candleSignal = candle.OpenPrice > _previousOpen.Value ? 1 : candle.OpenPrice < _previousOpen.Value ? -1 : 0;

		// MACD direction (difference decreasing = bullish momentum)
		var macdDelta = macdMain - _previousMacdMain.Value;
		var macdSignal = macdDelta < 0m ? 1 : macdDelta > 0m ? -1 : 0;

		// Stochastic direction
		var stochSignal = stochasticD < 50m ? 1 : stochasticD > 50m ? -1 : 0;

		// RSI direction
		var rsiSignal = rsi < 50m ? 1 : rsi > 50m ? -1 : 0;

		var longSignal = candleSignal >= 0 && macdSignal >= 0 && stochSignal >= 0 && rsiSignal >= 0;
		var shortSignal = candleSignal <= 0 && macdSignal <= 0 && stochSignal <= 0 && rsiSignal <= 0;

		var compositeSignal = longSignal ? 1 : shortSignal ? -1 : 0;

		if (_cooldownRemaining == 0 && compositeSignal != 0 && compositeSignal != _previousCompositeSignal)
		{
			if (compositeSignal > 0 && Position <= 0)
			{
				BuyMarket(Volume + (Position < 0 ? -Position : 0m));
				_cooldownRemaining = SignalCooldownBars;
			}
			else if (compositeSignal < 0 && Position >= 0)
			{
				SellMarket(Volume + (Position > 0 ? Position : 0m));
				_cooldownRemaining = SignalCooldownBars;
			}
		}

		_previousOpen = candle.OpenPrice;
		_previousMacdMain = macdMain;
		_previousCompositeSignal = compositeSignal;
	}
}