- BrainTools - https://www.braintools.ru -

Треть доходности моего бэктеста оказалась издержками. Полная карта того, где алготрейдер теряет деньги

Треть доходности моего бэктеста оказалась издержками. Полная карта того, где алготрейдер теряет деньги - 1

Три недели назад я публично исправлял собственный Sharpe с 2.8 до 1.8: аудит нашёл, что исторический движок не считал проскальзывание, и треть доходности за пять лет существовала только на бумаге. Пока я пересчитывал, выяснилось, что издержки — самая недооценённая сила в алготрейдинге: они убивают стратегии чаще, чем плохие модели, решают больше, чем архитектура сети, и врут в бэктестах охотнее всего остального.

Эта статья — полная карта слоёв, где теряются деньги, с измеренными на моей системе последствиями каждого. Стенд прежний (часовые свечи топ-20 Мосбиржи, рекуррентный ансамбль, протокол честной валидации [1]) — но сегодня без нейросетей: только арифметика, которая больно бьёт.

Карта слоёв

Слой

Сколько

Когда платишь

Комиссия брокера

0.05% × 2 (за круг 0.1%)

каждая сделка

Проскальзывание

~0.05% × 2

каждая сделка

Спред

от 0.01% у топ-бумаг до процентов у хвоста

каждая сделка, спрятан в цене

Тариф-абонентка

сотни ₽/мес

всегда, даже без сделок

Парковка кэша

0 у своего фонда брокера, до 0.05% у чужих

при перекладке

Налог

13% с прибыли

раз в год, за скобками этой статьи

Итого честная цена одного круга «купил-продал» на хорошем тарифе — ~0.2% плюс спред. Запомните эту цифру, она сейчас начнёт убивать стратегии.

Проскальзывание: слой, который я забыл

Классическая ошибка [2] рассинхронизации: в live-контуре проскальзывание было прописано честно, а в историческом движке, печатавшем все красивые цифры, — нет. Комиссии были в обоих, и это усыпляло: «издержки же учтены».

Пересчёт с полными издержками: система +75% → +47% за пять лет, Sharpe 2.8 → 1.8. Треть доходности не существовала.

Урок дороже самой цифры: если у вас больше одного симулятора (бэктест, live-имитация, walk-forward-оценка при переобучении) — модель издержек обязана быть одним куском кода. У меня она теперь зашита в единственный движок, и «забыть» её стало синтаксически невозможно.

Порог жизни: смерть LightGBM

Треть доходности моего бэктеста оказалась издержками. Полная карта того, где алготрейдер теряет деньги - 2

У меня в системе живёт LightGBM-бейзлайн. С одними комиссиями он показывал скромные, но положительные +5% за пять лет — «модель работает, просто слабее нейросети». С полными издержками: −19%.

Его кромка была тоньше цены круга. Модель с честным AUC 0.55, реально предсказывающая направление, — и при этом убыточная: каждая сделка приносила меньше 0.2%, которые съедал круг.

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

Тот же порог, кстати, закрыл мне целые направления без единого обучения [3]: минутные стратегии (движения этого масштаба меньше цены круга) и ежедневные ребалансировки. Горизонт стратегии — это в первую очередь издержковое решение, и только потом сигнальное.

Асимметрия: издержки бьют по обороту, а не по доходности

Треть доходности моего бэктеста оказалась издержками. Полная карта того, где алготрейдер теряет деньги - 3

Самое контринтуитивное следствие пересчёта. Мой бенчмарк — SMA-кросс на тех же 20 бумагах — после честных издержек просел сильнее нейросети: Sharpe 0.98 → 0.59 против 2.8 → 1.8. Отрыв системы от бенчмарка после исправления вырос.

Причина проста: SMA-кросс торгует чаще (5567 сделок против 3578 за пять лет). Издержки — налог на оборот, а не на доходность. «Простая дешёвая стратегия» может оказаться самой дорогой в портфеле, а «сложная» — экономной, если реже дёргается.

