A estratégia replica o consultor especialista MetaTrader "Exp_SSL_NRTR_Tm_Plus" usando a infraestrutura de alto nível do StockSharp. Ela
assina um único período, calcula o canal SSL NRTR com um método de suavização configurável e reage às transições
de cor fornecidas pelo indicador. As entradas compradas são acionadas quando o canal se torna altista enquanto as entradas vendidas ocorrem em
transições baixistas. A implementação preserva os controles de risco originais, os filtros de operações opcionais e a saída baseada em temporizador.
Parâmetros
Grupo
Parâmetro
Descrição
Trading
Money Management
Fração do portfólio (ou lotes diretos quando negativo/modo Lot) usado para dimensionar ordens.
Trading
Margin Mode
Modo usado para traduzir o valor de gestão de dinheiro em um tamanho de posição. Modos diferentes de Lot são aproximados com cálculos baseados em portfólio.
Trading
Allow Long/Short Entries
Habilitar ou desabilitar a abertura de posições na direção respectiva.
Trading
Allow Long/Short Exits
Permitir que a estratégia feche posições na direção respectiva em reversões do indicador.
Risk
Stop Loss
Distância de stop de proteção em passos de preço. A estratégia monitora os níveis em vez de colocar ordens de stop nativas.
Risk
Take Profit
Distância de take profit em passos de preço.
Risk
Slippage
Parâmetro informacional mantido do EA original.
Risk
Use Time Exit
Habilitar o temporizador que força uma posição plana após o período de manutenção configurado.
Risk
Exit Minutes
Período de manutenção em minutos para a saída baseada em tempo.
Data
Candle Type
Período de trabalho usado tanto para negociação quanto para cálculos do indicador.
Indicator
Smoothing Method
Tipo de média móvel usado pelo canal SSL NRTR. Tipos personalizados não suportados recorrem a uma EMA.
Indicator
Length
Período base do algoritmo de suavização.
Indicator
Phase
Parâmetro auxiliar usado por médias adaptativas (T3, VIDYA, AMA).
Indicator
Signal Bar
Número de barras fechadas para olhar para trás ao avaliar as cores SSL.
Lógica de negociação
Assinar o período configurado e processar apenas velas terminadas.
Calcular as médias móveis SSL NRTR e derivar a cor do canal (para cima, para baixo ou neutro).
Quando a cor muda para altista (0), opcionalmente fechar posições vendidas e, se habilitado, abrir uma posição comprada.
Quando a cor muda para baixista (2), opcionalmente fechar posições compradas e, se habilitado, abrir uma posição vendida.
Rastrear os níveis de stop-loss/take-profit usando o preço de entrada e fechar a posição quando qualquer nível for atingido.
Opcionalmente fechar posições assim que o tempo de manutenção exceder o parâmetro Exit Minutes.
Prevenir entradas repetidas dentro da mesma barra com a lógica do "nível de tempo" original do MT5.
Gestão de dinheiro
O modo Lot trata o valor de gestão de dinheiro como um volume direto expresso em lotes/contratos.
FreeMargin e Balance aproximam a fração de capital solicitada dividindo-a pelo último preço de fechamento.
LossFreeMargin e LossBalance estimam o volume negociável a partir da perda permitida por operação usando a distância de stop-loss configurada.
Valores negativos de gestão de dinheiro sempre mapeiam para um tamanho de lote absoluto.
Notas
Apenas os métodos de suavização disponíveis no StockSharp são implementados diretamente. Jurx e Parma recorrem à média móvel exponencial e esse comportamento está documentado nos comentários do código.
A estratégia mantém a lógica de stop-loss e take-profit dentro do loop da estratégia em vez de enviar ordens de proteção nativas para permanecer agnóstica à plataforma.
O deslizamento é uma configuração informacional mantida para completude; as ordens são enviadas como ordens de mercado simples.
A implementação desenha velas e operações próprias na área do gráfico por padrão.
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()