Ставь лайки и следи за новостями
Поставь на него ссылку - пусть другие тоже оценят
Оцени его работу в терминале MetaTrader 5
- Просмотров:
- 62
- Рейтинг:
- Опубликован:
-
Нужен робот или индикатор на основе этого кода? Закажите его на бирже фрилансеров Перейти на биржу
Исходные цены на валютном рынке и рынке фьючерсов являются нестационарными: стандартные модели регрессии и классификации, обученные на них, сталкиваются с серьезным смещением, связанным с предвосхищением будущих значений, и ложными корреляциями. Наивный способ решения этой проблемы — целочисленное дифференцирование — устраняет нестационарность, но при этом уничтожает всю «память» цен, отбрасывая именно ту структуру автокорреляции, которая необходима прогнозной модели.
Дробовое дифференцирование с фиксированной шириной (FFD), представленное в главе 5 книги «Advances in Financial Machine Learning» (López de Prado, 2018), решает эту проблему за счёт дифференцирования с нецелым порядком d ∈ (0, 1), который является достаточным для достижения стационарности при сохранении максимальной «памяти». В данной работе представлена готовая к производственному использованию реализация этого метода на языке MQL5.

Иллюстрация результатов FFD на двух панелях: нестационарная исходная цена (a) и стационарный ряд FFD (b) с отмеченным окном обратного просмотра
Компоненты
- FFDEngine.mqh — библиотека, состоящая только из заголовка, содержащая класс CFFDEngine. Предоставляет функции Init(), Compute() (один бар) и ComputeBuffer() (полный буфер индикатора с оптимизацией prev_calculated ). После вызова OnInit() динамическое выделение памяти не производится.
- FFD.mq5 — пользовательский индикатор, оборачивающий CFFDEngine. Рисует ряд FFD в отдельном окне графика. Поддерживает все значения ENUM_APPLIED_PRICE.
Как работает алгоритм
Вектор весов определяется рекуррентным соотношением (уравнение 5.4 AFML):
w[0] = 1 w[k] = -w[k-1] * (d - k + 1) / k, k = 1, 2, ...
Итерация останавливается, когда |w[k]| < пороговое значение. Затем вектор обращается, так что самая старая цена в окне обратного обзора получает наименьший вес, а самая новая — 1,0. Значение FFD на баре i представляет собой скалярное произведение обращенного векторного веса на окно логарифмических цен [i−width, …, i].
При d = 0,4 и threshold = 1e-5 ширина окна составляет 1 457 баров. При threshold = 1e-3 она составляет 54 бара. Пороговое значение регулирует компромисс между стационарностью и памятью: меньшие значения сохраняют больше информации за счёт более широкого окна обратного обзора.
Входные параметры
| Параметр | По умолчанию | Описание |
|---|---|---|
| InpD | 0,4 | Порядок дробного дифференцирования. Типичный диапазон: 0,1–0,9. Значения выше 0,5 дают результаты, близкие к целочисленному дифференцированию; значения ниже 0,1 дают результаты, близкие к исходным ценам. Оптимальное значение d — это минимальное значение, которое проходит ADF-тест на выбранном уровне значимости — см. сопутствующую статью, посвященную процедуре поиска в Python. |
| InpThreshold | 1e-5 | Пороговое значение τ для весов. Итерация останавливается, когда |w[k]| < τ. Меньшие значения дают более широкое окно и лучшее сохранение памяти, но требуют большего количества исторических баров до получения первого достоверного результата. Рекомендуемый диапазон: от 1e-4 до 1e-5. |
| InpUseLog | true | Применять ln(цена) перед дифференцированием. Рекомендуется для необработанных ценовых рядов (цены закрытия, открытия, максимума, минимума). Устанавливайте значение false только в том случае, если входные данные уже представляют собой ряд доходности или логарифмической доходности. |
| InpPrice | PRICE_CLOSE | Тип применяемой цены. Принимает любое значение из перечисления ENUM_APPLIED_PRICE: PRICE_OPEN, PRICE_HIGH, PRICE_LOW, PRICE_CLOSE, PRICE_MEDIAN, PRICE_TYPICAL, PRICE_WEIGHTED. |
Установка
- Скопируйте файл FFDEngine.mqh в папку MQL5\Include\ (или в подпапку, указанную при загрузке с CodeBase — см. расположение файлов ниже).
- Скопируйте файл FFD.mq5 в пап ку MQL5\Indicators\Downloads\ (он помещается туда автоматически при загрузке с CodeBase).
- Скомпилируйте оба файла в MetaEditor. Индикатор должен скомпилироваться без предупреждений при использовании #property strict.
- Прикрепите FFD к любому графику. Окно индикатора появится под основным графиком после заполнения окна обратного просмотра (ширина + 1 бар).
Использование CFFDEngine в собственном советнике или индикаторе
FFDEngine.mqh — это библиотека, состоящая только из заголовка. Включите её и вызовите Init() один раз в функции OnInit():
#include <FFDEngine.mqh> //--- Глобальный экземпляр механизма дифференцирования с фиксированной шириной и дробными шагами CFFDEngine g_engine; //+------------------------------------------------------------------+ //| Функция инициализации эксперта | //+------------------------------------------------------------------+ int OnInit() { //--- Инициализация движка FFD с параметрами d=0,4, пороговое значение=1e-5 и включенным логарифмическим преобразованием //--- Эта конфигурация формирует статическое окно весовых коэффициентов памяти на этапе инициализации EA if(!g_engine.Init(0.4, 1 e-5, true)) { Print("FFD engine init failed"); return(INIT_FAILED); } return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Функция «экспертного тика» | //+------------------------------------------------------------------+ void OnTick() { //--- Запросить у движка, чтобы точно узнать, сколько исторических баров требуется //--- для вычисления допустимого значения FFD на основе порогового значения int need = g_engine.GetMinBars(); double close[]; //--- Загрузить данные о ценах за необходимый период. //--- Если история ещё не синхронизирована или данных недостаточно, пропустить выполнение, чтобы избежать ошибок. if(CopyClose(_Symbol, _Period, 0, need, close) < need) return; //--- Убедиться, что индексация массива соответствует хронологическому порядку (самый старый столбец по индексу 0) //--- для правильного выравнивания с учетом обратных преобразований матрицы векторных весов FFD ArraySetAsSeries(close, false); //--- Вычислить стационарное значение выхода с дробными разностями для текущего бара double ffd_value = g_engine.Compute(close, need); //--- Используйте ffd_value в качестве признака для вашей модели. }
Кросс-валидация с помощью Python
Сопутствующий файл FFDValidation.mq5 (доступен в загрузке статьи) экспортирует значения FFD в файл CSV. Скрипт на Python ffd_cross_validate.py пересчитывает те же значения с использованием библиотеки afml и сравнивает их по каждому бару. На 5 000 барах EURUSD H1 с d = 0,4 и пороговым значением = 1e-5 максимальное абсолютное расхождение составляет менее 1e-12.
Примечания по производительности
- Выделение векторного веса: один раз в OnInit(). Нулевое выделение памяти на пути тиков.
- Вычисления по каждому бару: скалярное произведение O(width). На современном оборудовании скалярное произведение по 1 457 элементам выполняется менее чем за 50 мкс.
- Функция ComputeBuffer() использует аргумент prev_calculated для пропуска уже вычисленных баров — при каждом тике пересчитывается только текущий незавершённый бар.
Ссылки и сопутствующая статья
- Лопес де Прадо, М. (2018). «Достижения в области финансового машинного обучения», глава 5 («Дробовое дифференцирование»), стр. 76–95. Wiley.
- Полная теория, реализация на Python и поиск параметров на основе ADF: «Инженерия признаков для машинного обучения — Часть 2: Реализация дробного дифференцирования с фиксированной шириной в MQL5» Патрика М. Ньороге.
- Сопутствующие инструменты валидации: FFDValidation.mq5 и ffd_cross_validate.py — включены в пакет для скачивания, прилагаемый к статье.
Перевод с английского произведен MetaQuotes Ltd.
Оригинальная публикация: https://www.mql5.com/en/code/72499
Осциллятор TRIX для долгосрочного тренда
Осциллятор долгосрочного импульса и тренда, основанный на двойной фильтрации TRIX и LWMA.
AIS Smoothed Linear Trend
Этот индикатор отображает сглаженное значение линейного тренда
YURAZ_RSAXEL Скрипт рисует уровни Рудолфа Акселя
Скрипт рисует уровни Рудолфа Акселя
YURAZ_MCCH
Индикатор рассчитывает % роста или падения относительно CLOSE, написан с применением ООП, и легко интегрируется в любой советник или иной индикатор.