Ver no GitHub

Estratégia Heiken Ashi Supertrend ADX

Estratégia que combina velas Heiken Ashi, a direção do Supertrend e um filtro ADX opcional. Uma vela Heiken Ashi de alta sem sombra inferior abre uma posição comprada em tendência de alta. Velas de baixa sem sombra superior abrem posições vendidas em tendência de baixa. As posições fecham em sinais opostos ou em um stop trailing baseado em ATR.

Os testes indicam um retorno anual médio de aproximadamente 128%. Funciona melhor no mercado de criptomoedas.

Heiken Ashi suaviza o ruído enquanto Supertrend e ADX confirmam a direção. O ATR determina os stops dinâmicos.

Detalhes

  • Critérios de entrada:
    • Comprado: vela HA de alta sem sombra inferior com Supertrend ascendente e confirmação ADX opcionais
    • Vendido: vela HA de baixa sem sombra superior com Supertrend descendente e confirmação ADX opcionais
  • Comprado/Vendido: Ambos
  • Critérios de saída: Vela oposta ou stop trailing ATR
  • Stops: Stop trailing ATR
  • Valores padrão:
    • UseSupertrend = true
    • AtrPeriod = 10
    • SupertrendMultiplier = 3m
    • UseAdxFilter = false
    • AdxPeriod = 14
    • AdxThreshold = 25m
    • TrailAtrMultiplier = 2m
    • CandleType = TimeSpan.FromMinutes(15).TimeFrame()
  • Filtros:
    • Categoria: Tendência
    • Direção: Ambos
    • Indicadores: Heiken Ashi, Supertrend, ADX, ATR
    • Stops: Sim
    • Complexidade: Intermediário
    • Período: Médio prazo
    • Sazonalidade: Não
    • Redes neurais: Não
    • Divergência: Não
    • Nível de risco: Médio
using System;
using System.Collections.Generic;

using Ecng.Common;

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

namespace StockSharp.Samples.Strategies;

public class HeikenAshiSupertrendAdxStrategy : Strategy
{
	private readonly StrategyParam<int> _fastEmaPeriod;
	private readonly StrategyParam<int> _slowEmaPeriod;
	private readonly StrategyParam<DataType> _candleType;
	private decimal _prevFastEma;
	private decimal _prevSlowEma;

	public int FastEmaPeriod { get => _fastEmaPeriod.Value; set => _fastEmaPeriod.Value = value; }
	public int SlowEmaPeriod { get => _slowEmaPeriod.Value; set => _slowEmaPeriod.Value = value; }
	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }

	public HeikenAshiSupertrendAdxStrategy()
	{
		_fastEmaPeriod = Param(nameof(FastEmaPeriod), 120)
			.SetGreaterThanZero()
			.SetDisplay("Fast EMA", "Fast EMA period", "Indicators");
		_slowEmaPeriod = Param(nameof(SlowEmaPeriod), 450)
			.SetGreaterThanZero()
			.SetDisplay("Slow EMA", "Slow EMA period", "Indicators");
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(1).TimeFrame())
			.SetDisplay("Candle Type", "Type of candles to use", "General");
	}

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

	protected override void OnReseted()
	{
		base.OnReseted();
		_prevFastEma = 0m;
		_prevSlowEma = 0m;
	}

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		var fastEma = new ExponentialMovingAverage { Length = FastEmaPeriod };
		var slowEma = new ExponentialMovingAverage { Length = SlowEmaPeriod };
		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(fastEma, slowEma, ProcessCandle).Start();
		var area = CreateChartArea();
		if (area != null)
		{
			DrawCandles(area, subscription);
			DrawIndicator(area, fastEma);
			DrawIndicator(area, slowEma);
			DrawOwnTrades(area);
		}
	}

	private void ProcessCandle(ICandleMessage candle, decimal fastEmaValue, decimal slowEmaValue)
	{
		if (candle.State != CandleStates.Finished) return;
		if (_prevFastEma == 0m || _prevSlowEma == 0m)
		{
			_prevFastEma = fastEmaValue;
			_prevSlowEma = slowEmaValue;
			return;
		}
		if (_prevFastEma <= _prevSlowEma && fastEmaValue > slowEmaValue && Position <= 0)
			BuyMarket();
		else if (_prevFastEma >= _prevSlowEma && fastEmaValue < slowEmaValue && Position >= 0)
			SellMarket();
		_prevFastEma = fastEmaValue;
		_prevSlowEma = slowEmaValue;
	}
}