Auf GitHub ansehen

EMA-Trend-Heikin-Ashi-Einstiegs-Strategie

Strategie, die Bollinger-Bänder auf Heikin-Ashi-Kerzen mit einem EMA-Trendfilter auf dem übergeordneten Zeitrahmen verwendet. Kauft nach aufeinanderfolgenden bärischen Heikin-Ashi-Kerzen, die das untere Band berühren, gefolgt von einer bullischen Kerze darüber, wenn die schnelle EMA des übergeordneten Zeitrahmens über der langsamen EMA liegt. Verkauft umgekehrt.

Nach dem Einstieg wird ein erstes Ziel in Höhe des Risikos genommen und der Stop anhand der Extrema der vorherigen Kerze nachgezogen.

Details

  • Einstiegskriterien:
    • Long: mindestens zwei bärische HA-Kerzen am unteren Band, dann bullische darüber mit schneller EMA des übergeordneten Zeitrahmens über langsamer EMA
    • Short: mindestens zwei bullische HA-Kerzen am oberen Band, dann bärische darunter mit schneller EMA des übergeordneten Zeitrahmens unter langsamer EMA
  • Long/Short: Beide
  • Ausstiegskriterien:
    • Long: erstes Ziel bei 1R, dann Trailing-Stop an vorherigen Tiefs
    • Short: erstes Ziel bei 1R, dann Trailing-Stop an vorherigen Hochs
  • Stops: Vorheriges Kerzentief/-hoch
  • Standardwerte:
    • BollingerPeriod = 20
    • BollingerDeviation = 2m
    • FastEmaPeriod = 9
    • SlowEmaPeriod = 21
    • CandleType = TimeSpan.FromMinutes(5).TimeFrame()
    • HigherTimeframe = TimeSpan.FromMinutes(180).TimeFrame()
  • Filter:
    • Kategorie: Muster
    • Richtung: Beide
    • Indikatoren: Bollinger Bands, Heikin Ashi, EMA
    • Stops: Ja
    • Komplexität: Mittel
    • Zeitrahmen: Mittelfristig
    • Saisonalität: Nein
    • Neuronale Netze: Nein
    • Divergenz: Nein
    • Risikolevel: Mittel
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 EmaTrendHeikinAshiEntryStrategy : 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 EmaTrendHeikinAshiEntryStrategy()
	{
		_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;
	}
}