English
preview
Архитектура машинного обучения для MetaTrader 5 (Часть 10): Определение размера позиции в финансовом машинном обучении

Архитектура машинного обучения для MetaTrader 5 (Часть 10): Определение размера позиции в финансовом машинном обучении

MetaTrader 5Торговые системы |
65 0
Patrick Murimi Njoroge
Patrick Murimi Njoroge

Оглавление

  1. Введение
  2. Почему наивное определение размера позиции не работает
  3. Инструментарий AFML для определения размера позиции
  4. Вероятностное определение размера (bet_size_probability)
  5. Динамическое определение размера по прогнозным ценам (bet_size_dynamic)
  6. Бюджетно-ограниченное определение размера (bet_size_budget)
  7. Резервное определение размера через смесь гауссиан (bet_size_reserve)
  8. Заключение
  9. Прикрепленные файлы


Введение

У вас есть оценки вероятностей из конвейера классификатора, построенного в этой серии, и вам нужно преобразовать их в размеры позиций, с которыми может работать торговая система. Стандартные подходы в этом случае дают сбой четырьмя конкретными способами. Правило фиксированной доли обрабатывает прогноз 51% точно так же, как прогноз 91%, отбрасывая информацию об уверенности, которую модель специально оценивала. Использование сырой вероятности в качестве размера позиции игнорирует перекрытие сигналов. Если активны десять triple-barrier-меток и каждая имеет размер 10% капитала, суммарная экспозиция достигает 100% без какого-либо осознанного решения использовать плечо.

Непрерывное изменение размера усредненного сигнала создает микро-корректировки, транзакционные издержки которых превышают ожидаемый вклад в P&L. Ни одно из этих правил не учитывает асимметрию выплат. Стратегия, которая выигрывает три доллара на каждый потерянный доллар, требует иного распределения капитала, чем симметричная сделка при той же вероятности. Критерий Келли это учитывает; методы, основанные только на вероятности, — нет. Измеримые симптомы: систематическая чрезмерная экспозиция в периоды высокой плотности сигналов, размывание преимущества транзакционными издержками и размеры позиций, которые оказываются либо безрассудно большими, либо неоправданно малыми в зависимости от структуры выплат каждой сделки.

В этой статье представлен полный инструментарий определения размера позиции из главы 10 книги Маркоса Лопеса де Прадо Advances in Financial Machine Learning, реализованный в модуле afml.bet_sizing. После прочтения у вас будет полностью работоспособная система определения размера позиции, состоящая из четырех компонентов:

  1. вероятностный метод определения размера позиции первого этапа (bet_size_probability / get_signal) который преобразует выход классификатора в сигнал, взвешенный по уверенности. Он корректирует перекрытие меток, усредняя все активные сигналы во времени, и дискретизирует обновления, чтобы предотвратить чрезмерную торговлю;
  2. динамический метод на основе прогнозной цены (bet_size_dynamic) с сигмоидальной и степенной функциональными формами, процедурой калибровки в закрытой форме, которая задает параметр агрессивности по целевому расхождению и размеру ставки, а также выходной лимитной ценой для систем исполнения;
  3. бюджетно-ограниченный метод (bet_size_budget) и резервный метод, обучаемый по данным (bet_size_reserve) для стратегий, которые выдают только направленные сигналы. Резервный метод обучает свою кривую определения размера позиции по эмпирическому распределению дисбаланса одновременно активных позиций с использованием алгоритма EF3M. На выходе получается знаковый ряд позиций в [−1, 1] с поправкой на перекрытие сигналов и диагностикой по барам.

В сопутствующей статье, Части 11, эти сигналы используются в двухэтапной гибридной архитектуре с применением критерия Келли, добавлением учета отношения выплат, слоя интеграции рисков проп-фирмы и динамического бэктеста на основе CPCV. Калибровка самих вероятностных оценок — и ее измеримое влияние на размеры позиций и P&L — рассматривается в следующей статье.

Эта статья — Часть 10 серии Архитектура машинного обучения MetaTrader 5. Предыдущие статьи построили компоненты, от которых зависит эта система:

  1. Часть 1 устранила утечку данных на уровне баров
  2. Часть 2 ввела triple-barrier- и meta-метки
  3. Часть 3 добавила метки trend-scanning
  4. Часть 4 рассмотрела перекрытие меток и ввела веса средней уникальности
  5. Часть 5 ввела последовательный бутстрэппинг и установила соглашение о раздельных весах для обучения и оценки
  6. Часть 6 построила инфраструктуру кеширования
  7. Часть 7 и Часть 9 собрали все в воспроизводимый производственный конвейер
  8. Часть 8 описала интеллектуальную оптимизацию гиперпараметров


Почему наивное определение размера позиции не работает

Чтобы понять, зачем существуют методы AFML для определения размера позиции, полезно точно разобрать, как ломаются более простые альтернативы. Есть три отдельных режима отказа, и финансовое ML сталкивается со всеми тремя одновременно.

Заблуждение фиксированной доли

