Открыть на GitHub

Стратегия Interceptor (порт StockSharp)

Общая идея

Стратегия Interceptor представляет собой перенос советника MetaTrader5 на платформу StockSharp. Алгоритм ориентирован на таймфрейм M5 по паре GBP/USD и строится вокруг согласованного движения EMA-фанов (34/55/89/144/233) на трёх таймфреймах, подтверждения Stochastic, обнаружения узких диапазонов и свечных паттернов "молот". Дополнительно используется анализ дивергенций и контроль "рога" (схождение EMA), чтобы усиливать сигналы на пробой тренда.

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

  • Структура тренда – EMA на M5/M15/H1 должны быть упорядочены по возрастанию (для лонга) или по убыванию (для шорта), а максимальный размах между самой быстрой и самой медленной EMA не должен превышать заданные лимиты.
  • Подтверждение импульса – Stochastic на M5 и M15 обязан выйти из зон перепроданности/перекупленности, показывая, что цена покидает консолидацию.
  • Пробой флэта – модуль поиска диапазонов оценивает ширину и продолжительность локального флэта. Выход цены за границу диапазона добавляет вес к сигналу.
  • Свечные фильтры – в указанном окне анализируются молоты/перевёрнутые молоты, удовлетворяющие требованиям по размерам теней и расположению относительно локальных экстремумов.
  • Дивергенции – стратегия отслеживает расхождения между ценой и Stochastic на M5, чтобы войти в направлении восстановления тренда.
  • Horn (схождение EMA) – после сужения "веера" EMA фиксируется время сходимости; пробой диапазона в сторону доминирующего тренда добавляет дополнительный сигнал.

Условия входа

В лонг можно войти, если выполняются одно или несколько условий (каждое условие добавляет описание в список сигналов):

  1. Фаны EMA выстроены в бычьем порядке на всех трёх таймфреймах, Stochastic M5 даёт бычий кроссовер, а тело свечи превышает MinBodyPoints.
  2. Свеча пробивает диапазон фана M5, открываясь у минимума и закрываясь выше быстрых EMA.
  3. Обнаружен пробой ранее найденного флэта вверх.
  4. M5 и M15 одновременно демонстрируют пробой при сохранении допустимого расстояния EMA.
  5. Зафиксирована бычья дивергенция между ценой и Stochastic.
  6. В окне поиска найден бычий молот, соответствующий фильтрам.
  7. Stochastic на M15 пересекается вверх и сопровождается свечами роста.
  8. После схождения EMA (horn) цена пробивает верхнюю границу диапазона.

Шортовые сигналы строятся зеркально. Если одновременно присутствуют условия и на покупку, и на продажу, сделка не совершается.

Управление позицией

  • Начальные стоп-лосс/тейк-профит задаются через StopLossPoints и TakeProfitPoints.
  • Параметры TakeProfitAfterBreakeven и StopLossAfterBreakeven позволяют переводить стоп в безубыток после достижения заданной прибыли.
  • TrailingDistancePoints и TrailingStepPoints реализуют плавающий стоп.
  • При появлении сигнала в противоположную сторону текущая позиция закрывается перед открытием новой.

Основные параметры

Параметр Описание
Volume Размер сделки.
FlatnessCoefficient, MinFlatBars, MaxFlatPoints Контроль поиска флэтов.
StopLossPoints, TakeProfitPoints Размеры стоп-лосса и тейк-профита (0 отключает тейк).
TakeProfitAfterBreakeven, StopLossAfterBreakeven Настройки перевода в безубыток.
MaxFanDistanceM5/M15/H1 Максимальная ширина EMA-фанов на каждом ТФ.
StochasticKPeriod*, StochasticUpper*, StochasticLower* Параметры и уровни Stochastic.
MinBodyPoints Минимальный размер тела свечи для подтверждения импульса.
MinDivergenceBars Минимальное количество баров между пивотами при дивергенции.
Hammer* Набор параметров для фильтрации молотов.
MaxFanWidthAtNarrowest, FanConvergedBars Критерии сужения EMA для horn-сигналов.
RangeBreakLookback Длина окна для проверки пробоя диапазона.
TrailingStepPoints, TrailingDistancePoints Параметры плавающего стопа.
CandleType Тип основной серии свечей (по умолчанию M5).

Практические замечания

  • Стратегия повторяет оригинальный EA, разработанный под GBP/USD M5; при смене инструмента или таймфрейма параметры нужно адаптировать.
  • Для работы требуются свечи M5, M15 и H1 одного инструмента.
  • Алгоритм поддерживает только одну нетто-позицию; при реверсе закрывается противоположная.

Предупреждение

Приведённая реализация предназначена для обучения. Торговля на реальном счёте требует дополнительного тестирования, настройки параметров и учёта рисков.

using System;
using System.Collections.Generic;

using Ecng.Common;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// Interceptor strategy (simplified). Uses RSI + EMA trend filter.
/// </summary>
public class InterceptorStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _emaLength;
	private readonly StrategyParam<int> _rsiLength;

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

	public int EmaLength
	{
		get => _emaLength.Value;
		set => _emaLength.Value = value;
	}

	public int RsiLength
	{
		get => _rsiLength.Value;
		set => _rsiLength.Value = value;
	}

	public InterceptorStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
			.SetDisplay("Candle Type", "Candles", "General");

		_emaLength = Param(nameof(EmaLength), 50)
			.SetGreaterThanZero()
			.SetDisplay("EMA Length", "Trend EMA", "Indicators");

		_rsiLength = Param(nameof(RsiLength), 14)
			.SetGreaterThanZero()
			.SetDisplay("RSI Length", "RSI period", "Indicators");
	}

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);

		var ema = new ExponentialMovingAverage { Length = EmaLength };
		var rsi = new RelativeStrengthIndex { Length = RsiLength };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(ema, rsi, (ICandleMessage candle, decimal emaValue, decimal rsiValue) =>
			{
				if (candle.State != CandleStates.Finished)
					return;

				if (!IsFormedAndOnlineAndAllowTrading())
					return;

				var close = candle.ClosePrice;

				if (close > emaValue && rsiValue > 60m && Position <= 0)
					BuyMarket();
				else if (close < emaValue && rsiValue < 40m && Position >= 0)
					SellMarket();
			})
			.Start();

		var area = CreateChartArea();
		if (area != null)
		{
			DrawCandles(area, subscription);
			DrawIndicator(area, ema);
			DrawOwnTrades(area);
		}
	}
}