La estrategia replica el asesor experto de MetaTrader "Exp_SSL_NRTR_Tm_Plus" usando la infraestructura de alto nivel de StockSharp. Se
suscribe a un solo marco temporal, calcula el canal SSL NRTR con un método de suavizado configurable y reacciona a las transiciones
de color proporcionadas por el indicador. Las entradas largas se activan cuando el canal se vuelve alcista mientras que las entradas cortas
ocurren en transiciones bajistas. La implementación preserva los controles de riesgo originales, los filtros de operaciones opcionales y la salida basada en temporizador.
Parámetros
Grupo
Parámetro
Descripción
Trading
Money Management
Fracción del portafolio (o lotes directos cuando es negativo/modo Lot) usada para dimensionar órdenes.
Trading
Margin Mode
Modo usado para traducir el valor de gestión de dinero a un tamaño de posición. Los modos distintos de Lot se aproximan con cálculos basados en el portafolio.
Trading
Allow Long/Short Entries
Habilitar o deshabilitar la apertura de posiciones en la dirección respectiva.
Trading
Allow Long/Short Exits
Permitir a la estrategia cerrar posiciones en la dirección respectiva en reversiones del indicador.
Risk
Stop Loss
Distancia de stop protector en pasos de precio. La estrategia monitorea los niveles en lugar de colocar órdenes de stop nativas.
Risk
Take Profit
Distancia de take profit en pasos de precio.
Risk
Slippage
Parámetro informacional mantenido del EA original.
Risk
Use Time Exit
Habilitar el temporizador que fuerza una posición plana tras el período de mantenimiento configurado.
Risk
Exit Minutes
Período de mantenimiento en minutos para la salida basada en tiempo.
Data
Candle Type
Marco temporal de trabajo usado tanto para trading como para cálculos del indicador.
Indicator
Smoothing Method
Tipo de media móvil usado por el canal SSL NRTR. Los tipos personalizados no soportados recurren a una EMA.
Indicator
Length
Período base del algoritmo de suavizado.
Indicator
Phase
Parámetro auxiliar usado por promedios adaptativos (T3, VIDYA, AMA).
Indicator
Signal Bar
Número de barras cerradas hacia atrás al evaluar los colores SSL.
Lógica de trading
Suscribirse al marco temporal configurado y procesar solo las velas terminadas.
Calcular las medias móviles SSL NRTR y derivar el color del canal (arriba, abajo o neutral).
Cuando el color cambia a alcista (0), opcionalmente cerrar posiciones cortas y, si está habilitado, abrir una posición larga.
Cuando el color cambia a bajista (2), opcionalmente cerrar posiciones largas y, si está habilitado, abrir una posición corta.
Rastrear los niveles de stop-loss/take-profit usando el precio de entrada y cerrar la posición cuando se alcance cualquier nivel.
Opcionalmente cerrar posiciones una vez que el tiempo de mantenimiento supere el parámetro Exit Minutes.
Prevenir entradas repetidas dentro de la misma barra con la lógica del "nivel de tiempo" original de MT5.
Gestión de dinero
El modo Lot trata el valor de gestión de dinero como un volumen directo expresado en lotes/contratos.
FreeMargin y Balance aproximan la fracción de capital solicitada dividiéndola por el último precio de cierre.
LossFreeMargin y LossBalance estiman el volumen negociable a partir de la pérdida permitida por operación usando la distancia de stop-loss configurada.
Los valores negativos de gestión de dinero siempre se asignan a un tamaño de lote absoluto.
Notas
Solo los métodos de suavizado disponibles en StockSharp se implementan directamente. Jurx y Parma recurren a la media móvil exponencial y este comportamiento está documentado en comentarios del código.
La estrategia mantiene la lógica de stop-loss y take-profit dentro del bucle de la estrategia en lugar de enviar órdenes de protección nativas para mantenerse agnóstica a la plataforma.
El deslizamiento es un parámetro informacional mantenido para completitud; las órdenes se envían como órdenes de mercado simples.
La implementación dibuja velas y operaciones propias en el área del gráfico por defecto.
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()