Открыть на GitHub

Parabolic SAR Fibo Limits

Обзор

Parabolic SAR Fibo Limits — порт стратегии MetaTrader 4 FT_0tk80i9uw4ep_Parabolic на платформу StockSharp. Исходный эксперт сочетает две версии индикатора Parabolic SAR и уровни Фибоначчи, чтобы выставлять лимитные заявки в точках отката. Реализация на C# сохраняет поэтапную постановку заявок, встроенную защиту (перенос в безубыток и трейлинг-стоп) и опциональный фильтр торговой сессии, поэтому при работе на закрытых свечах поведение соответствует оригинальному советнику.

Логика стратегии

Подготовка сигналов

  • Согласование двух Parabolic SAR — на выбранном таймфрейме рассчитываются быстрый и медленный SAR. Быстрая кривая служит ранним предупреждением, медленная подтверждает смену состояния. Если быстрый SAR поднимается выше цены, пока медленный остается ниже, формируется потенциальная длинная настройка. Если быстрый SAR уходит ниже цены, а медленный выше, формируется короткая настройка. Как только медленный SAR пересекает цену, соответствующая настройка сбрасывается.
  • Поиск свингов — стратегия использует максимум и минимум за окно длиной Bar Search, что воспроизводит вспомогательную функцию MaximumMinimum из EA. Противоположный экстремум (High[1] или Low[1]) берётся из предыдущей завершённой свечи и служит базой для расчёта уровней Фибоначчи.

Постановка и сопровождение заявок

  • Лимитные заявки по Фибоначчи — когда обе кривые SAR оказываются по одну сторону от цены и настройка активирована, стратегия выставляет лимитную заявку на уровне 50% (Entry Fibonacci %) от найденного свинга. Защитный стоп размещается на заданное количество пунктов дальше экстремума, а тейк-профит — на расширении Фибоначчи (Target Fibonacci %). Заявка регистрируется только в том случае, если текущая цена, будущий стоп и цель находятся минимум в пяти шагах цены друг от друга, что повторяет фильтр Point*5 в MT4.
  • Автоматическое снятие заявок — если быстрый SAR возвращается на другую сторону от цены, активная лимитка по соответствующему направлению отменяется, чтобы не войти в рынок поздно. Исполнение лимитки автоматически отменяет противоположную отложенную заявку.

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

  • Начальные стоп и цель — после исполнения лимитки стратегия закрепляет рассчитанные уровни стоп-лосса и тейк-профита, имитируя параметры SL/TP исходного эксперта.
  • Переход в безубыток — при ненулевом параметре Break Even (points) стоп переносится к цене входа (плюс или минус один шаг цены) после набора указанного количества пунктов прибыли, что соответствует функции BBU.
  • Трейлинг-стоп — если включён параметр Trailing Stop (points), стоп следует за ценой на фиксированном расстоянии. Обновление выполняется только при улучшении прежнего стопа минимум на Trailing Step (points), аналогично TrailingShag в MT4.
  • Принудительное закрытие — при касании рассчитанного стопа или цели на закрытой свече позиция закрывается рыночной заявкой, тем самым эмулируя автоматическое исполнение в MetaTrader.

Фильтр торговой сессии

  • Опциональное ограничение по времени — параметр Use Time Filter разрешает открывать новые сделки только между Start Hour и Stop Hour (включительно) во времени площадки. Защитные механизмы (безубыток, трейлинг, выходы) продолжают работать и вне торгового окна, как и в MQL-версии.