Самое простое правило определения размера — выделять фиксированную долю капитала, например 2%, на каждый сигнал, который генерирует модель, независимо от ее уверенности. Это правило обрабатывает прогноз вероятности 51% точно так же, как прогноз 95%. Почти в любой разумной модели оптимального принятия решений в условиях неопределенности это неверно. Ожидаемая ценность ставки растет вместе с уверенностью прогноза; соответствующий размер позиции тоже должен расти.

Правило фиксированной доли также игнорирует структуру выплат. Сделка, которая выигрывает $2 на каждый потерянный $1, требует иного распределения капитала, чем симметричная сделка, даже при той же вероятности. И оно игнорирует историю просадок: стратегия, которая уже израсходовала 80% дневного риск-бюджета, имеет меньше возможностей для новых позиций, чем стратегия в начале дня, даже если сила сигнала одинакова.

Проблема взрывного роста перекрытия сигналов

Проблема резко усугубляется, когда метки перекрываются во времени, что практически универсально для triple-barrier-разметки. Предположим, стратегия генерирует сигналы с типичным периодом удержания десять дней. В нормальных рыночных условиях пять или шесть таких сигналов могут быть активны одновременно. Если каждый имеет размер 10% капитала, суммарная экспозиция равна 50–60% — это управляемо. Но в период необычно плотной генерации сигналов пятнадцать или двадцать сигналов могут активироваться быстро один за другим, и каждый будет активен те же десять дней. Если каждый по-прежнему имеет размер 10%, суммарная экспозиция достигает 150–200% капитала — примерно втрое выше управляемого базового уровня — без изменения модели или сознательного решения.

Ловушка чрезмерной торговли

Даже если сигнал учитывает уверенность и перекрытия сигналов, непрерывный сигнал размера позиции, обновляющийся на каждом баре, создает третью проблему: чрезмерную торговлю. Если размер позиции на каждом новом баре меняется с 10.2% до 10.5% капитала, стратегия должна постоянно ребалансироваться. Каждая корректировка несет спред и комиссию. На ликвидном фьючерсном рынке со спредом 0.5 тика и комиссией $5 за лот такие микро-корректировки могут поглотить всю ожидаемую прибыль стратегии до закрытия хотя бы одной прибыльной позиции. Практическая система определения размера позиции должна дискретизировать изменения позиции до шагов, которые оправдывают транзакционные издержки.


Инструментарий AFML для определения размера позиции

Модуль afml.bet_sizing реализует четыре разных подхода. Пользовательские функции в bet_sizing.py организуют весь конвейер. Базовая математика реализована в ch10_snippets.py, сохраняя прямое соответствие пронумерованным фрагментам из главы 10 AFML. Алгоритм EF3M — необходимый для наиболее сложного метода — находится в собственном модуле, ef3m.py.

Метод

Пользовательская функция

Основной вход

Ключевой механизм

Вероятностный bet_size_probability Вероятности классификатора Z-score через нормальную CDF с опциональным усреднением активных сигналов и дискретизацией
Динамический (прогнозная цена) bet_size_dynamic Прогнозная цена относительно рыночной цены Сигмоидальная или степенная функция расхождения цены, откалиброванная на целевой размер позиции при целевом расхождении; возвращает лимитную цену
Бюджетно-ограниченный bet_size_budget Стороны ставок и временные метки Отношение разности активных длинных и коротких позиций к их соответствующим историческим максимумам; вероятность не требуется
Резервный (смесь EF3M) bet_size_reserve Стороны ставок и временные метки CDF смеси двух гауссиан, подогнанной к эмпирическому распределению дисбаланса одновременно активных позиций

Каждый метод занимает свою нишу. Это не взаимозаменяемые альтернативы одной и той же задаче, а ответы на действительно разные структуры задач. Правильный выбор зависит от того, что выдает модель, перекрываются ли метки, сколько исторических данных доступно и можете ли вы охарактеризовать структуру выплат.


Вероятностное определение размера (bet_size_probability)

Это наиболее широко применимый метод и естественная отправная точка для любой стратегии на основе классификатора. Его ключевая логика реализована в get_signal (фрагмент AFML 10.1).

Статистический механизм get_signal

На вход подается прогнозная вероятность p от классификатора, обученного на задаче с num_classes возможными исходами. Нулевая гипотеза состоит в том, что у модели нет прогностической способности: ее прогнозы не лучше случайного угадывания. При нулевой гипотезе ожидаемая вероятность любого отдельного класса равна базовой частоте 1/num_classes. Для бинарной классификации это 0.5.

Метод измеряет, насколько статистически неожиданна прогнозная вероятность относительно этой нулевой гипотезы, нормируя ее естественным масштабом неопределенности переменной Бернулли:

z = (p - 1/num_classes) / sqrt(p * (1 - p))

Знаменатель sqrt(p * (1 - p)) — это стандартное отклонение переменной Бернулли(p ) — фундаментальная единица неопределенности для бинарного исхода. Оно максимально при p = 0.5 (максимальная неопределенность) и стремится к нулю, когда p приближается к 0 или 1 (высокая уверенность). Деление на эту величину означает, что z-score — это не просто сырое расстояние от базовой частоты, а расстояние, нормированное на неопределенность самого прогноза. Затем этот z-score пропускается через стандартную нормальную CDF и отображается в интервал [−1, 1]:

