The strategy replicates the MetaTrader expert advisor "Exp_SSL_NRTR_Tm_Plus" using StockSharp high level infrastructure. It
subscribes to a single timeframe, calculates the SSL NRTR channel with a configurable smoothing method and reacts to the color
transitions provided by the indicator. Long entries are triggered when the channel turns bullish while short entries occur on
bearish transitions. The implementation preserves the original risk controls, optional trade filters and the timer-based exit.
Parameters
Group
Parameter
Description
Trading
Money Management
Fraction of the portfolio (or direct lots when negative/Lot mode) used to size orders.
Trading
Margin Mode
Mode used to translate the money management value into a position size. Modes other than Lot are approximated with portfolio-based calculations.
Trading
Allow Long/Short Entries
Enable or disable opening positions in the respective direction.
Trading
Allow Long/Short Exits
Allow the strategy to close positions in the respective direction on indicator reversals.
Risk
Stop Loss
Protective stop distance in price steps. The strategy monitors the levels instead of placing native stop orders.
Risk
Take Profit
Take profit distance in price steps.
Risk
Slippage
Informational parameter kept from the original EA.
Risk
Use Time Exit
Enable the timer that forces a flat position after the configured holding period.
Risk
Exit Minutes
Holding period in minutes for the time-based exit.
Data
Candle Type
Working timeframe used for both trading and indicator calculations.
Indicator
Smoothing Method
Moving-average type used by the SSL NRTR channel. Unsupported custom types fall back to an EMA.
Indicator
Length
Base period of the smoothing algorithm.
Indicator
Phase
Auxiliary parameter used by adaptive averages (T3, VIDYA, AMA).
Indicator
Signal Bar
Number of closed bars to look back when evaluating SSL colors.
Trading Logic
Subscribe to the configured timeframe and process only finished candles.
Calculate the SSL NRTR moving averages and derive the channel color (up, down or neutral).
When the color switches to bullish (0), optionally close short positions and, if enabled, open a long position.
When the color switches to bearish (2), optionally close long positions and, if enabled, open a short position.
Track stop-loss/take-profit levels using the entry price and close the position when either level is reached.
Optionally close positions once the holding time exceeds the Exit Minutes parameter.
Prevent repeated entries within the same bar by throttling with the original MT5 "time level" logic.
Money Management
Lot mode treats the money management value as a direct volume expressed in lots/contracts.
FreeMargin and Balance approximate the requested capital fraction by dividing it by the latest close price.
LossFreeMargin and LossBalance estimate the tradable volume from the allowed loss per trade using the configured stop-loss distance.
Negative money management values always map to an absolute lot size.
Notes
Only the smoothing methods available in StockSharp are implemented directly. Jurx and Parma fall back to the exponential moving average and this behaviour is documented in code comments.
The strategy keeps stop-loss and take-profit logic inside the strategy loop instead of sending native protective orders to stay platform agnostic.
Slippage is an informational setting retained for completeness; orders are sent as plain market orders.
The implementation draws candles and own trades on the chart area by default.
using System;
using System.Collections.Generic;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
public class ExpSslNrtrTmPlusStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _fastPeriod;
private readonly StrategyParam<int> _slowPeriod;
private decimal? _prevFast, _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 ExpSslNrtrTmPlusStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame()).SetDisplay("Candle Type", "Timeframe", "General");
_fastPeriod = Param(nameof(FastPeriod), 10).SetGreaterThanZero().SetDisplay("Fast EMA", "Fast period", "Indicators");
_slowPeriod = Param(nameof(SlowPeriod), 30).SetGreaterThanZero().SetDisplay("Slow EMA", "Slow period", "Indicators");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities() => [(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 fast, decimal slow)
{
if (candle.State != CandleStates.Finished) return;
if (!IsFormedAndOnlineAndAllowTrading()) { _prevFast = fast; _prevSlow = slow; return; }
if (_prevFast == null || _prevSlow == null) { _prevFast = fast; _prevSlow = slow; return; }
var prevAbove = _prevFast.Value > _prevSlow.Value;
var currAbove = fast > slow;
_prevFast = fast; _prevSlow = slow;
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_ssl_nrtr_tm_plus_strategy(Strategy):
def __init__(self):
super(exp_ssl_nrtr_tm_plus_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 period", "Indicators")
self._slow_period = self.Param("SlowPeriod", 30) \
.SetDisplay("Slow EMA", "Slow 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_ssl_nrtr_tm_plus_strategy, self).OnReseted()
self._prev_fast = None
self._prev_slow = None
def OnStarted2(self, time):
super(exp_ssl_nrtr_tm_plus_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_ssl_nrtr_tm_plus_strategy()