Ver no GitHub

Estratégia de rastreamento Macd Stochastic

MACD Stochastic Estratégia de rastreamento

Visão geral

  • Convertido do MetaTrader 4 consultor especialista MQL/7637/3_lccfpgubwykd__www_forex-instruments_info.mq4.
  • Usa um fluxo de trabalho de três períodos de tempo: velas horárias acionam ambos os filtros MACD, velas de 15 minutos fornecem osciladores Stochastic e velas de 1 minuto confirmam quebras de preços e gerenciam saídas finais.
  • Implementa uma estratégia StockSharp de alto nível usando SubscribeCandles(...).Bind(...) / BindEx(...) sem pesquisa manual de dados.
  • As posições são abertas com ordens de mercado e gerenciadas inteiramente dentro da estratégia (não foram necessárias alterações externas no equipamento de teste).

Indicadores e Parâmetros

Nome Tipo Padrão Descrição
LongStopLoss decimal 17 Distância inicial de parada para negociações longas, expressa em pontos de instrumento.
ShortStopLoss decimal 40 Distância inicial de parada para negociações curtas (pontos).
LongTrailingStop decimal 88 Distância final para posições longas.
ShortTrailingStop decimal 76 Distância final para posições curtas.
OrderVolume decimal 0.1 Volume base de negociação (lotes) espelhado da entrada MQL.
MacdCandleType DataType H1 Prazo para os filtros MACD de alta e baixa (22/27/9 e 19/77/9).
StochasticCandleType DataType M15 Período usado para ambos os osciladores Stochastic (5/3/11 e 9/3/19).
EntryCandleType DataType M1 Prazo que fornece confirmação de rompimento e lógica de rastreamento.

Todas as configurações baseadas em pontos são convertidas em preços absolutos por meio do instrumento PriceStep, reproduzindo fielmente o multiplicador MetaTrader Point.

Regras de negociação

Entrada longa

  1. A linha principal horária MACD(22,27,9) cruza acima de seu valor anterior, mas permanece abaixo de zero.
  2. M15 Stochastic(%K=5,%D=3,slowing=11) está abaixo de 26 e subindo em relação ao seu valor anterior.
  3. O fechamento atual do M1 perfura a máxima anterior do M1.
  4. Quando todas as condições se alinham e nenhuma posição está aberta, a estratégia compra OrderVolume mais qualquer quantidade necessária para inverter uma posição vendida existente.

Entrada curta

  1. A linha principal horária MACD(19,77,9) fica abaixo do valor anterior, com o valor anterior acima de zero.
  2. M15 Stochastic(%K=9,%D=3,slowing=19) está acima de 70.
  3. O fechamento atual do M1 quebra abaixo da mínima anterior do M1.
  4. Uma posição curta é aberta com a mesma lógica de inversão de posição do EA original.

Sair e seguir

  • As paradas iniciais refletem as distâncias MQL StopLoss em pontos.
  • Os trailing stops são ativados quando o preço se move mais do que a distância final especificada em favor da posição e são recalculados em cada vela M1 finalizada.
  • Se o preço atingir o nível de stop ativo (inicial ou de trilha), a posição será fechada com uma ordem de mercado.

Notas de implementação

  • As assinaturas de velas são divididas por período de tempo para que as atualizações dos indicadores permaneçam independentes, correspondendo exatamente ao comportamento de vários períodos de tempo do EA.
  • As comparações finais de MQL Bid/Ask são aproximadas com os máximos/mínimos da vela M1 finalizados, que é a representação mais próxima dentro do alto nível baseado em vela API.
  • O código segue as diretrizes do repositório: recuo de tabulação, namespace StockSharp.Samples.Strategies, comentários em inglês e declarações de parâmetros dentro do construtor via Param(...).
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>
/// MACD + Stochastic trailing strategy.
/// Enters long when MACD histogram is positive and Stochastic K crosses above D from oversold.
/// Enters short when MACD histogram is negative and Stochastic K crosses below D from overbought.
/// </summary>
public class MacdStochasticTrailingStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;

	private decimal? _prevK;
	private decimal? _prevD;

	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }

	public MacdStochasticTrailingStrategy()
	{
		_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();
		_prevK = null;
		_prevD = null;
	}

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);

		_prevK = null;
		_prevD = null;

		var macd = new MovingAverageConvergenceDivergenceSignal();
		var stoch = new StochasticOscillator();

		var subscription = SubscribeCandles(CandleType);
		subscription
			.BindEx(macd, stoch, ProcessCandle)
			.Start();
	}

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

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

		var macdVal = (MovingAverageConvergenceDivergenceSignalValue)macdValue;
		var stochVal = (StochasticOscillatorValue)stochValue;

		if (macdVal.Macd is not decimal macd || macdVal.Signal is not decimal signal)
			return;
		if (stochVal.K is not decimal k || stochVal.D is not decimal d)
			return;

		if (_prevK is not decimal prevK || _prevD is not decimal prevD)
		{
			_prevK = k;
			_prevD = d;
			return;
		}

		var histogram = macd - signal;
		var kCrossUp = prevK <= prevD && k > d;
		var kCrossDown = prevK >= prevD && k < d;

		// Buy: MACD histogram positive + stochastic K crosses above D
		if (histogram > 0 && kCrossUp && k < 50 && Position <= 0)
		{
			if (Position < 0)
				BuyMarket();
			BuyMarket();
		}
		// Sell: MACD histogram negative + stochastic K crosses below D
		else if (histogram < 0 && kCrossDown && k > 50 && Position >= 0)
		{
			if (Position > 0)
				SellMarket();
			SellMarket();
		}

		_prevK = k;
		_prevD = d;
	}
}