signal = 2 * norm.cdf(z) - 1

Когда задана прогнозная сторона pred (+1 для long, −1 для short), итоговый знаковый размер позиции становится pred × signal. В противном случае возвращается только модуль. Полученный сигнал равен нулю, когда прогноз совпадает с базовой частотой (нет преимущества, нет позиции), монотонно растет вместе с уверенностью и насыщается — асимптотически приближаясь к ±1, — а не растет без ограничений.

Зачем использовать нормальную CDF? Если предположить, что ошибки оценки вероятности распределены нормально вокруг истинной вероятности, z-score следует стандартному нормальному распределению. Поэтому CDF этого распределения является естественным отображением от «на сколько стандартных отклонений выше нуля находится этот прогноз» к «какая доля прогнозов с таким z-score действительно информативна». Она дает непрерывное, дифференцируемое и ограниченное отображение, устойчивое к вероятностным оценкам, которые выдают реальные модели, и имеет правильную качественную форму — крутая около нуля и плоская около экстремумов.

Full anatomy of the get_signal transformation

Рисунок 1. Полная анатомия преобразования get_signal

  • Вверху слева: Знаменатель стандартного отклонения Бернулли максимален при p=0.5 и стремится к нулю около p=0 и p=1. Когда знаменатель приближается к нулю, z-score неограниченно растет.
  • Вверху справа: один и тот же абсолютный прирост Δp=0.04 даёт значительно больший Δz около p=0.9, чем около p=0.5, потому что при более высоких вероятностях знаменатель меньше. Z-score — это расстояние от базовой частоты, нормированное по уверенности.
  • В середине слева: Стандартная нормальная CDF сжимает неограниченный z-score в интервал [−1, +1]. Три примера показывают нелинейное отображение: один и тот же Δz дает большее изменение сигнала около z=0, чем около z=3.
  • В середине справа: Полное преобразование для бинарных (k=2), трехклассовых (k=3) и четырехклассовых (k=4) задач. Каждая кривая равна нулю на своей базовой частоте 1/k и асимптотически приближается к 1.
  • Внизу слева: значение на каждом этапе конвейера (p → z-score → Φ(z) → signal) для четырёх репрезентативных прогнозных вероятностей, иллюстрирующее, как p=0.92 отображается почти в максимальный сигнал, тогда как p=0.52 отображается почти в нулевой сигнал.
  • Внизу справа: Знаковый размер позиции для стороны long (прогнозный класс +1) и стороны short (прогнозный класс −1). Обе равны нулю на базовой частоте p=0.5 и насыщаются в направлении ±1 на крайних значениях.

Усреднение активных сигналов: поправка на перекрытия сигналов

Преобразование z-score решает проблему уверенности. Слой усреднения — реализованный в avg_active_signals (фрагмент AFML 10.2) — решает проблему перекрытия сигналов.

Рассмотрим стратегию, triple-barrier-метки которой имеют типичную длительность десять баров. В любой момент от четырех до двенадцати сигналов из прошлых десяти баров все еще открыты: их метки назначены, но периоды удержания еще не истекли. Если просто использовать выход get_signal как размер позиции этого сигнала, стратегия неявно держит несколько перекрывающихся позиций одновременно, и каждая имеет размер, как будто это единственная открытая сделка.

avg_active_signals исправляет это, вычисляя в каждый момент времени средний размер позиции по всем одновременно активным сигналам. Он принимает DataFrame со столбцом signal (размеры позиций по отдельным наблюдениям из get_signal) и столбцом t1 (время окончания каждой ставки). Для каждой временной метки в объединенном наборе времен начала и окончания он вычисляет средний сигнал по всем сигналам, активным в этот момент. Результат — профиль экспозиции в непрерывном времени: в каждый момент портфель держит одну усредненную позицию, отражающую коллективную уверенность всех одновременно активных сигналов. Реализация использует внутренний цикл, ускоренный Numba, с @njit(parallel=True), чтобы сделать это вычисление пригодным для производственного масштаба.

avg_active_signals — Concurrency Correction

Рисунок 2. Трехпанельная иллюстрация avg_active_signals.

  • Вверху: Диаграмма Ганта для восьми перекрывающихся сигналов, раскрашенная по стороне (синий = long, оранжевый = short) и с прозрачностью, масштабированной по силе сигнала. Желтая пунктирная ступенчатая линия на правой оси показывает число одновременно активных сигналов на каждом баре.
  • В центре: Выход avg_active_signals — среднее всех одновременно активных сигналов на каждом баре. Экспозиция портфеля всегда ограничена ±1.
  • Внизу: Сырая сумма всех активных сигналов на каждом баре без усреднения. Красные затененные столбцы отмечают все точки, где суммарная экспозиция превышает 100% капитала; при пиковой плотности сигналов наивная сумма достигает 1.78 — на 78% выше целевого максимума.

Дискретизация для предотвращения чрезмерной торговли

После усреднения сигнал все еще является непрерывной величиной, которая может незначительно сдвигаться на каждом новом баре. Фрагмент AFML 10.3 дает простую, но важную дискретизацию:

signal1 = (signal0 / step_size).round() * step_size
signal1[signal1 > 1]  = 1    # Cap
signal1[signal1 < -1] = -1   # Floor

step_size, равный 0.05, означает, что стратегия будет корректировать позицию только тогда, когда требуемое изменение превышает 5% от максимума. Это отфильтровывает микро-корректировки, ожидаемый вклад которых в P&L перекрывается транзакционными издержками. Для стратегии, торгующей стандартными FX-лотами с комиссией $5/лот, такой порог обычно предотвращает примерно 60–80% потенциальных корректировок позиции без существенного ухудшения точности сигнала.

Полный пример использования

from afml.bet_sizing.bet_sizing import bet_size_probability

# events: pd.DataFrame with datetime index and 't1' column (label end times)
# prob:   pd.Series of predicted probabilities from your classifier
# sides:  pd.Series of +1 (long) / -1 (short) primary model predictions

bet_sizes = bet_size_probability(
    events=events,
    prob=prob,
    num_classes=2,
    pred=sides,
    step_size=0.05,           # 5% position increments
    average_active=True,      # handle overlapping triple-barrier labels
)

# bet_sizes: pd.Series indexed by bar time, values in [-1, 1]
# Positive = long, Negative = short, 0 = flat
# Evaluated at both the open and close of every active bet

Когда использовать


Используйте этот метод всякий раз, когда модель выдает вероятности классов, что характерно практически для всех классификаторов в scikit-learn. Опцию average_active=True следует считать настройкой по умолчанию для любой стратегии на triple-barrier-метках: ее отключение эквивалентно предположению, что ваши метки никогда не перекрываются, что почти никогда не верно. Метод работает с любым числом классов через параметр num_classes и является естественным методом определения размера позиции первого этапа в двухэтапной архитектуре, где множитель Келли применяется как второй этап, как описано в части 11.


Динамическое определение размера по прогнозным ценам (bet_size_dynamic)

Не все модели выдают вероятности классов. Модель возврата к среднему может прогнозировать уровень цены, к которому вернется спред. Модель фундаментальной стоимости может оценивать справедливую цену. Модель парного трейдинга может прогнозировать равновесное соотношение между двумя активами. В этих случаях естественный выход модели — непрерывная прогнозная цена, а не вероятность, и вопрос определения размера звучит так: насколько большой должна быть позиция, когда рыночная цена отклоняется от прогноза?

Фрагмент AFML 10.4 предоставляет две функциональные формы: сигмоидальную и степенную. Обе управляются одним калибровочным параметром w.

Сигмоидальная форма и ее геометрия

Пусть price_div = forecast_price − market_price. Сигмоидальный размер позиции равен:

bet_size = price_div / sqrt(w + price_div**2)

Эта функция равна нулю при price_div = 0, ограничена в (−1, +1) и обладает нечетной симметрией. Параметр w управляет наклоном: малое w дает крутую, ступенчатую функцию (агрессивное определение размера); большое w дает плавную функцию (консервативное определение размера). Критически важно, что сигмоида всегда имеет одну и ту же качественную S-форму — w управляет только шириной перехода, а не фундаментальной кривизной реакции.

Степенная форма и случай нелинейной ожидаемой ценности

Степенная форма использует структурно иную функциональную форму:

bet_size = sign(price_div) * abs(price_div)**w

Для этого требуется |price_div| ≤ 1 — расхождение должно быть нормализовано. Качественная форма принципиально меняется вместе с w: при w < 1 функция вогнутая — она резко растет около нуля (позиции быстро набираются при малых расхождениях); при w = 1 она точно линейна; при w > 1 она выпуклая — остается низкой при малых расхождениях и ускоряется при больших. Это структурное отличие делает степенную форму применимой там, где сигмоида не подходит.

Степенная форма особенно полезна, когда ожидаемая ценность сделки растет с расхождением нелинейно. Для стратегии возврата к среднему связь между расхождением и ожидаемой прибылью обычно выпуклая: небольшое отклонение от справедливой стоимости легко может быть шумом; вероятность настоящего прибыльного возврата низка и растет быстрее самого расхождения по мере того, как неправильная оценка становится статистически значимой.

Оптимальная функция определения размера позиции в таком режиме тоже должна быть выпуклой: удерживать капитал при малых, шумовых расхождениях и агрессивно задействовать его, когда сигнал статистически значим. Степенная форма с w > 1 дает именно такую форму, которую сигмоида не может воспроизвести независимо от калибровки w . Для momentum- или breakout-стратегии связь обратная: начальный пробой несет большую часть информации, а по мере роста расхождения сделка становится более переполненной и усиливаются силы возврата к среднему. Степенная форма с w < 1 соответствует этой вогнутой кривой EV.

Power form curvature taxonomy

Рисунок 3. Таксономия кривизны степенной формы

  • Вверху: Положительная половина расхождения (x∈[0,1]), показывающая пять качественных семейств по w. w < 1 — вогнутая форма: размер позиции быстро растет около нуля (агрессивный ранний вход). w = 1 — точно линейная. w > 1 — выпуклая: размер позиции подавлен при малых расхождениях и ускоряется при больших.
  • Внизу: Полный симметричный диапазон (x∈[−1,1]). Те же пять кривых продолжены на отрицательное расхождение, подтверждая нечетную симметрию. Сигмоидальная форма, напротив, всегда дает одну и ту же S-форму независимо от параметра калибровки.

