Комбинированные метрики оптимизации: баланс доходности и эффективности
Продвинутые подходы к оценке качества торговых стратегий с учётом оборота и комиссий
Сравнение метрик оценки стратегий
При обучении торговых стратегий с подкреплением важно правильно оценивать качество моделей. Традиционные метрики имеют ограничения, которые могут привести к неоптимальным решениям в реальной торговле.
Основные метрики оценки
| Что сравниваем | Как считается | Что отражает |
|---|---|---|
| train_idx | dpnl / (1+DD) | «Доходность-на-риск»: сколько прибыли остаётся после учёта максимальной просадки |
| pnl / turnover | прибыль ÷ общий объём сделок | Эффективность торговли: сколько долларов заработано с каждого проторгованного доллара (proxy Sharpe/IRR на "капитал-оборот") |
Ограничения train_idx
Метрика train_idx показывает доходность с учётом риска, но игнорирует количество денег, "прогоняемых" через рынок. Это может привести к серьёзным проблемам при переходе к реальной торговле.
Проблемы при одинаковом train_idx:
- Комиссии и проскальзывания сильнее сократят чистую прибыль
- Потребуется больший маржин/баланс для тех же позиций
- Ликвидность может стать узким местом
Комбинированный скор (prod_score)
Для решения этих проблем предлагается комбинированный подход, который учитывает как качество доходности с учётом риска, так и эффективность торговли.
prod_score = train_idx * 0.7 + (pnl / turnover) * 0.3
70% - Качество доходности
Наш обычный индекс train_idx, учитывающий риск-скорректированную доходность
30% - Эффективность торговли
Прибыль на доллар оборота, учитывающая комиссии и проскальзывания
Важно: Вес 0.3 условный и может корректироваться под приоритеты. Модель не должна жертвовать оборотом ради символического роста индекса.
Бонус за уменьшение объёма (use_volume_decrease_bonus)
use_volume_decrease_bonus действительно толкает политику к меньшему обороту, но имеет важные ограничения:
- Не гарантирует, что итоговый чекпоинт сравнительно экономичен — бонус мог быть перекрыт случайными выгодными объёмными сделками
- Работает только во время обучения. Для отложенной валидации (test-chunk) бонус не начисляется, и мы можем увидеть обратный эффект
Логика работы
Во время обучения
Bonus-shaping (use_volume_decrease_bonus) чуть подталкивает градиенты в сторону «меньше объёма»
При выборе модели
Комбинированный prod_score смотрит на факт: «Сколько же реально заработала стратегия и какой ценой по обороту»
Практический пример
Рассмотрим сравнение двух моделей с условными цифрами:
| Модель | PNL | Max DD | Turnover | train_idx | PNL/Turnover | prod_score |
|---|---|---|---|---|---|---|
| A | $1,200 | 6% | $600,000 | 0.113 | 0.0020 | 0.083 |
| B | $1,050 | 4% | $200,000 | 0.100 | 0.0053 | 0.085 |
Анализ результатов:
- train_idx говорит «А» лучше (0.113 > 0.100)
- Но PNL/Turnover у «В» в 2.5 раза выше
- Применив prod_score, выигрывает В (0.085 > 0.083) — модель чуть менее доходная, зато в 3х экономичнее по обороту
Реализация
В блоке сохранения (_train_ppo → _ppo_iteration) после получения train_metrics:
idx = train_metrics["index"] pnl = train_metrics["pnl"] turnover = max(train_metrics["turnover"], 1e-8) # защита от /0 efficiency = pnl / turnover # $ на $ оборота prod_score = idx * 0.7 + efficiency * 0.3
Храним лучшую пару (best_prod_score, best_checkpoint) и сравниваем по ней:
if prod_score > best_prod_score:
best_prod_score = prod_score
save_checkpoint(...)При желании логируем обе метрики, чтобы видеть компромисс.
Итог: взаимодополняющие механизмы
Два механизма работают на разных уровнях и дополняют друг друга:
use_volume_decrease_bonus
On-policy рубильник, заставляющий агента помнить о «дороговизне» оборота
Работает во время обучения, направляя градиенты в сторону уменьшения объёма
prod_score
Off-policy фильтр, выбирающий итоговую модель по соотношению PNL / объём
Оценивает уже обученную модель с учётом реальной эффективности торговли
Ключевой принцип: Они не заменяют, а дополняют друг друга: один помогает обучаться «аккуратнее», второй — выбрать, что действительно выгоднее в продакшене.