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
Die Preisquelle auswählen (close, open, gewichtete Varianten, Trend-Follow-Preise, etc.).
Diesen Preisstrom mit einem ersten gleitenden Durchschnitt glätten (PriceMaMethod, PriceMaLength).
Den Unterschied zwischen Preis und geglättetem Wert in positive und negative Flüsse aufteilen.
Die positiven und negativen Flüsse unabhängig mit einem zweiten gleitenden Durchschnitt glätten (SmoothingMethod, SmoothingLength).
Den Trend Intensity Index berechnen: TII = 100 * Positive / (Positive + Negative).
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();
}
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
class exp_trend_intensity_index_strategy(Strategy):
def __init__(self):
super(exp_trend_intensity_index_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(1))) \
.SetDisplay("Candle Type", "Timeframe", "General")
self._fast_period = self.Param("FastPeriod", 10) \
.SetDisplay("Fast EMA", "Fast EMA period", "Indicators")
self._slow_period = self.Param("SlowPeriod", 30) \
.SetDisplay("Slow EMA", "Slow EMA period", "Indicators")
self._prev_fast = None
self._prev_slow = None
@property
def CandleType(self):
return self._candle_type.Value
@property
def FastPeriod(self):
return self._fast_period.Value
@property
def SlowPeriod(self):
return self._slow_period.Value
def OnReseted(self):
super(exp_trend_intensity_index_strategy, self).OnReseted()
self._prev_fast = None
self._prev_slow = None
def OnStarted2(self, time):
super(exp_trend_intensity_index_strategy, self).OnStarted2(time)
self._prev_fast = None
self._prev_slow = None
fast = ExponentialMovingAverage()
fast.Length = self.FastPeriod
slow = ExponentialMovingAverage()
slow.Length = self.SlowPeriod
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(fast, slow, self._on_process).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, fast)
self.DrawIndicator(area, slow)
self.DrawOwnTrades(area)
def _on_process(self, candle, fast_value, slow_value):
if candle.State != CandleStates.Finished:
return
fv = float(fast_value)
sv = float(slow_value)
if self._prev_fast is None or self._prev_slow is None:
self._prev_fast = fv
self._prev_slow = sv
return
prev_above = self._prev_fast > self._prev_slow
curr_above = fv > sv
self._prev_fast = fv
self._prev_slow = sv
if not prev_above and curr_above and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
elif prev_above and not curr_above and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
def CreateClone(self):
return exp_trend_intensity_index_strategy()