Two canonical EV‑divergence regimes

Рисунок 4. Два канонических режима EV-расхождения

  • Слева — возврат к среднему (выпуклая EV): EV ускоряется при больших расхождениях, где неправильная оценка статистически значима, а вероятность настоящего возврата растет быстрее самого расхождения. Соответствующее оптимальное w равно 2.2. Затененная область — капитал, неверно распределенный линейным правилом размера.
  • В центре — линейная EV (w=1 оптимально): EV пропорциональна расхождению на всем диапазоне. Пунктирная белая опорная линия совпадает с кривой EV; систематического неверного распределения от линейного правила размера нет.
  • Справа — momentum / пробой (вогнутая EV): EV в основном захватывается начальным сигналом и замедляется по мере переполнения сделки. Соответствующее оптимальное w равно 0.45. Затененная область — капитал, оставленный на столе из-за недоразмера начального пробоя.

Power versus sigmoid sizing for three strategy archetypes

Рисунок 5. Степенное и сигмоидальное определение размера для трех архетипов стратегий

  • Левый столбец — кривая EV + размер: Целевая EV (белая пунктирная), наиболее подходящий степенной размер (сплошная) и сигмоидальный размер (пунктирная того же цвета) для каждого архетипа.
  • Центральный столбец — остаток (размер − EV): Знаковая разница между каждой кривой определения размера позиции и целевой EV. Остаток выше нуля означает, что функция определения размера позиции выделяет слишком много относительно EV; ниже нуля — слишком мало.
  • Правый столбец — интерпретация: Краткое резюме того, какая форма подходит архетипу и почему.
  • Верхняя строка (возврат к среднему): Выпуклая EV — power w=2.5 хорошо отслеживает на всем диапазоне; сигмоида завышает размер при малых расхождениях, где EV минимальна.
  • Средняя строка (статистический арбитраж): Линейная EV — обе формы приемлемы; линейная power-форма является правильным вариантом по умолчанию.
  • Нижняя строка (momentum / пробой): Вогнутая EV — power w=0.4 соответствует быстрому раннему захвату; сигмоида занижает размер критического начального пробоя.

Калибровка w

Вместо того чтобы угадывать w, функция get_w вычисляет его по калибровочной цели: «я хочу размер позиции cal_bet_size при расхождении cal_divergence." Для сигмоидальной формы это дает аналитическое обращение формулы. Для степенной формы оптимальный w можно найти, подогнав ее к эмпирической кривой EV-расхождения, оцененной по бэктесту.

from afml.bet_sizing.ch10_snippets import get_w

# Calibrate sigmoid: at 10 pips divergence, bet size should be 0.95
w = get_w(price_div=10, m_bet_size=0.95, func='sigmoid')
# w ≈ 0.28 — steep function, aggressive sizing

# Calibrate sigmoid: at 10 pips divergence, bet size should be 0.50
w = get_w(price_div=10, m_bet_size=0.50, func='sigmoid')
# w ≈ 75.0 — shallow function, conservative sizing

Sigmoid form and w calibration

Рисунок 6. Сигмоидальная форма · bet_size = x/√(w+x²) · Калибровка w

  • Слева — формы сигмоиды при откалиброванных w: Четыре сигмоидальные кривые, каждая проходит через калибровочную точку (кружок), где bet_size_sigmoid(w, 10) = cal_bet_size. Все имеют одну и ту же S-форму; w управляет только шириной перехода, а не фундаментальной кривизной реакции.
  • Справа — ключевое структурное отличие: Сигмоида сравнивается с тремя степенными кривыми на той же нормализованной шкале. Сигмоида не может породить чисто выпуклую форму w=2.5 или чисто вогнутую форму w=0.5, независимо от калибровки.

Shape Matching — Which w Minimizes Residual Against Convex EV?

Рисунок 7. Сопоставление формы — какой w минимизирует остаток относительно выпуклой EV?

  • Слева — наложение кривых: Степенные кривые при шести значениях w построены относительно выпуклой целевой EV (белая). Наиболее подходящая кривая (сплошная) визуально ближе всего отслеживает цель; все остальные пунктирные.
  • Справа — столбчатая диаграмма MSE: Среднеквадратичная ошибка между каждой степенной кривой и целевой EV. Оптимальное w (2.0) выделено белой рамкой. Эту процедуру калибровки можно применить к любой эмпирической кривой EV-расхождения, оцененной по бэктесту.

Целевая позиция и лимитная цена

bet_size_dynamic возвращает не только нормализованный размер позиции, но и целевую целочисленную позицию (t_pos) и лимитную цену (l_p). Лимитная цена вычисляется интегрированием обратной функции определения размера позиции по каждой дискретной единице позиции от текущей позиции к целевой, что дает среднюю цену, при которой исполнение экономически безубыточно с учетом прогноза. Трейдер или алгоритм исполнения может использовать это как верхнюю границу для лимитных ордеров.

Пример кода