Параметры

  • Use Time Filter — включение фильтра торговой сессии.
  • Start Hour / Stop Hour — границы торгового окна при активном фильтре.
  • Fast SAR Step / Fast SAR Max — коэффициент ускорения и его максимум для быстрого Parabolic SAR.
  • Slow SAR Step / Slow SAR Max — коэффициент ускорения и его максимум для медленного Parabolic SAR.
  • Bar Search — количество свечей, используемых при поиске свинговых максимумов/минимумов.
  • Offset (points) — отступ в пунктах за пределы экстремума при расчёте стоп-лосса.
  • Entry Fibonacci % — процент Фибоначчи для цены лимитной заявки.
  • Target Fibonacci % — процент Фибоначчи для расчёта тейк-профита.
  • Break Even (points) — прибыль в пунктах, после которой стоп переносится в безубыток (± один шаг). Значение 0 отключает функцию.
  • Trailing Stop (points) — дистанция между ценой и трейлинг-стопом. Значение 0 отключает трейлинг.
  • Trailing Step (points) — минимальное улучшение (в пунктах) перед очередным сдвигом трейлинг-стопа.
  • Candle Type — таймфрейм, используемый для расчёта индикаторов и свингов.
  • Volume — базовый объём заявок, наследуемый от класса Strategy (по умолчанию 0.1).

Дополнительные сведения

  • Все параметры, выраженные в пунктах, автоматически переводятся в денежные величины через шаг цены инструмента, поэтому значения из MT4 можно применять без перерасчёта.
  • Стратегия обрабатывает только завершённые свечи выбранного таймфрейма, полностью повторяя баровое исполнение оригинального эксперта.
  • Python-реализация отсутствует, доступна только C# версия в составе каталога API.
using System;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// Parabolic SAR strategy with Fibonacci retracement-based targets.
/// Enters on SAR flip, uses Highest/Lowest range for Fibonacci levels.
/// </summary>
public class ParabolicSarFiboLimitsStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _lookback;

	private decimal _prevSar;
	private bool _hasPrevSar;
	private decimal _entryPrice;

	public ParabolicSarFiboLimitsStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(3).TimeFrame())
			.SetDisplay("Candle Type", "Timeframe for analysis.", "General");

		_lookback = Param(nameof(Lookback), 20)
			.SetDisplay("Lookback", "Period for Highest/Lowest range.", "Indicators");
	}

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

	public int Lookback
	{
		get => _lookback.Value;
		set => _lookback.Value = value;
	}

	/// <inheritdoc />
	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();

		_prevSar = 0;
		_hasPrevSar = false;
		_entryPrice = 0;
	}

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

		_prevSar = 0;
		_hasPrevSar = false;
		_entryPrice = 0;

		var sar = new ParabolicSar();
		var highest = new Highest { Length = Lookback };
		var lowest = new Lowest { Length = Lookback };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(sar, highest, lowest, ProcessCandle)
			.Start();

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

	private void ProcessCandle(ICandleMessage candle, decimal sarValue, decimal highestValue, decimal lowestValue)
	{
		if (candle.State != CandleStates.Finished)
			return;

		var close = candle.ClosePrice;
		var range = highestValue - lowestValue;

		// SAR flip detection
		var sarBelow = sarValue < close;
		var prevSarBelow = _hasPrevSar && _prevSar < close;

		var sarAbove = sarValue > close;
		var prevSarAbove = _hasPrevSar && _prevSar > close;

		// Fibonacci levels from the range
		var fib382 = lowestValue + range * 0.382m;
		var fib618 = lowestValue + range * 0.618m;

		// Position management
		if (Position > 0)
		{
			// Exit at 61.8% Fibonacci or SAR flip above
			if (close >= fib618 || sarAbove)
			{
				SellMarket();
			}
		}
		else if (Position < 0)
		{
			// Exit at 38.2% Fibonacci or SAR flip below
			if (close <= fib382 || sarBelow)
			{
				BuyMarket();
			}
		}

		// Entry on SAR flip with range confirmation
		if (Position == 0 && _hasPrevSar && range > 0)
		{
			if (sarBelow && !prevSarBelow && close > fib382)
			{
				// SAR flipped below price - bullish
				_entryPrice = close;
				BuyMarket();
			}
			else if (sarAbove && !prevSarAbove && close < fib618)
			{
				// SAR flipped above price - bearish
				_entryPrice = close;
				SellMarket();
			}
		}

		_prevSar = sarValue;
		_hasPrevSar = true;
	}
}