Практическое следствие: сравнивать стратегии можно только при одинаковой модели издержек, и у каждой надо смотреть не только доходность, но и оборот. Стратегия А с +40% и 500 сделок и стратегия Б с +45% и 5000 сделок поменяются местами от одного изменения тарифа.

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

Тариф решает больше, чем архитектура

Неудобная правда для ML-инженеров: переключение брокерского тарифа влияет на итог сильнее, чем любое из четырёх десятков улучшений модели, которые я успел измерить.

На дефолтном тарифе моего брокера комиссия 0.3% за сторону — цена круга 0.6%+ без проскальзывания. На таком тарифе мертва даже лучшая версия моей системы: вся её кромка меньше. Переключение на тариф для активной торговли (0.05%) — один клик в приложении — сделал для доходности больше, чем переход от одиночной модели к ансамблю. Абонентская плата тарифа — отдельный слой: на маленьком счёте сотни рублей в месяц превращаются в единицы процентов годовых и тают только с ростом капитала.

Проверка боем: полторы недели на реальных деньгах

31 августа система начала торговать реальными деньгами (микро-этап: замер честности исполнения). Первый же день дал сверку модели издержек с реальностью:

  • фактическая комиссия по сделкам: 0.0499% и 0.0500% — модельные 0.05% подтвердились до четвёртого знака;

  • спред фонда ликвидности при парковке кэша: 0.005% — лучше модели;

  • сюрприз, которого не было в бэктесте: покупка фонда ликвидности через API-стакан оказалась платной (0.05%), хотя в приложении свои фонды брокер продаёт без комиссии. Цикл парковки окупается ставкой примерно за три дня — дисциплина «не дёргать кэш туда-сюда» из гигиены стала деньгами. UPD при вычитке: решение нашлось — у брокера есть собственный фонд денежного рынка, и он торгуется без комиссии в том числе через API (проверено боевым лотом: круг стоил одну копейку спреда). Переехал на него; цена вопроса — чуть более дорогая комиссия самого фонда, на моём обороте парковки это кратно выгоднее.

За полторы недели накопилась первая статистика исполнения: полсотни входов, 87% из них исполнились лимитками (в симуляции закладывал ~90%), остальные доехали по рынку. Еженедельная сверка реальных цен входа с симуляцией: медианное расхождение 6.6 базисных пункта — fill-модель пока не врёт. Полная статистика проскальзывания — тема отчёта после первого месяца.

Чек-лист

  1. Посчитайте полную цену круга (комиссия ×2 + проскальзывание ×2 + спред) — и сравните с кромкой вашей стратегии на сделку. Если запас меньше двух-трёх раз — у вас не стратегия, а генератор комиссий.

  2. Модель издержек — один код на все симуляторы. Два движка = гарантированный рассинхрон.

  3. Бенчмарки несут те же издержки, что стратегия. Оборот у них разный — эффект несимметричен.

  4. Проверьте тариф до того, как улучшать модель: клик в настройках может стоить больше всего вашего ресёрча.

  5. Абонентские платежи и комиссии за перекладку кэша — тоже издержки; на малом счёте они видны в доходности невооружённым глазом. Проверьте, чей фонд ликвидности вы покупаете: свой фонд брокер продаёт без комиссии.

  6. После выхода в реал — сверьте фактические комиссии из отчёта брокера с моделью в первый же день. Это бесплатно и однажды найдёт вам сюрприз.

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


Не является индивидуальной инвестиционной рекомендацией.

Автор: svtoroi

Источник [4]


Сайт-источник BrainTools: https://www.braintools.ru

Путь до страницы источника: https://www.braintools.ru/article/35311

URLs in this post:

[1] протокол честной валидации: https://habr.com/ru/articles/1069594/

[2] ошибка: http://www.braintools.ru/article/4192

[3] обучения: http://www.braintools.ru/article/5125

[4] Источник: https://habr.com/ru/articles/1080664/?utm_campaign=1080664&utm_source=habrahabr&utm_medium=rss

www.BrainTools.ru

Rambler's Top100