Открыть на GitHub

Стратегия Exp Skyscraper Fix ColorAML

Обзор

Стратегия переносит логику экспертного советника MetaTrader 5 Exp_Skyscraper_Fix_ColorAML в инфраструктуру StockSharp. Она объединяет два независимых модуля сигналов:

  1. Skyscraper Fix – ATR-подобный канал, который окрашивает бычий или медвежий режим в зависимости от направления адаптивных границ.
  2. ColorAML – адаптивный индикатор рыночных уровней, сравнивающий локальные фрактальные диапазоны и определяющий фазы расширения либо сжатия.

Оригинальная MQL-версия работала с двумя magic-числами и могла удерживать хеджированные позиции. StockSharp ведёт единую чистую позицию, поэтому противоречивые сигналы взаимно компенсируются, а текущее направление определяется последним входом. В README подчёркнуты отличия, чтобы пользователи учитывали их при тестировании и реальной работе.

Параметры

Модуль Skyscraper Fix

  • SkyscraperCandleType – таймфрейм для построения индикатора. По умолчанию 4h.
  • SkyscraperEnableLongEntry / SkyscraperEnableShortEntry – разрешение на открытие длинных или коротких позиций.
  • SkyscraperEnableLongExit / SkyscraperEnableShortExit – разрешение на закрытие существующих позиций соответствующего направления.
  • SkyscraperLength – число выборок ATR для расчёта шага лестницы. По умолчанию 10.
  • SkyscraperMultiplier – коэффициент, умножаемый на ATR. По умолчанию 0.9.
  • SkyscraperPercentage – дополнительное процентное смещение средней линии (0 отключает смещение).
  • SkyscraperMode – выбор между расчётом по High/Low или по Close.
  • SkyscraperSignalBar – количество завершённых свечей для анализа цветового буфера. Минимум 1.
  • SkyscraperVolume – объём рыночного ордера при входе.
  • SkyscraperStopLoss / SkyscraperTakeProfit – расстояния до стоп-лосса и тейк-профита в шагах цены.

Модуль ColorAML

  • ColorAmlCandleType – таймфрейм для ColorAML. По умолчанию 4h.
  • ColorAmlEnableLongEntry / ColorAmlEnableShortEntry – разрешение на открытие длинных или коротких позиций.
  • ColorAmlEnableLongExit / ColorAmlEnableShortExit – разрешение на закрытие текущих позиций.
  • ColorAmlFractal – длина фрактального диапазона. По умолчанию 6.
  • ColorAmlLag – параметр лагового сглаживания. По умолчанию 7.
  • ColorAmlSignalBar – количество завершённых свечей для чтения цветового буфера.
  • ColorAmlVolume – объём ордера для модулей ColorAML.
  • ColorAmlStopLoss / ColorAmlTakeProfit – защитные расстояния в шагах цены.

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

Стратегия подписывается на выбранные свечи каждого модуля и работает только с завершёнными барами. Оба индикатора реализованы на C# и повторяют математические формулы из MQL:

  • Skyscraper Fix формирует канал, похожий на SuperTrend. При появлении цвета 0 модуль закрывает шорты (если разрешено) и, когда предыдущий цвет отличался, готовит вход в лонг. Цвет 1 закрывает лонги и инициирует шорт.
  • ColorAML сравнивает фрактальные диапазоны. Цвет 2 указывает на бычью фазу: модуль закрывает шорты и может открыть лонг. Цвет 0 сигнализирует медвежью фазу: закрываются лонги и при необходимости открываются шорты. Нейтральный цвет 1 сохраняет позицию.

Каждый вход отправляет рыночный ордер объёмом НастроенныйОбъём + |текущая позиция|, что позволяет одновременно закрыть противоположное плечо и развернуться в условиях неттинга.

Управление рисками

При старте вызывается StartProtection(). Когда модуль открывает позицию, стратегия запоминает цену входа и рассчитывает уровни стоп-лосса и тейк-профита исходя из параметров модуля. В последующих свечах закрытие происходит, если максимум или минимум бара достигает заданных уровней. Нулевые значения отключают автоматическую защиту.

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

  • Расчёты Skyscraper Fix и ColorAML перенесены напрямую и выполняются во внутренних буферах, дополнительные индикаторы подключать не требуется.
  • StockSharp ведёт единую позицию, поэтому одновременные лонг и шорт из оригинального советника взаимно сокращаются. Пользователям, привыкшим к хеджированию, стоит учитывать это отличие.
  • Обрабатываются только закрытые свечи. Значение SignalBar должно быть не меньше 1; интрабарная обработка не реализована.
  • Защитные уровни отслеживаются по экстремумам свечей, что соответствует возможностям данного фреймворка.

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

  1. Привяжите стратегию к нужному инструменту и счёту.
  2. Настройте параметры обоих модулей, убедившись, что необходимые таймфреймы доступны.
  3. Запустите стратегию – она подпишется на свечи, вычислит цвета индикаторов и начнёт размещать рыночные заявки.
  4. Следите за логами или графиками, чтобы контролировать смену режимов, срабатывание защитных уровней и совершённые сделки.
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 ExpSkyscraperFixColorAmlStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _period;
	private decimal? _prevDm;

	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
	public int Period { get => _period.Value; set => _period.Value = value; }

	public ExpSkyscraperFixColorAmlStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame()).SetDisplay("Candle Type", "Timeframe", "General");
		_period = Param(nameof(Period), 14).SetGreaterThanZero().SetDisplay("DeMarker Period", "DeMarker lookback", "Indicators");
	}

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

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

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_prevDm = null;
		var dm = new DeMarker { Length = Period };
		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(dm, ProcessCandle).Start();
		var area = CreateChartArea();
		if (area != null) { DrawCandles(area, subscription); DrawOwnTrades(area); }
	}

	private void ProcessCandle(ICandleMessage candle, decimal dmVal)
	{
		if (candle.State != CandleStates.Finished) return;
		if (!IsFormedAndOnlineAndAllowTrading()) { _prevDm = dmVal; return; }
		if (_prevDm == null) { _prevDm = dmVal; return; }
		if (_prevDm.Value < 0.45m && dmVal >= 0.55m && Position <= 0) { if (Position < 0) BuyMarket(); BuyMarket(); }
		else if (_prevDm.Value > 0.55m && dmVal <= 0.45m && Position >= 0) { if (Position > 0) SellMarket(); SellMarket(); }
		_prevDm = dmVal;
	}
}