Auf GitHub ansehen

ADX Smoothed Cross-Strategie

Zusammenfassung

Die Strategie handelt auf Basis eines doppelt geglätteten Average Directional Index (ADX). Sie vergleicht die geglätteten +DI- und -DI-Linien, um Trendwechsel zu erkennen. Wenn die geglättete +DI-Linie die geglättete -DI-Linie von unten kreuzt, eröffnet die Strategie eine Long-Position. Wenn die geglättete +DI-Linie die geglättete -DI-Linie von oben kreuzt, wird eine Short-Position eröffnet.

Funktionsweise

  • Verwendet einen ADX-Indikator mit konfigurierbarer Periode.
  • Wendet zwei Durchläufe der exponentiellen Glättung an, gesteuert durch die Parameter Alpha1 und Alpha2.
  • Ein Long-Signal tritt auf, wenn das vorherige geglättete +DI unter dem geglätteten -DI lag und das aktuelle geglättete +DI darüber liegt.
  • Ein Short-Signal tritt beim umgekehrten Kreuzungsverhalten auf.
  • Optionale Parameter ermöglichen das Deaktivieren von Long- oder Short-Trades und steuern, ob bestehende Positionen bei einem entgegengesetzten Signal geschlossen werden können.
  • Das integrierte Risikomanagement setzt Stop-Loss- und Take-Profit-Niveaus in Punkten.

Parameter

Name Beschreibung
AdxPeriod Periode für die ADX-Berechnung.
Alpha1 Erster Glättungskoeffizient (0-1).
Alpha2 Zweiter Glättungskoeffizient (0-1).
StopLoss Stop-Loss in Punkten.
TakeProfit Take-Profit in Punkten.
AllowBuy Long-Einstiege aktivieren.
AllowSell Short-Einstiege aktivieren.
AllowCloseBuy Schließen von Long-Positionen bei Verkaufssignalen erlauben.
AllowCloseSell Schließen von Short-Positionen bei Kaufsignalen erlauben.
CandleType Zeitrahmen für den Indikator.

Hinweise

  • Es werden nur abgeschlossene Kerzen verarbeitet.
  • Die Strategie verwendet die High-Level-API mit Indikator-Bindung.
  • Stop-Loss und Take-Profit werden über StartProtection verwaltet.
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;

/// <summary>
/// Smoothed EMA crossover strategy (ADX-inspired directional cross concept).
/// Buys when fast EMA crosses above slow EMA, sells when below.
/// </summary>
public class AdxSmoothedCrossStrategy : Strategy
{
	private readonly StrategyParam<int> _fastPeriod;
	private readonly StrategyParam<int> _slowPeriod;
	private readonly StrategyParam<DataType> _candleType;

	private decimal? _prevFast;
	private decimal? _prevSlow;

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

	public AdxSmoothedCrossStrategy()
	{
		_fastPeriod = Param(nameof(FastPeriod), 10)
			.SetGreaterThanZero()
			.SetDisplay("Fast Period", "Fast EMA period", "Indicator");

		_slowPeriod = Param(nameof(SlowPeriod), 25)
			.SetGreaterThanZero()
			.SetDisplay("Slow Period", "Slow EMA period", "Indicator");

		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
			.SetDisplay("Candle Type", "Candle type", "General");
	}

	/// <inheritdoc />
	public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
		=> [(Security, CandleType)];

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_prevFast = null;
		_prevSlow = null;
	}

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);

		var fast = new ExponentialMovingAverage { Length = FastPeriod };
		var slow = new ExponentialMovingAverage { Length = SlowPeriod };

		SubscribeCandles(CandleType)
			.Bind(fast, slow, ProcessCandle)
			.Start();
	}

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

		if (_prevFast is null || _prevSlow is null)
		{
			_prevFast = fastValue;
			_prevSlow = slowValue;
			return;
		}

		var crossUp = _prevFast <= _prevSlow && fastValue > slowValue;
		var crossDown = _prevFast >= _prevSlow && fastValue < slowValue;

		if (crossUp && Position <= 0)
		{
			if (Position < 0) BuyMarket();
			BuyMarket();
		}
		else if (crossDown && Position >= 0)
		{
			if (Position > 0) SellMarket();
			SellMarket();
		}

		_prevFast = fastValue;
		_prevSlow = slowValue;
	}
}