Открыть на GitHub

Стратегия Alerting System — это аккуратная конверсия советника MetaTrader 4 AlertingSystem.mq4 в экосистему StockSharp. В оригинале пользователь размещает две горизонтальные линии и получает звуковой сигнал при касании цены. StockSharp-вариант реализует тот же алгоритм: подписывается на поток котировок Level1 (лучший бид/аск) и записывает сообщения в журнал при пересечении заданных уровней.

Основная идея

  1. Подписаться на Level1, чтобы стратегия получала обновления бида и аска на каждом тике — аналог обработчика OnTick в MQL4.
  2. Прочитать значения параметров UpperPrice и LowerPrice. Ноль отключает соответствующее оповещение, что совпадает с удалением линии в MetaTrader.
  3. Сравнивать каждый входящий бид с верхним уровнем и каждый аск с нижним уровнем.
  4. При пробое активного уровня сформировать единственное уведомление и ждать, пока рынок вернётся обратно, прежде чем повторно «взводить» оповещение. Такой подход сохраняет смысл исходного сигнала, но предотвращает лавину одинаковых записей.

Параметры

Имя Значение по умолчанию Описание
UpperPrice 0 Верхний горизонтальный уровень оповещения. Значение 0 отключает проверку.
LowerPrice 0 Нижний горизонтальный уровень оповещения. Значение 0 отключает проверку.

Оба параметра доступны в интерфейсе Designer. Их можно менять до запуска и во время работы — следующая котировка сразу использует новые уровни.

Поведение во время работы

  • Подписка на данные: метод GetWorkingSecurities запрашивает Level1, поэтому стратегия получает котировки даже без свечей и сделок.
  • Инициализация: при срабатывании OnStarted стратегия записывает в журнал актуальные уровни, чтобы оператор подтвердил настройки.
  • Выявление пробоев: вспомогательные методы (CheckUpperAlert и CheckLowerAlert) хранят внутренние флаги и гарантируют, что каждое пересечение даёт ровно одно уведомление до возврата цены.
  • Отсутствие торговли: в конверсии нет ордеров — это чистый инструмент мониторинга, полностью повторяющий советника, который лишь воспроизводил звук.
  • Сброс: OnReseted очищает внутренние флаги, обеспечивая «чистый» старт при следующем запуске.

Типичный сценарий использования

  1. Выберите нужный инструмент в StockSharp Designer и подключите AlertingSystemStrategy.
  2. Задайте верхний и/или нижний уровни. Оставьте 0, если сторона не нужна.
  3. Запустите стратегию. В журнале появятся записи с подтверждением активных оповещений.
  4. Следите за журналом: при пробое верхнего уровня бидом или нижнего уровня аском стратегия создаёт информативное сообщение.

Особенности конверсии

  • В MetaTrader линии можно было перетаскивать мышью. В StockSharp используются числовые параметры, что делает процесс воспроизводимым и удобным для алгоритмической среды.
  • Оригинал вызывал PlaySound на каждом подходящем тике. Конверсия добавляет «антидребезг» и ждёт возврата цены, чтобы не засорять журнал дубликатами.
  • Логика не использует индикаторы и работает только на котировках, поэтому подходит для любых инструментов с доступом к Level1.

Классификация

  • Категория: Утилиты / Оповещения
  • Торговое направление: Нет
  • Стиль исполнения: Событийный мониторинг
  • Требуемые данные: Level1 (bid/ask)
  • Сложность: Базовая
  • Рекомендуемый таймфрейм: Любой (котировки)
  • Управление рисками: Не применяется (сделки не совершаются)

Этот документ описывает реализацию на StockSharp и показывает, как воспроизвести рабочий процесс MetaTrader в рамках платформы.

namespace StockSharp.Samples.Strategies;

using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;

/// <summary>
/// Alerting System strategy: Bollinger Band breakout.
/// Buys when price crosses above upper band, sells when below lower band.
/// </summary>
public class AlertingSystemStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _bbPeriod;
	private readonly StrategyParam<decimal> _bbWidth;

	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
	public int BbPeriod { get => _bbPeriod.Value; set => _bbPeriod.Value = value; }
	public decimal BbWidth { get => _bbWidth.Value; set => _bbWidth.Value = value; }

	public AlertingSystemStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
			.SetDisplay("Candle Type", "Candle timeframe", "General");
		_bbPeriod = Param(nameof(BbPeriod), 20)
			.SetGreaterThanZero()
			.SetDisplay("BB Period", "Bollinger Bands period", "Indicators");
		_bbWidth = Param(nameof(BbWidth), 2m)
			.SetDisplay("BB Width", "Bollinger Bands width multiplier", "Indicators");
	}

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		var bb = new BollingerBands
		{
			Length = BbPeriod,
			Width = BbWidth
		};
		var subscription = SubscribeCandles(CandleType);
		subscription.BindEx(bb, ProcessCandle).Start();
	}

	private void ProcessCandle(ICandleMessage candle, IIndicatorValue bbValue)
	{
		if (candle.State != CandleStates.Finished) return;
		if (!bbValue.IsFinal) return;

		var typed = (BollingerBandsValue)bbValue;
		if (typed.UpBand is not decimal upper || typed.LowBand is not decimal lower) return;

		var close = candle.ClosePrice;

		// Mean reversion: buy at lower band, sell at upper band
		if (close < lower && Position <= 0)
			BuyMarket();
		else if (close > upper && Position >= 0)
			SellMarket();
	}
}