Открыть на GitHub

Стратегия Exp Skyscraper Fix Color AML MMRec

Exp Skyscraper Fix Color AML MMRec — порт эксперта MQL5 Exp_Skyscraper_Fix_ColorAML_MMRec на платформу StockSharp. Исходный робот сочетает два независимых индикатора — Skyscraper Fix и Color AML — и применяет модель MMRec, уменьшая объём позиции после серии убыточных сделок. Реализация на C# сохраняет оба источника сигналов и адаптивное управление размером позиции, используя высокоуровневый API StockSharp для работы с заявками.

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

  1. Модуль Skyscraper Fix строит адаптивный канал по закрытым свечам типа SkyscraperCandleType. Когда цвет канала становится бирюзовым (тренд > 0), короткие позиции закрываются, а если предыдущий задержанный цвет отличался от бирюзового, открывается новая длинная позиция. При переходе цвета в красный (тренд < 0) логика зеркально отрабатывает для коротких сделок. Используется уже готовый SkyscraperFixIndicator из стратегии 3040_Exp_Skyscraper_Fix_Duplex.
  2. Модуль Color AML анализирует свечи ColorAmlCandleType. Переписанный ColorAmlIndicator воспроизводит адаптивный рыночный уровень и выдаёт код цвета: 2 (бычий), 0 (медвежий) или 1 (нейтральный). Модуль всегда закрывает позицию противоположного направления и, если цвет изменился относительно предыдущего задержанного значения, открывает новую сделку по тренду.
  3. Задержка сигналов настраивается параметрами SkyscraperSignalBar и ColorAmlSignalBar. Стратегия хранит очереди значений индикаторов и исполняет сигнал только после указанного количества полностью сформированных свечей, что соответствует вызовам CopyBuffer(..., shift, ...) в MQL5.
  4. Риск-менеджмент повторяет исходные расстояния стоп-лосса и тейк-профита. Каждый модуль задаёт защитные уровни в шагах цены (тик). Стратегия преобразует их в абсолютные цены и на каждой закрытой свече проверяет, достиг ли диапазон бара стопа или цели. При срабатывании позиция закрывается рыночной заявкой, а уровни защиты очищаются.
  5. MMRec ведёт независимый учёт серий убытков для четырёх направлений: длинные и короткие сделки Skyscraper, длинные и короткие сделки Color AML. Когда серия по направлению достигает порога *LossTrigger, объём уменьшается с *Mm до *SmallMm. После прибыльной сделки счётчик обнуляется. В условиях единой неттинговой позиции в StockSharp практически задействован только режим Lot; остальные режимы сводятся к прямому заданию объёма.

Особенности реализации

  • Стратегия опирается исключительно на высокоуровневый API StockSharp: свечные подписки питают индикаторы, а торговые решения исполняются методами BuyMarket, SellMarket и ClosePosition.
  • Защитные уровни реализованы через рыночное закрытие, без выставления отдельных стоп/лимит заявок, чтобы избежать конфликтов между модулями.
  • Подсчёт серий убытков выполняется в обработчике OnOwnTradeReceived. Модуль, открывший позицию, фиксируется и при её закрытии обновляет свой счётчик.
  • Индикатор ColorAmlIndicator кэширует свечи и значения сглаживания, повторяя оригинальную экспоненциальную фильтрацию с динамическим коэффициентом и цветовым кодированием (синий — рост AML, красный — падение, серый — нейтрально).
  • Магические номера и параметр проскальзывания из MQL5 не используются в портированной версии.

Параметры

Модуль Skyscraper Fix

Параметр Значение по умолчанию Описание
SkyscraperCandleType H4 Таймфрейм для расчёта канала Skyscraper Fix.
SkyscraperLength 10 Длина окна ATR при расчёте шага канала.
SkyscraperKv 0.9 Множитель, задающий чувствительность шага.
SkyscraperPercentage 0 Процентное смещение срединной линии.
SkyscraperMode HighLow Источник цены для построения канала (high/low или close).
SkyscraperSignalBar 1 Количество закрытых свечей, на которое откладывается сигнал.
SkyscraperEnableLongEntry true Разрешить входы в лонг при бычьем канале.
SkyscraperEnableShortEntry true Разрешить входы в шорт при медвежьем канале.
SkyscraperEnableLongExit true Закрывать длинные позиции при медвежьем сигнале.
SkyscraperEnableShortExit true Закрывать короткие позиции при бычьем сигнале.
SkyscraperBuyLossTrigger 2 Количество убыточных лонгов подряд для включения уменьшенного объёма.
SkyscraperSellLossTrigger 2 Количество убыточных шортов подряд для включения уменьшенного объёма.
SkyscraperSmallMm 0.01 Объём сделки после срабатывания триггера убытков.
SkyscraperMm 0.1 Базовый объём сделок Skyscraper.
SkyscraperMmMode Lot Режим управления капиталом (в порте фактически используется только Lot).
SkyscraperStopLossTicks 1000 Стоп-лосс в шагах цены, 0 — отключено.
SkyscraperTakeProfitTicks 2000 Тейк-профит в шагах цены, 0 — отключено.

Модуль Color AML

