Привет, SmartLab. Я строю онлайн-сервис для анализа акций Мосбиржи, как инструмент принятия решений и системного инвестирования.
Вот здесь я рассказывал, как начинал с гугл-таблицы, а тут – какие поймал ограничения и как переписал все на Python+Flask.
Сегодня покажу результат одного конкретного теста: как количество акций в портфеле и период ребалансировки влияют на доходность. Казалось бы, очевидный вопрос, но когда я прогнал 30 сочетаний на реальных данных, результат оказался не таким однозначным.
Модель выдаёт итоговый score для каждой акции. Берём ТОП-N акций по скору, держим Hz дней (Horizont), ребалансируем, повторяем.
Полный перебор: N = {5, 10, 15, 20, 25, 30} × Hz = {20, 30, 40, 60, 90} = 30 сочетаний.
Период: 2021–2026 (62 тридцатидневных периода).
Что учтено:
Комиссия 0.03% (тариф популярного брокера) на каждую сделку
Slippage 0.1% (проскальзывание при исполнении)
Фильтр ликвидности ≥ 2 млн руб/день (об этом ниже – отдельная история)
N \ Hz |
20d |
30d |
40d |
60d |
90d |
5 |
−36.6 |
+6.8 |
−59.8 |
+29.4 |
+12.0 |
10 |
−0.4 |
+43.8 |
−24.0 |
+23.2 |
+11.9 |
15 |
+16.4 |
+82.5 |
−9.9 |
+48.0 |
+15.7 |
20 |
+25.0 |
+39.0 |
+5.4 |
+30.1 |
+35.0 |
25 |
+22.6 |
+31.8 |
+3.0 |
+31.0 |
+31.6 |
30 |
+21.8 |
+37.1 |
+0.7 |
+26.2 |
+34.1 |
Для проверки прогнал тот же N=15 на еженедельных данных (323 точки, в 5 раз больше наблюдений):
Hz |
Альфа |
Hit Rate |
20d |
+14.1% |
48% |
30d |
+44.0% |
58% |
40d |
−31.6% |
40% |
60d |
+52.9% |
52% |
90d |
+6.7% |
48% |
Еженедельная матрица подтвердила ежемесячную: 30d — лидер, 40d — провал. Абсолютные цифры альфы ниже (+44% vs +82.5%) — потому что еженедельные точки сглаживают удачные ежемесячные совпадения. Но ранжирование горизонтов — идентичное.
Горизонт 30 дней – безусловный лидер. При любом N тридцатидневная ребалансировка обыгрывает остальные варианты. Не 20 дней (слишком частая торговля, комиссия съедает), не 60 (модель «протухает»). Ровно 30 календарных дней.
N=15 при 30d – абсолютный максимум. +82.5% альфы, +104.2% абсолютной доходности, hit rate 61% (в 61% периодов портфель обыгрывает рынок). Это не подгонка одного параметра – N=10 и N=20 при том же горизонте тоже в хорошем плюсе.
N=5 – рулетка. Разброс от −59.8% до +29.4%. Концентрированный портфель из 5 бумаг слишком зависит от одного неудачного выбора.
40 дней – аномально плохой горизонт (или мертвая зона рынка?) Первоначально я думал, что провал на 40d это артефакт ежемесячных бэктест-дат. Но еженедельный бэктест на 323 точках подтвердил: 40d это худший горизонт с альфой −31.6% и hit rate 40%. В 2022 году hit rate на 40d = 0% – ни одного периода, когда портфель обыграл рынок.
Почему? 40 дней это промежуток между двумя рабочими режимами. На 20–30 днях ещё работает ценовой momentum (тренд продолжается). На 60+ днях уже проявляется фундаментал (рынок «переваривает» отчётности). А на 40 днях – ни то, ни другое: momentum уже затух, фундаментал ещё не сработал. В этом окне спекулятивные акции обгоняют фундаментально сильные, и модель системно проигрывает.
Это не баг модели – это структурная особенность рынка.
N=15 – лидер на полном периоде 2021–2026. Когда я прогнал тот же тест на подпериоде 2023–2026, лидером стал N=10 (+39.6% альфы vs +21.5% у N=15). Оптимальный N нестабилен – он зависит от рыночного режима.
Пока «идеального N на все времена» найти не удалось. Есть диапазон (10–20 акций), и есть способы адаптации — но это тема для отдельного поста, где я постараюсь разобрать адаптивный режим.
Это отдельное наблюдение, которое оказалось важнее, чем подбор N.
Изначально модель не фильтровала по ликвидности – в Top-15 попадали в том числе тикеры с минимальными оборотами. Формально они «лучшие по скору», но в реальности:
Спред 1–3% (на входе уже потерял)
Объём не позволяет набрать позицию
Гэпы на новостях съедают стоп-лосс
Я добавил одно условие: средний дневной оборот за 20 дней ≥ 2 млн рублей (рассчитывается как close × volume, исторический, без заглядывания в будущее).
Результат:
Без фильтра |
С фильтром ≥ 2М |
|
Альфа |
+57.1% |
+82.5% |
Hit rate |
47% |
61% |
Отфильтровано |
0 |
~80 из 212 |
Плюс 25 процентных пунктов альфы при добавлении единственного условия. Без оптимизации весов, без новых метрик, без машинного обучения.
Почему так сильно? Неликвидные тикеры создавали шум – они попадали в TОП из-за высоких фундаментальных показателей (маленькая компания с хорошей маржой), но их цена двигалась не по фундаменталу, а по случайным сделкам крупных лотов. Модель была «права» по фундаменталу, но рынок не отражал эту правоту.
Чем обоснован порог 2 млн. руб.: на 1 млн результат похуже (+71%), на 5 млн – ещё чуть хуже (+68%, т.к. отсекаются нормальные mid-caps типа BSPB и UPRO). В итоге 2 млн – точка перегиба.
Ссылки:
Модель работает на moexanalyst.ru – 200+ акций, 7 секторов, обновление ежедневно. Бесплатный доступ, без регистрации можно посмотреть 4 тикера в день, чтобы понять нужно ли вам это.
В канале @moexanalyst периодически публикую актуальные обновления, секретные ссылки на модель и протоколы.
В следующий раз расскажу, что модель говорит о работе с шортами.