Auf GitHub ansehen

Gleichgewichts-Kerzen-Muster-Strategie

Strategie, die Gleichgewichtskerzen verwendet, um kurze Trends zu erkennen und bei Rücksetzern einzusteigen. Das Gleichgewicht ist der Mittelpunkt zwischen dem höchsten und niedrigsten Preis über ein Rückblickfenster. Nach einer bullischen oder bärischen Serie löst eine Bewegung zurück durch das Gleichgewicht einen Einstieg aus. ATR wird für optionale Stop/Ziel-Werte und zum Ausstieg bei ungewöhnlich großen Kerzen verwendet.

Details

  • Einstiegskriterien:
    • Long: Nach einem bullischen Trend, wenn der Preis das Gleichgewicht nach unten durchbricht.
    • Short: Nach einem bärischen Trend, wenn der Preis das Gleichgewicht nach oben durchbricht.
  • Long/Short: Beide
  • Stops: ATR-basierter Stop Loss und Take Profit (optional)
  • Standardwerte:
    • EquilibriumLength = 9
    • CandlesForTrend = 7
    • MaxPullbackCandles = 2
    • AtrPeriod = 14
    • StopMultiplier = 2
    • UseTpSl = true
    • UseBigCandleExit = true
    • BigCandleMultiplier = 1
    • UseReverse = false
    • CandleType = TimeSpan.FromMinutes(5).TimeFrame()
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 EquilibriumCandlesPatternStrategy : 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 EquilibriumCandlesPatternStrategy()
	{
		_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;
	}
}