from afml.bet_sizing.bet_sizing import bet_size_dynamic

result = bet_size_dynamic(
    current_pos=current_positions,
    max_pos=100,
    market_price=prices,
    forecast_price=forecasts,
    cal_divergence=10,       # calibrate: at 10 pips divergence...
    cal_bet_size=0.95,       # ...bet size is 0.95
    func='sigmoid',
)
# result: DataFrame with columns bet_size, t_pos, l_p

Когда использовать

Используйте этот метод, когда модель выдает прогнозную цену, а не вероятность класса: регрессионные модели, подходы на основе справедливой стоимости, стратегии возврата спреда к среднему и любые подходы, где позиция должна расти непрерывно по мере удаления рынка от справедливой стоимости. Выбирайте сигмоиду, когда связь EV-расхождения приблизительно линейна или неизвестна. Выбирайте степенную форму, когда у вас достаточно исторических данных, чтобы охарактеризовать кривую EV-расхождения, и она явно выпуклая или вогнутая.


Бюджетно-ограниченное определение размера (bet_size_budget)

Некоторые стратегии дают только бинарное направление без оценки уверенности. Простое правило тренд-следования на основе пересечения скользящих средних, модель ранжирования по импульсу или сигнал режима на основе кластеризации могут генерировать только сигнал покупки или продажи и временную метку. В этих случаях ни get_signal, ни bet_size_dynamic не применимы.

bet_size_budget решает это, рассматривая размер позиции как функцию текущего состояния книги позиций стратегии, а не уверенности отдельного сигнала. В каждый момент времени он вычисляет число одновременно активных long- и short-позиций с помощью внутреннего цикла, распараллеленного Numba. Размер ставки для каждого наблюдения затем равен нормализованному дисбалансу long-short:

bet_size = (active_long / max_long) - (active_short / max_short)

где max_long и max_short — исторические максимумы одновременных длинных и коротких позиций соответственно. Когда стратегия имеет максимальную историческую концентрацию long без активных short-позиций, размер позиции равен +1. Когда обе стороны одинаково концентрированы относительно своих максимумов, размер позиции равен нулю.

Экономическая интуиция — это ограничение емкости. Стратегия знает, насколько «занятой» она обычно бывает. Когда она необычно смещена в long относительно собственной истории, портфель должен быть long. Когда длинные и короткие сигналы примерно уравновешены, портфель должен быть близок к нулевой позиции. В торговле в реальном времени исторические максимумы следует обновлять в скользящем окне, а не по всему бэктесту, поскольку максимальное число одновременно активных позиций, наблюдавшаяся в истории, может занижать или завышать будущую активность.

bet_size_budget — Exposure Management from Position Counts

Рисунок 8. Три панели, иллюстрирующие bet_size_budget

  • Вверху: Сырые количества одновременно активных long- и short-ставок на каждом баре. Горизонтальные пунктирные линии отмечают исторические максимумы (max_long, max_short), используемые как знаменатели нормализации.
  • В центре: frac_long and −frac_short как залитые ступенчатые области; белая ступенчатая линия — чистый размер позиции (frac_long − frac_short), по построению ограниченный [−1, +1].
  • Внизу: Бюджетный сигнал (белый, на основе количества, без вероятности), синтетический вероятностный сигнал (фиолетовый пунктир, без учета перекрытия сигналов) и их произведение (зеленый штрих-пунктир). Бюджетный метод знает режим портфеля; вероятностный сигнал знает уверенность модели. Их произведение одновременно учитывает оба аспекта.

Когда использовать

Используйте этот метод, когда модель генерирует только направленные сигналы без оценок уверенности, либо как вторичное наложение поверх первичного вероятностного метода определения размера позиции. В качестве наложения он масштабирует размер на уровне сигнала коэффициентом, который гарантирует, что суммарная экспозиция никогда не превысит исторические нормы, даже когда первичный метод определения размера позиции не знает о количестве конкурентных позиций.


Резервное определение размера через смесь гауссиан (bet_size_reserve)

Бюджетно-ограниченный метод использует long-short дисбаланс как вход, но отображает его через линейную функцию. Резервный метод заменяет это линейное отображение формы, обучаемая на данных, обученной на эмпирическом распределении самого дисбаланса. Это наиболее статистически сложный из четырех подходов.

Интуиция двух режимов

Рассмотрим распределение дисбаланса одновременно активных позиций c_t = active_long − active_short за долгую историю типичной trend-following стратегии. Это распределение обычно бимодально. Есть много наблюдений, где long и short примерно компенсируют друг друга (период нерешительности или перехода режима), концентрируясь около нуля. И есть много наблюдений, где стратегия занимает сильный направленный взгляд, концентрируясь на больших положительных или отрицательных значениях. Унимодальная гауссиана плохо описывала бы такое распределение. Смесь двух гауссиан — одна с центром около нуля для нейтрального режима, другая со сдвигом от нуля для направленного режима — точно улавливает бимодальность.

Это предпосылка bet_size_reserve. CDF подогнанной смеси становится функцией размера: ее выход равен нулю, когда c_t = 0, приближается к ±1 по мере того, как c_t становится экстремальным, и имеет ту промежуточную форму, которую задает эмпирическое распределение.

