Ver no GitHub

Harami CCI Confirmação

Visão geral

Harami CCI Confirmação é uma porta StockSharp de alto nível do MetaTrader 5 consultor especialista Expert_ABH_BH_CCI. O EA original negocia os padrões de reversão Bullish Harami e Bearish Harami de duas velas. Antes de entrar em uma negociação, ele exige a confirmação de um oscilador do Commodity Channel Index (CCI) e mede o tamanho do corpo da vela em relação a uma média móvel para garantir que a vela maior realmente domine o intervalo. A conversão StockSharp mantém a mesma lógica de confirmação, processa apenas velas concluídas e usa o módulo de proteção integrado da plataforma para segurança do pedido.

Lógica estratégica

Detecção de padrões

  • Cálculo do corpo médio – mantém uma média móvel dos corpos absolutos das velas nas últimas N barras (padrão 5). Isso reflete a classe auxiliar MetaTrader que suaviza o tamanho da vela e a referência de tendência.
  • Bullish Harami – exige que a vela anterior seja de alta, a vela anterior seja de baixa com um corpo mais longo que a média e o corpo de alta permaneça dentro da faixa de baixa. O ponto médio da vela anterior também deve ficar abaixo da média móvel de fechamento, confirmando uma tendência de baixa.
  • Bearish Harami – condições espelhadas: a vela anterior deve ser de baixa, a vela anterior deve ser de alta e longa, o corpo de baixa deve estar contido dentro da faixa de alta e o ponto médio precisa estar acima da média móvel próxima para confirmar uma tendência de alta.

CCI confirmação

  • Filtro de entrada – a estratégia verifica o valor CCI da vela concluída mais recentemente (turno 1). As negociações longas exigem que CCI esteja abaixo de -EntryThreshold (padrão 50), enquanto as negociações curtas exigem um valor acima de +EntryThreshold.
  • Banda de saída – o histórico CCI é monitorado para cruzamentos de ±ExitBand (padrão 80). Quando o indicador sobe até -ExitBand, qualquer posição curta aberta é fechada. Quando cai abaixo de +ExitBand, a longa exposição existente é fechada. Isso reproduz os "votos" usados ​​pelo especialista MetaTrader para nivelar posições.

Gestão comercial

  • Reversões – se a configuração oposta de Harami for confirmada enquanto a estratégia já mantém uma posição, ela negociará volume suficiente para fechar a exposição existente e abrir a nova direção.
  • ProteçãoStartProtection() é ativado para que os usuários possam anexar configurações de stop-loss ou take-profit por meio da IU do StockSharp, se desejarem. Nenhuma parada fixa é aplicada por padrão para permanecer alinhado com a fonte EA, que dependia de configurações manuais de gerenciamento de dinheiro.

Parâmetros

  • Volume de pedidos – volume base enviado a cada entrada no mercado. O volume extra é adicionado automaticamente para fechar a posição oposta quando ocorre uma reversão.
  • CCI Período – duração do oscilador do Commodity Channel Index.
  • Body Average – número de velas históricas usadas para calcular a média do tamanho do corpo e preços de fechamento.
  • CCI Entrada – valor absoluto mínimo CCI necessário para aceitar um sinal Harami.
  • CCI Banda de Saída – magnitude da banda que define as regras de saída de cruzamento CCI.
  • Tipo de vela – período usado para velas (padrão: período de 1 hora).

Notas adicionais

  • Todos os cálculos são executados em velas concluídas fornecidas por SubscribeCandles. Os sinais intrabar são intencionalmente ignorados para corresponder ao modelo de execução MetaTrader.
  • A estratégia mantém um breve histórico deslizante de velas e valores CCI para avaliar as regras Harami sem recriar buffers completos de indicadores.
  • Somente a implementação do C# é fornecida nesta pasta; não há versão Python para esta conversão.
namespace StockSharp.Samples.Strategies;

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

/// <summary>
/// Harami CCI Confirmation strategy: Harami pattern with CCI confirmation.
/// </summary>
public class HaramiCciConfirmationStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _cciPeriod;
	private readonly StrategyParam<decimal> _entryLevel;
	private readonly StrategyParam<int> _signalCooldownCandles;

	private readonly List<ICandleMessage> _candles = new();
	private int _candlesSinceTrade;

	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
	public int CciPeriod { get => _cciPeriod.Value; set => _cciPeriod.Value = value; }
	public decimal EntryLevel { get => _entryLevel.Value; set => _entryLevel.Value = value; }
	public int SignalCooldownCandles { get => _signalCooldownCandles.Value; set => _signalCooldownCandles.Value = value; }

	public HaramiCciConfirmationStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(30).TimeFrame())
			.SetDisplay("Candle Type", "Candle timeframe", "General");
		_cciPeriod = Param(nameof(CciPeriod), 14)
			.SetGreaterThanZero()
			.SetDisplay("CCI Period", "CCI period", "Indicators");
		_entryLevel = Param(nameof(EntryLevel), 0m)
			.SetDisplay("Entry Level", "CCI threshold", "Signals");
		_signalCooldownCandles = Param(nameof(SignalCooldownCandles), 6)
			.SetGreaterThanZero()
			.SetDisplay("Signal Cooldown", "Bars to wait between trades", "Trading");
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_candles.Clear();
		_candlesSinceTrade = SignalCooldownCandles;
	}

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_candles.Clear();
		_candlesSinceTrade = SignalCooldownCandles;
		var cci = new CommodityChannelIndex { Length = CciPeriod };
		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(cci, ProcessCandle).Start();
	}

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

		if (_candlesSinceTrade < SignalCooldownCandles)
			_candlesSinceTrade++;

		_candles.Add(candle);
		if (_candles.Count > 5) _candles.RemoveAt(0);

		if (_candles.Count >= 2)
		{
			var curr = _candles[^1];
			var prev = _candles[^2];

			var bullishHarami = prev.OpenPrice > prev.ClosePrice
				&& curr.ClosePrice > curr.OpenPrice
				&& curr.OpenPrice > prev.ClosePrice
				&& curr.ClosePrice < prev.OpenPrice;

			var bearishHarami = prev.ClosePrice > prev.OpenPrice
				&& curr.OpenPrice > curr.ClosePrice
				&& curr.ClosePrice > prev.OpenPrice
				&& curr.OpenPrice < prev.ClosePrice;

			if (bullishHarami && cciValue < -EntryLevel && Position <= 0 && _candlesSinceTrade >= SignalCooldownCandles)
			{
				BuyMarket();
				_candlesSinceTrade = 0;
			}
			else if (bearishHarami && cciValue > EntryLevel && Position >= 0 && _candlesSinceTrade >= SignalCooldownCandles)
			{
				SellMarket();
				_candlesSinceTrade = 0;
			}
		}
	}
}