Параметр Значение по умолчанию Описание
ColorAmlCandleType H4 Таймфрейм для расчёта Color AML.
ColorAmlFractal 6 Период фрактала при оценке диапазона.
ColorAmlLag 7 Глубина сглаживания AML.
ColorAmlSignalBar 1 Задержка сигналов Color AML в закрытых свечах.
ColorAmlEnableLongEntry true Разрешить лонги при цвете 2 (бычий).
ColorAmlEnableShortEntry true Разрешить шорты при цвете 0 (медвежий).
ColorAmlEnableLongExit true Закрывать лонги при медвежьем цвете.
ColorAmlEnableShortExit true Закрывать шорты при бычьем цвете.
ColorAmlBuyLossTrigger 2 Порог убыточных лонгов для уменьшения объёма.
ColorAmlSellLossTrigger 2 Порог убыточных шортов для уменьшения объёма.
ColorAmlSmallMm 0.01 Объём сделки после срабатывания триггера.
ColorAmlMm 0.1 Базовый объём сделок Color AML.
ColorAmlMmMode Lot Режим управления капиталом (в порте фактически используется только Lot).
ColorAmlStopLossTicks 1000 Стоп-лосс в шагах цены, 0 — отключено.
ColorAmlTakeProfitTicks 2000 Тейк-профит в шагах цены, 0 — отключено.

Использование

  1. Подключите стратегию к нужному портфелю и инструменту. Инструмент должен предоставлять свечи с таймфреймами SkyscraperCandleType и ColorAmlCandleType.
  2. При необходимости скорректируйте параметры объёма под шаг контракта брокера. В портированной версии объём задаётся напрямую через *Mm и *SmallMm.
  3. Настройте расстояния стоп-лосса и тейк-профита (в тиках) для каждого модуля, установите 0, чтобы отключить защиту.
  4. Запустите стратегию. Она подпишется на обе свечные серии, рассчитает индикаторы и будет автоматически управлять позициями по описанным правилам.

Данный файл описывает реализацию CS/ExpSkyscraperFixColorAmlMmrecStrategy.cs и служит справочной документацией по использованию стратегии в StockSharp.

namespace StockSharp.Samples.Strategies;

using System;
using System.Collections.Generic;

using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;

public class ExpSkyscraperFixColorAmlMmrecStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _trendPeriod;
	private readonly StrategyParam<int> _filterPeriod;
	private readonly StrategyParam<decimal> _upperLevel;
	private readonly StrategyParam<decimal> _lowerLevel;

	private decimal? _previousTrend;
	private decimal? _previousClose;

	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
	public int TrendPeriod { get => _trendPeriod.Value; set => _trendPeriod.Value = value; }
	public int FilterPeriod { get => _filterPeriod.Value; set => _filterPeriod.Value = value; }
	public decimal UpperLevel { get => _upperLevel.Value; set => _upperLevel.Value = value; }
	public decimal LowerLevel { get => _lowerLevel.Value; set => _lowerLevel.Value = value; }

	public ExpSkyscraperFixColorAmlMmrecStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame()).SetDisplay("Candle Type", "Timeframe", "General");
		_trendPeriod = Param(nameof(TrendPeriod), 18).SetGreaterThanZero().SetDisplay("Trend Period", "Trend WMA period", "Indicators");
		_filterPeriod = Param(nameof(FilterPeriod), 12).SetGreaterThanZero().SetDisplay("Filter Period", "DeMarker period", "Indicators");
		_upperLevel = Param(nameof(UpperLevel), 0.55m).SetDisplay("Upper Level", "Buy filter level", "Signals");
		_lowerLevel = Param(nameof(LowerLevel), 0.45m).SetDisplay("Lower Level", "Sell filter level", "Signals");
	}

	public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities() => [(Security, CandleType)];

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_previousTrend = null;
		_previousClose = null;
	}

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_previousTrend = null;
		_previousClose = null;

		var trend = new WeightedMovingAverage { Length = TrendPeriod };
		var filter = new DeMarker { Length = FilterPeriod };
		var subscription = SubscribeCandles(CandleType);

		subscription.Bind(trend, filter, ProcessCandle).Start();
	}

	private void ProcessCandle(ICandleMessage candle, decimal trendValue, decimal filterValue)
	{
		if (candle.State != CandleStates.Finished)
			return;

		var previousClose = _previousClose;
		var previousTrend = _previousTrend;

		_previousClose = candle.ClosePrice;
		_previousTrend = trendValue;

		if (!IsFormedAndOnlineAndAllowTrading())
			return;

		if (previousClose is null || previousTrend is null)
			return;

		var crossedUp = previousClose.Value <= previousTrend.Value && candle.ClosePrice > trendValue;
		var crossedDown = previousClose.Value >= previousTrend.Value && candle.ClosePrice < trendValue;
		var buySignal = crossedUp && filterValue >= UpperLevel;
		var sellSignal = crossedDown && filterValue <= LowerLevel;

		if (buySignal && Position <= 0)
		{
			if (Position < 0)
			{
				BuyMarket();
				return;
			}

			BuyMarket();
		}
		else if (sellSignal && Position >= 0)
		{
			if (Position > 0)
			{
				SellMarket();
				return;
			}

			SellMarket();
		}
	}
}