Ver no GitHub

Estratégia de histograma de abertura do dia MACD

Visão geral

Esta estratégia replica o especialista MetaTrader "2 1000 1 0,7% 0,5 500lev st" inserindo uma negociação no início de cada novo dia de negociação e filtrando a direção com a inclinação do histograma MACD. O sistema foi projetado para velas horárias e depende de parâmetros fixos de gerenciamento de dinheiro convertidos das configurações originais MQL.

Lógica de negociação

  • A estratégia monitora velas horárias e detecta a primeira vela de cada novo dia.
  • Ele avalia o histograma MACD nas duas velas concluídas mais recentes do dia anterior.
  • Se o histograma cair entre essas duas barras, o sistema abre uma posição longa na primeira vela do novo dia.
  • Se o histograma aumentar, ele abre uma posição curta.
  • Apenas uma posição pode estar ativa por vez. Os sinais opostos fecham a negociação atual antes de abrir a nova direção.

Gestão de risco

  • Distância inicial do stop loss: 875 pontos (convertido em preço multiplicando pela etapa de preço do instrumento).
  • Distância de lucro: 510 pontos.
  • Distância de parada final: 2.172 pontos. O stop segue o preço mais alto (longo) ou mais baixo (curto) alcançado desde a entrada e substitui o stop inicial quando este se torna mais apertado.
  • A opção de ponto de equilíbrio original foi desativada e, portanto, omitida aqui.

Parâmetros

Nome Descrição Padrão
CandleType Série de velas utilizadas pela estratégia (de hora em hora por padrão). Velas de 1 hora
MacdFastPeriod Período EMA rápido para o MACD. 58
MacdSlowPeriod Período EMA lento para o MACD. 195
MacdSignalPeriod Período da linha de sinal para o MACD. 183
StopLossPoints Distância de stop-loss expressa em pontos do instrumento. 875
TakeProfitPoints Distância de lucro em pontos. 510
TrailingStopPoints Distância de parada final em pontos. 2172

Notas

  • A estratégia usa apenas velas concluídas para evitar antecipação intrabarra, espelhando a opção "Usar valor da barra anterior" do especialista fonte.
  • As saídas móveis e fixas são tratadas internamente, portanto, as proteções adicionais do portfólio devem permanecer desativadas para evitar o tratamento duplo de stops.
  • A lógica pressupõe que a corretora usa definições de pontos padrão (etapa de preço). Ajuste os parâmetros se o instrumento usar um tamanho de tick diferente.
namespace StockSharp.Samples.Strategies;

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

/// <summary>
/// Day Opening MACD Histogram strategy: MACD histogram direction.
/// Buys when MACD histogram turns positive, sells when turns negative.
/// </summary>
public class DayOpeningMacdHistogramStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _fastPeriod;
	private readonly StrategyParam<int> _slowPeriod;
	private readonly StrategyParam<int> _signalPeriod;
	private readonly StrategyParam<int> _signalCooldownCandles;

	private decimal _prevHistogram;
	private int _candlesSinceTrade;
	private bool _hasPrev;

	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
	public int FastPeriod { get => _fastPeriod.Value; set => _fastPeriod.Value = value; }
	public int SlowPeriod { get => _slowPeriod.Value; set => _slowPeriod.Value = value; }
	public int SignalPeriod { get => _signalPeriod.Value; set => _signalPeriod.Value = value; }
	public int SignalCooldownCandles { get => _signalCooldownCandles.Value; set => _signalCooldownCandles.Value = value; }

	public DayOpeningMacdHistogramStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(60).TimeFrame())
			.SetDisplay("Candle Type", "Candle timeframe", "General");
		_fastPeriod = Param(nameof(FastPeriod), 12)
			.SetGreaterThanZero()
			.SetDisplay("MACD Fast", "MACD fast EMA period", "Indicators");
		_slowPeriod = Param(nameof(SlowPeriod), 26)
			.SetGreaterThanZero()
			.SetDisplay("MACD Slow", "MACD slow EMA period", "Indicators");
		_signalPeriod = Param(nameof(SignalPeriod), 9)
			.SetGreaterThanZero()
			.SetDisplay("Signal Period", "MACD signal period", "Indicators");
		_signalCooldownCandles = Param(nameof(SignalCooldownCandles), 4)
			.SetGreaterThanZero()
			.SetDisplay("Signal Cooldown", "Bars to wait between trades", "Trading");
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_prevHistogram = 0;
		_candlesSinceTrade = SignalCooldownCandles;
		_hasPrev = false;
	}

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_prevHistogram = 0;
		_candlesSinceTrade = SignalCooldownCandles;
		_hasPrev = false;
		var macd = new MovingAverageConvergenceDivergenceSignal
		{
			Macd = { ShortMa = { Length = FastPeriod }, LongMa = { Length = SlowPeriod } },
			SignalMa = { Length = SignalPeriod }
		};
		var subscription = SubscribeCandles(CandleType);
		subscription.BindEx(macd, ProcessCandle).Start();
	}

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

		if (_candlesSinceTrade < SignalCooldownCandles)
			_candlesSinceTrade++;

		if (macdValue is not MovingAverageConvergenceDivergenceSignalValue typed) return;
		if (typed.Macd is not decimal macdMain || typed.Signal is not decimal signal) return;

		var histogram = macdMain - signal;

		if (_hasPrev)
		{
			if (_prevHistogram <= 0 && histogram > 0 && Position <= 0 && _candlesSinceTrade >= SignalCooldownCandles)
			{
				BuyMarket();
				_candlesSinceTrade = 0;
			}
			else if (_prevHistogram >= 0 && histogram < 0 && Position >= 0 && _candlesSinceTrade >= SignalCooldownCandles)
			{
				SellMarket();
				_candlesSinceTrade = 0;
			}
		}

		_prevHistogram = histogram;
		_hasPrev = true;
	}
}