Auf GitHub ansehen

Exp Trendintensitätsindex Strategie

Diese Strategie ist eine StockSharp-Konvertierung des MetaTrader-Experten Exp_Trend_Intensity_Index. Sie handelt auf abgeschlossenen Kerzen eines konfigurierbaren Zeitrahmens und verwendet den Trend Intensity Index (TII), um zu erkennen, wenn Momentum extreme bullische oder bärische Zonen verlässt. Wenn der Indikator aus einer oberen Zone herausgeht, schließt der Algorithmus Shorts und kann einen neuen Long starten. Wenn der Indikator eine untere Zone verlässt, schließt der Algorithmus Longs und kann einen neuen Short starten.

Wie der Indikator aufgebaut wird

  1. Die Preisquelle auswählen (close, open, gewichtete Varianten, Trend-Follow-Preise, etc.).
  2. Diesen Preisstrom mit einem ersten gleitenden Durchschnitt glätten (PriceMaMethod, PriceMaLength).
  3. Den Unterschied zwischen Preis und geglättetem Wert in positive und negative Flüsse aufteilen.
  4. Die positiven und negativen Flüsse unabhängig mit einem zweiten gleitenden Durchschnitt glätten (SmoothingMethod, SmoothingLength).
  5. Den Trend Intensity Index berechnen: TII = 100 * Positive / (Positive + Negative).
  6. Das Ergebnis mit den Schwellenwerten HighLevel und LowLevel vergleichen, um einen Farbzustand zuzuweisen: hohe Zone (0), neutral (1) oder niedrige Zone (2).

Die Implementierung verwendet StockSharp-Gleitende Durchschnitte (einfach, exponentiell, geglättet, gewichtet). Erweiterte Glättungstypen aus der ursprünglichen MQL-Bibliothek sind in diesem Port nicht verfügbar.

Handelslogik

  • Signale werden nur verarbeitet, wenn eine Kerze vollständig abgeschlossen ist (CandleStates.Finished).
  • Der Parameter SignalBar definiert, welcher abgeschlossene Balken analysiert wird (Standard: ein Balken zurück). Die Strategie inspiziert auch den unmittelbar davor liegenden Balken, entsprechend der doppelten Puffer-Suche im MQL-Code.
  • Wenn der ältere Balken zur hohen Zone gehört (color == 0):
    • Jede Short-Position schließen, wenn EnableSellExits wahr ist.
    • Wenn der neuere Balken die hohe Zone verlassen hat und EnableBuyEntries wahr ist, eine Long-Position eröffnen oder umkehren.
  • Wenn der ältere Balken zur niedrigen Zone gehört (color == 2):
    • Jede Long-Position schließen, wenn EnableBuyExits wahr ist.
    • Wenn der neuere Balken die niedrige Zone verlassen hat und EnableSellEntries wahr ist, eine Short-Position eröffnen oder umkehren.
  • Orders werden mit BuyMarket und SellMarket eingereicht. Positionsumkehrungen verwenden das aktuelle Positionsvolumen plus die konfigurierte Volume-Eigenschaft.
  • Optionaler Stop-Loss und Take-Profit-Schutz (Preiseinheiten) wird über StopLossPoints und TakeProfitPoints konfiguriert und mit StartProtection implementiert.

Parameter

Parameter Beschreibung
CandleType Zeitrahmen für Indikatorberechnung und Handel.
PriceMaMethod, PriceMaLength Gleitender Durchschnitt-Typ und Periode auf den Basispreisstrom angewendet.
SmoothingMethod, SmoothingLength Gleitender Durchschnitt-Typ und Periode auf die positiven und negativen Flüsse angewendet.
AppliedPrice Preisquelle für den Indikator (close, open, median, Trend-Follow-Varianten, Demark, etc.).
HighLevel, LowLevel Obere und untere Schwellenwerte, die bullische und bärische Zonen definieren.
SignalBar Anzahl abgeschlossener Balken für Signalbestätigung zurückzuschauen.
EnableBuyEntries, EnableSellEntries Umschalter, die das Eröffnen von Long/Short-Positionen erlauben.
EnableBuyExits, EnableSellExits Umschalter, die automatische Ausstiege erlauben, wenn der Indikator wechselt.
StopLossPoints, TakeProfitPoints Optionale Schutzabstände in Preiseinheiten für StartProtection.

Unterschiede zum ursprünglichen MQL-Experten

  • Money-Management-Optionen (MM, MMMode, Deviation) werden durch StockSharp's Standard-Volumen-Eigenschaft und Order-Ausführung ersetzt; Slippage-Management wird nicht repliziert.
  • Nur die in StockSharp verfügbaren Typen von gleitenden Durchschnitten (einfach, exponentiell, geglättet, gewichtet) werden unterstützt.
  • Phasenparameter aus dem MQL-Indikator werden weggelassen, da StockSharp-Indikatoren keine äquivalenten Steuerungen exponieren.
  • Orders werden sofort nach Signalbestätigung auf der abgeschlossenen Kerze ausgeführt; es gibt keine explizite Planung für die nächste Balkeneröffnung.

Diese Änderungen halten die Handelsidee intakt und folgen dabei den StockSharp High-Level-Strategie-Richtlinien.

using System;
using System.Collections.Generic;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// Trend Intensity Index strategy. Uses EMA crossover for trend following.
/// </summary>
public class ExpTrendIntensityIndexStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _fastPeriod;
	private readonly StrategyParam<int> _slowPeriod;

	private decimal? _prevFast;
	private decimal? _prevSlow;

	public DataType CandleType
	{
		get => _candleType.Value;
		set => _candleType.Value = value;
	}

	public int FastPeriod
	{
		get => _fastPeriod.Value;
		set => _fastPeriod.Value = value;
	}

	public int SlowPeriod
	{
		get => _slowPeriod.Value;
		set => _slowPeriod.Value = value;
	}

	public ExpTrendIntensityIndexStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame())
			.SetDisplay("Candle Type", "Timeframe", "General");

		_fastPeriod = Param(nameof(FastPeriod), 10)
			.SetGreaterThanZero()
			.SetDisplay("Fast EMA", "Fast EMA period", "Indicators");

		_slowPeriod = Param(nameof(SlowPeriod), 30)
			.SetGreaterThanZero()
			.SetDisplay("Slow EMA", "Slow EMA period", "Indicators");
	}

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

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

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);

		_prevFast = null;
		_prevSlow = null;

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

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(fast, slow, ProcessCandle)
			.Start();

		var area = CreateChartArea();
		if (area != null)
		{
			DrawCandles(area, subscription);
			DrawIndicator(area, fast);
			DrawIndicator(area, slow);
			DrawOwnTrades(area);
		}
	}

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

		if (!IsFormedAndOnlineAndAllowTrading())
		{
			_prevFast = fastVal;
			_prevSlow = slowVal;
			return;
		}

		if (_prevFast == null || _prevSlow == null)
		{
			_prevFast = fastVal;
			_prevSlow = slowVal;
			return;
		}

		var prevAbove = _prevFast.Value > _prevSlow.Value;
		var currAbove = fastVal > slowVal;

		_prevFast = fastVal;
		_prevSlow = slowVal;

		if (!prevAbove && currAbove && Position <= 0)
		{
			if (Position < 0)
				BuyMarket();
			BuyMarket();
		}
		else if (prevAbove && !currAbove && Position >= 0)
		{
			if (Position > 0)
				SellMarket();
			SellMarket();
		}
	}
}