Алгоритм EF3M

Параметры смеси — средние (μ₁, μ₂), стандартные отклонения (σ₁, σ₂) и вероятность смешивания (p₁) — оцениваются с использованием Алгоритм EF3M (Exact Fit of the First 3 Moments), разработанный Лопесом де Прадо и Форманом (2014). Алгоритм использует первые пять сырых моментов эмпирического распределения, чтобы определить пять параметров смеси. Реализация в ef3m.py выполняет n_runs независимых попыток подгонки (по умолчанию 100) из разных начальных условий и выбирает наиболее вероятный набор параметров через kernel density estimate по результатам. EF3M требует значительной истории — минимум несколько сотен ставок, предпочтительно несколько тысяч — для стабильных оценок параметров.

Формула определения размера через CDF смеси

После оценки параметров размер позиции для данного _ct is:

if c_t >= 0:
    bet_size = (F(c_t) - F(0)) / (1 - F(0))
else:
    bet_size = (F(c_t) - F(0)) / F(0)

# F(x) = p1*norm.cdf(x, mu1, s1) + (1-p1)*norm.cdf(x, mu2, s2)

Эта формула отображает CDF условно по знаку c_t, создавая значение в [−1, 1], равное нулю при c_t = 0 и приближающееся к ±1 по мере того, как c_t становится экстремальным. Форма определяется подогнанной смесью, а не заранее заданной формулой, и создает индивидуальную функцию размера.

bet_size_reserve — EF3M конвейер

Рисунок 9. Пять панелей, иллюстрирующих полный конвейер EF3M

  • Вверху слева: Гистограмма дисбаланса одновременно активных позиций c_t = active_long − active_short. Бимодальная структура — один кластер около нуля (нейтральный / переходный режим) и один на больших значениях (направленный режим) — мотивирует модель смеси гауссиан.
  • Вверху справа: PDF подогнанной смеси (оранжевая) наложена на гистограмму; две отдельные гауссовы компоненты показаны пунктиром: нейтральная (зеленая) и направленного режима (фиолетовая).
  • В середине слева: Кумулятивная функция распределения подогнанной смеси. Отмечена опорная точка F(0) ; это значение нормализует CDF в размер позиции по обе стороны от нуля.
  • В середине справа: Функция размера, выведенная из CDF смеси. Для c_t ≥ 0: bet = (F(c_t)−F(0))/(1−F(0)). Для c_t < 0: bet = (F(c_t)−F(0))/F(0). Кривая равна нулю при c_t=0 и асимптотически стремится к ±1.
  • Внизу: Резервная кривая, обученная по данным (оранжевая) сравнивается с сигмоидой, откалиброванной на то же экстремальное значение (синий пунктир). Затененные области показывают, где методы расходятся; асимметрия и не-S-форма резервной кривой отражают эмпирическое распределение позиций, а не заранее заданную функциональную форму.

Пример кода

from afml.bet_sizing.bet_sizing import bet_size_reserve

result, params = bet_size_reserve(
    events_t1=events['t1'],
    sides=sides,
    fit_runs=100,
    variant=2,               # EF3M with first 5 moments
    return_parameters=True,
)
# result: DataFrame with t1, side, active_long, active_short, c_t, bet_size
# params: dict with mu_1, mu_2, sigma_1, sigma_2, p_1

Когда использовать

Используйте этот метод, когда у вас достаточно исторических сигналов, чтобы EF3M давал стабильные оценки параметров; когда распределение одновременно активных позиций явно бимодально; и когда вы хотите, чтобы функция определения размера позиции была полностью обучаемой по данным. Периодически переоценивайте параметры смеси — ежеквартально или при существенном сдвиге режима, — поскольку параметры зависят от совместного распределения активности сигналов, которое само отражает рыночную структуру.


Заключение

Четыре метода в этой статье устраняют каждый из режимов отказа, определенных в Разделе 1. bet_size_probability с average_active=True задает размер позиции по сигналу для стратегий на основе классификатора с учетом уверенности и перекрытия сигналов. bet_size_dynamic со своими сигмоидальной и степенной формами обслуживает стратегии прогнозной цены, а гибкая кривизна степенной формы соответствует отношению EV-расхождения, когда оно явно нелинейно. bet_size_budget обеспечивает управление экспозицией, когда оценка уверенности недоступна. bet_size_reserve обучает функцию размера по самим данным, когда распределение одновременно активных позиций бимодально, а история достаточна для его характеристики.

Ключевые выводы:

  • Всегда учитывайте перекрытие меток. Устанавливайте averageactive=True, если только не доказано, что ваши метки не перекрываются. Проблема взрывного роста перекрытия сигналов не гипотетична — это систематический риск в каждой triple-barrier-стратегии.
  • Согласуйте форму функции определения размера позиции с отношением EV-расхождения. Для mean-reversion стратегий с выпуклой EV используйте степенную форму с w > 1. Для momentum-стратегий с вогнутой EV используйте w < 1. Для неизвестной или линейной EV сигмоида — надежный вариант по умолчанию.
  • Калибруйте w явно. Используйте get_w с целевым расхождением и размером ставки, соответствующими вашему экономическому предположению. Никогда не угадывайте w.
  • Помните, что качество определения размера зависит от качества вероятностей. Эти методы напрямую передают полученные оценки уверенности в размеры позиций. Влияние неправильной калибровки на размеры позиций и P&L рассматривается в предстоящей статье о калибровке.

