Открыть на GitHub

Стратегия Exp SSL NRTR Tm Plus

Обзор

Стратегия воспроизводит работу советника MetaTrader "Exp_SSL_NRTR_Tm_Plus" в инфраструктуре StockSharp. Используется одна таймфреймная подписка, рассчитывается канал SSL NRTR с настраиваемым методом сглаживания, и торговые решения принимаются по смене его цвета. Лонг открывается при переходе канала в бычье состояние, шорт — при медвежьем сигнале. Сохраняются исходные фильтры, стоп-параметры и таймер принудительного выхода.

Параметры

Группа Параметр Описание
Trading Money Management Доля капитала (или прямой размер позиции при отрицательном значении/режиме Lot).
Trading Margin Mode Способ преобразования значения Money Management в объём заявки. Режимы отличные от Lot приближённо рассчитываются по стоимости портфеля.
Trading Allow Long/Short Entries Разрешение на открытие позиций в соответствующем направлении.
Trading Allow Long/Short Exits Разрешение на закрытие позиций по сигналу в соответствующем направлении.
Risk Stop Loss Дистанция стоп-лосса в ценовых шагах (контролируется внутри стратегии).
Risk Take Profit Дистанция тейк-профита в ценовых шагах.
Risk Slippage Информационный параметр из оригинального советника.
Risk Use Time Exit Включить таймер принудительного закрытия позиции.
Risk Exit Minutes Время удержания позиции в минутах.
Data Candle Type Рабочий таймфрейм для расчётов и торговли.
Indicator Smoothing Method Метод сглаживания SSL NRTR. Неподдерживаемые методы автоматически заменяются на EMA.
Indicator Length Базовый период сглаживания.
Indicator Phase Вспомогательный параметр адаптивных усреднений (T3, VIDYA, AMA).
Indicator Signal Bar Количество закрытых баров для анализа сигнала.

Логика торговли

  1. Подписка на свечи выбранного таймфрейма и обработка только закрытых баров.
  2. Расчёт скользящих средних SSL NRTR и определение текущего цвета канала.
  3. При смене цвета на бычий (0) — опциональное закрытие шорта и открытие лонга при разрешении.
  4. При смене цвета на медвежий (2) — опциональное закрытие лонга и открытие шорта при разрешении.
  5. Контроль стоп-лосса/тейк-профита относительно цены входа и закрытие позиции при достижении уровней.
  6. При включенном таймере позиция закрывается по истечении Exit Minutes.
  7. Защита от повторных входов на одной свече с помощью «временного уровня», как в оригинальном советнике.

Управление капиталом

  • Режим Lot трактует Money Management как прямой размер позиции в лотах/контрактах.
  • FreeMargin и Balance приближённо делят выделенную сумму на текущую цену инструмента.
  • LossFreeMargin и LossBalance рассчитывают объём исходя из допустимого убытка по стоп-лоссу.
  • Отрицательные значения Money Management всегда конвертируются в абсолютный размер позиции.

Примечания

  • Реализованы только методы сглаживания, доступные в StockSharp. Для Jurx и Parma используется замена на экспоненциальное усреднение (указано в комментариях к коду).
  • Стоп-лосс и тейк-профит контролируются внутри стратегии, что обеспечивает независимость от типа подключения.
  • Параметр Slippage носит исключительно информационный характер — заявки отправляются как рыночные.
  • На графике по умолчанию отображаются свечи и собственные сделки.
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(); }
	}
}