Fibonacci Retracement Momentum Strategy — это порт оригинального советника MetaTrader "FIBONACCI.mq4" на высокоуровневый API StockSharp. Стратегия сочетает уровни Фибоначчи нескольких таймфреймов с фильтрами Momentum и MACD, чтобы находить откаты в направлении доминирующего тренда. Основная логика работает на базовом таймфрейме, а подтверждающие данные поступают из более крупных интервалов.
Алгоритм переписан с нуля в стиле StockSharp: используются подписки на свечи, связка индикаторов через Bind, а также встроенные методы управления позициями. Денежный трейлинг и часть сервисных функций из версии MQL упрощены, чтобы сосредоточиться на ключевой механике — вход после касания уровней Фибоначчи при поддержке импульса и фильтра тренда.
Как работает стратегия
Базовый таймфрейм — стратегия подписывается на выбранные свечи (по умолчанию 15 минут) и считает две линейно-взвешенные скользящие средние (быструю и медленную) для оценки локального направления.
Анкерный таймфрейм Фибоначчи — более высокий интервал (по умолчанию 1 час) дает последнюю закрытую свечу. Её максимум и минимум формируют сетку уровней 0%–100% Фибоначчи. Эти же данные питают индикатор Momentum с периодом 14; последние три значения сохраняются в виде абсолютного отклонения от нейтрального уровня 100.
После закрытия каждой базовой свечи проверяется, касалась ли цена какого-либо уровня Фибоначчи, пока предыдущие закрытия находились по другую сторону уровня. При одновременном выполнении условий по скользящим средним, импульсу и MACD формируется сигнал.
Защита позиции реализована через стоп-лосс и тейк-профит в шагах цены. При достижении цели или при неблагоприятном движении позиция закрывается.
Условия входа
Лонг
Свеча старшего таймфрейма задает уровни Фибоначчи; минимум текущей базовой свечи касается любого уровня, при этом хотя бы одно из трех предыдущих закрытий находилось выше него.
Быстрая WMA выше медленной WMA на базовом таймфрейме.
Для любого из трех последних значений |Momentum - 100| превышает заданный порог.
Основная линия MACD находится выше сигнальной на выбранном таймфрейме MACD.
Структурное условие: максимум предыдущей свечи выше минимума свечи двумя барами ранее (аналог Low[2] < High[1]).
Шорт
Максимум текущей базовой свечи касается уровня Фибоначчи, при этом хотя бы одно из трех предыдущих закрытий оставалось ниже него.
Быстрая WMA ниже медленной WMA.
Импульс по абсолютному отклонению превышает пороговое значение хотя бы для одного из трех последних измерений.
Основная линия MACD ниже сигнальной.
Структурное условие: максимум предыдущей свечи выше минимума предыдущего бара (Low[1] < High[2]).
Управление позицией
При появлении противоположного сигнала открытая позиция закрывается вызовом ClosePosition(). Новый вход в обратную сторону выполняется только после закрытия текущей позиции и формирования следующей свечи, что отражает осторожный подход исходного советника.
Управление рисками
Стоп-лосс / тейк-профит — задаются в количестве шагов цены. Значение 0 отключает соответствующий выход.
Фиксация цены входа — цена закрытия сигнальной свечи используется как точка отсчета для расчета защитных дистанций.
Параметры
Параметр
Значение по умолчанию
Описание
FastMaLength
6
Период быстрой WMA на базовом таймфрейме.
SlowMaLength
85
Период медленной WMA.
MomentumLength
14
Период Momentum на таймфрейме Фибоначчи.
MomentumThreshold
0.3
Минимальное абсолютное отклонение от 100.
StopLossSteps
20
Дистанция стоп-лосса в шагах цены (0 — выключено).
TakeProfitSteps
50
Дистанция тейк-профита в шагах цены (0 — выключено).
MacdFastLength
12
Период быстрой EMA внутри MACD.
MacdSlowLength
26
Период медленной EMA внутри MACD.
MacdSignalLength
9
Период сигнальной EMA внутри MACD.
CandleType
15-минутные свечи
Базовый таймфрейм исполнения.
FibonacciCandleType
1-часовые свечи
Таймфрейм для уровней Фибоначчи и Momentum.
MacdCandleType
30-дневные свечи
Таймфрейм для фильтра MACD.
Рекомендации по использованию
При необходимости повторите оригинальную схему соответствия таймфреймов (например, M5 → M30, M15 → H1), настроив параметры свечей.
Значение Volume стратегии должно соответствовать требуемому торговому объему, поскольку закрытие выполняется через ClosePosition().
Дополнительные защиты капитала из MQL-версии (equity stop, трейлинг по прибыли в валюте и т.д.) не переносились — их можно добавить, расширив метод ManageRisk.
Запускайте стратегию в StockSharp Designer, Shell или Runner, подключив необходимые источники рыночных данных.
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 FibonacciRetracementMomentumStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _fastPeriod;
private readonly StrategyParam<int> _slowPeriod;
private decimal? _prevFast, _prevSlow;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int FastPeriod { get => _fastPeriod.Value; set => _fastPeriod.Value = value; }
public int SlowPeriod { get => _slowPeriod.Value; set => _slowPeriod.Value = value; }
public FibonacciRetracementMomentumStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame()).SetDisplay("Candle Type", "Timeframe", "General");
_fastPeriod = Param(nameof(FastPeriod), 6).SetGreaterThanZero().SetDisplay("Fast WMA", "Fast WMA period", "Indicators");
_slowPeriod = Param(nameof(SlowPeriod), 21).SetGreaterThanZero().SetDisplay("Slow WMA", "Slow WMA period", "Indicators");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities() => [(Security, CandleType)];
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevFast = null;
_prevSlow = null;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevFast = null; _prevSlow = null;
var fast = new WeightedMovingAverage { Length = FastPeriod };
var slow = new WeightedMovingAverage { Length = SlowPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(fast, slow, ProcessCandle).Start();
var area = CreateChartArea();
if (area != null) { DrawCandles(area, subscription); DrawIndicator(area, fast); DrawIndicator(area, slow); DrawOwnTrades(area); }
}
private void ProcessCandle(ICandleMessage candle, decimal fast, decimal slow)
{
if (candle.State != CandleStates.Finished) return;
if (!IsFormedAndOnlineAndAllowTrading()) { _prevFast = fast; _prevSlow = slow; return; }
if (_prevFast == null || _prevSlow == null) { _prevFast = fast; _prevSlow = slow; return; }
var prevAbove = _prevFast.Value > _prevSlow.Value;
var currAbove = fast > slow;
_prevFast = fast; _prevSlow = slow;
if (!prevAbove && currAbove && Position <= 0) { if (Position < 0) BuyMarket(); BuyMarket(); }
else if (prevAbove && !currAbove && Position >= 0) { if (Position > 0) SellMarket(); SellMarket(); }
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import WeightedMovingAverage
from StockSharp.Algo.Strategies import Strategy
class fibonacci_retracement_momentum_strategy(Strategy):
def __init__(self):
super(fibonacci_retracement_momentum_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(1))) \
.SetDisplay("Candle Type", "Timeframe", "General")
self._fast_period = self.Param("FastPeriod", 6) \
.SetDisplay("Fast WMA", "Fast WMA period", "Indicators")
self._slow_period = self.Param("SlowPeriod", 21) \
.SetDisplay("Slow WMA", "Slow WMA period", "Indicators")
self._prev_fast = None
self._prev_slow = None
@property
def CandleType(self):
return self._candle_type.Value
@property
def FastPeriod(self):
return self._fast_period.Value
@property
def SlowPeriod(self):
return self._slow_period.Value
def OnReseted(self):
super(fibonacci_retracement_momentum_strategy, self).OnReseted()
self._prev_fast = None
self._prev_slow = None
def OnStarted2(self, time):
super(fibonacci_retracement_momentum_strategy, self).OnStarted2(time)
self._prev_fast = None
self._prev_slow = None
fast = WeightedMovingAverage()
fast.Length = self.FastPeriod
slow = WeightedMovingAverage()
slow.Length = self.SlowPeriod
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(fast, slow, self._on_process).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, fast)
self.DrawIndicator(area, slow)
self.DrawOwnTrades(area)
def _on_process(self, candle, fast_value, slow_value):
if candle.State != CandleStates.Finished:
return
fv = float(fast_value)
sv = float(slow_value)
if self._prev_fast is None or self._prev_slow is None:
self._prev_fast = fv
self._prev_slow = sv
return
prev_above = self._prev_fast > self._prev_slow
curr_above = fv > sv
self._prev_fast = fv
self._prev_slow = sv
if not prev_above and curr_above and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
elif prev_above and not curr_above and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
def CreateClone(self):
return fibonacci_retracement_momentum_strategy()