This strategy is a StockSharp conversion of the MetaTrader expert Exp_Trend_Intensity_Index. It trades finished candles on a configurable timeframe and uses the Trend Intensity Index (TII) to detect when momentum leaves extreme bullish or bearish zones. When the indicator transitions out of an upper zone the algorithm exits shorts and can start a new long. When the indicator leaves a lower zone the algorithm closes longs and can start a new short.
Compare the result with the HighLevel and LowLevel thresholds to assign a color state: high zone (0), neutral (1), or low zone (2).
The implementation uses StockSharp moving averages (simple, exponential, smoothed, weighted). Advanced smoothing types from the original MQL library are not available in this port.
Trading logic
Signals are processed only when a candle is fully closed (CandleStates.Finished).
The SignalBar parameter defines which completed bar is analysed (default one bar back). The strategy also inspects the bar immediately before that, matching the double-buffer lookup in the MQL code.
When the older bar belongs to the high zone (color == 0):
Close any short position if EnableSellExits is true.
If the more recent bar left the high zone and EnableBuyEntries is true, open or reverse into a long.
When the older bar belongs to the low zone (color == 2):
Close any long position if EnableBuyExits is true.
If the more recent bar left the low zone and EnableSellEntries is true, open or reverse into a short.
Orders are submitted with BuyMarket and SellMarket. Position reversals use the current position volume plus the configured Volume property.
Optional stop-loss and take-profit protection (price units) is configured through StopLossPoints and TakeProfitPoints and implemented with StartProtection.
Parameters
Parameter
Description
CandleType
Timeframe used for indicator calculation and trading.
PriceMaMethod, PriceMaLength
Moving average type and period applied to the base price stream.
SmoothingMethod, SmoothingLength
Moving average type and period applied to the positive and negative flows.
AppliedPrice
Price source for the indicator (close, open, median, trend-follow variants, Demark, etc.).
HighLevel, LowLevel
Upper and lower thresholds that define bullish and bearish zones.
SignalBar
Number of completed bars to look back for signal confirmation.
EnableBuyEntries, EnableSellEntries
Toggles that allow opening long/short positions.
EnableBuyExits, EnableSellExits
Toggles that allow automatic exits when the indicator flips.
StopLossPoints, TakeProfitPoints
Optional protective distances expressed in price units for StartProtection.
Differences from the original MQL expert
Money-management options (MM, MMMode, Deviation) are replaced with StockSharp's standard volume property and order execution; slippage management is not replicated.
Only the moving average types available in StockSharp (simple, exponential, smoothed, weighted) are supported.
Phase parameters from the MQL indicator are omitted because StockSharp indicators do not expose equivalent controls.
Orders are executed immediately after a signal is confirmed on the finished candle; there is no explicit scheduling for the next bar opening.
These changes keep the trading idea intact while following StockSharp high-level strategy guidelines.
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()