Сопутствующая статья (часть 11) применяет критерий Келли к сигналу размера, полученному здесь. Она использует двухэтапную архитектуру, которая добавляет учет отношения выплат, не нарушая коррекцию перекрытия сигналов. Она также интегрирует ограничения риска проп-фирмы и запускает динамический бэктест CPCV по комбинаторным путям φ(N, k).


Прикрепленные файлы

 

Файл

Модуль

Описание

 1. bet_sizing.py afml.bet_sizing Функции пользовательского уровня: bet_size_probability, bet_size_dynamic, bet_size_budget, bet_size_reserve.
 2. ch10_snippets.py afml.bet_sizing Низкоуровневые реализации: get_signal, avg_active_signals, discrete_signal, семейства sigmoid и power, get_w. Ускорено с помощью Numba.
 3. ef3m.py afml.bet_sizing Алгоритм EF3M. Класс M2N с параллельной подгонкой mp_fit. Требуется для bet_size_reserve.


Дополнительная литература

  • Лопес де Прадо, М. (2018). Advances in Financial Machine Learning. John Wiley & Sons.

Перевод с английского произведен MetaQuotes Ltd.
Оригинальная статья: https://www.mql5.com/en/articles/21824

Прикрепленные файлы |
bet_sizing.py (13.85 KB)
ch10_snippets.py (16.1 KB)
ef3m.py (19.45 KB)
Нейросети в трейдинге: Принятие торговых решений с учётом неопределенности (UncAD) Нейросети в трейдинге: Принятие торговых решений с учётом неопределенности (UncAD)
Статья предлагает перенос принципов риск-ориентированного фреймворка UncAD в алгоритмический трейдинг и обосновывает сходство задач навигации и управления капиталом при неполной информации. Мы строим на MQL5/OpenCL карту плотности рыночных состояний, которая компактно кодирует историческую структуру. Это позволяет выявлять зоны поддержки/сопротивления и области низкой плотности для более устойчивого выбора действий.
Низкочастотные количественные стратегии в MetaTrader 5: (Часть 2) Бэктестинг lead/lag-анализа в SQL и MetaTrader 5 Низкочастотные количественные стратегии в MetaTrader 5: (Часть 2) Бэктестинг lead/lag-анализа в SQL и MetaTrader 5
В статье описывается полный конвейер, использующий анализ данных для поиска низкочастотных торговых возможностей lead/lag. Пошагово строится анализатор Lead/Lag на основе кросс-корреляции, с особым вниманием к самым распространенным ошибкам, которые новички чаще всего допускают при разработке запросов для анализа межактивной диффузии информации. После скрининга десятков коинтегрированных и коррелированных пар выбирается торговая пара-кандидат, оценивается её торговая реализуемость в чистом SQL-бэктесте. После того как пара проходит отбор, стратегия тестируется в MetaTester для оптимизации параметров. Советник с соответствующими настройками бэктеста и входными параметрами оптимизации предоставляется вместе со скриптами Python и SQL.
3D-визуализация без внешних библиотек: как MetaTrader 5 раскрывает результаты оптимизации через MQL5 + DX11 3D-визуализация без внешних библиотек: как MetaTrader 5 раскрывает результаты оптимизации через MQL5 + DX11
Описывается практическое применение DirectX 11 и встроенных средств MQL5 для создания 3D-визуализаций и интерактивных интерфейсов в MetaTrader 5. В центре внимания — когнитивная эффективность: как объемные графики и управляемые сцены помогают понять данные оптимизации, кластеры ликвидности и многомерные торговые сценарии. Последовательно разбираются основы DX-конвейера, работа с шейдерами, привязка событий мыши и клавиатуры, а также объективные технологические ограничения. Материал адресован MQL5-разработчикам и алготрейдерам, готовым превратить метрики стратегий в понятные аналитические 3D-ландшафты, где визуальный слой работает на ускорение принятия решений.
Архитектура машинного обучения для MetaTrader 5 (Часть 9): Интеграция байесовской оптимизации гиперпараметров в производственный пайплайн Архитектура машинного обучения для MetaTrader 5 (Часть 9): Интеграция байесовской оптимизации гиперпараметров в производственный пайплайн
В этой статье бэкенд оптимизации гиперпараметров Optuna (HPO) интегрируется в единый ModelDevelopmentPipeline. Добавлены совместная настройка гиперпараметров модели и схем весов выборки, раннее отсечение с Hyperband и отказоустойчивое SQLite-хранилище исследований. Пайплайн автоматически определяет первичные и вторичные модели, добавляет перед моделью обученный препроцессор удаления столбцов, обеспечивающий безопасный инференс, поддерживает последовательный бутстрэппинг, формирует отчет Optuna и интегрируется с bid/ask-пайплайном и LearnedStrategy. Читатели получают более быстрые, возобновляемые запуски и развертываемые самодостаточные модели.