Динамическая аллокация по ширине рынка
Методика отдельного модуля PortfolioLab, версия движка 1.0.1 от 20.10.2026 (формат входов 1.0.0). Рыночный срез — 16.10.2026. Начальный сценарий: основной актив MCFTR, защитный актив MM_CBR, порог 0 п.п., капитал 1 000 000 рублей, торговые издержки 10 б.п. на каждую сторону оборота. Это описание гипотетического расчёта, а не фактической доходности управляемого портфеля.
Назначение и границы
Модуль преобразует месячный индикатор ширины рынка в переменные веса двух выбранных активов. Пользователь задаёт порог, основной и защитный активы, период, начальный капитал и ставку торговых издержек; затем явно запускает расчёт. Изменение настройки не изменяет исходный индикатор и не переписывает прежние результаты исследования.
Индикатор — характеристика участия бумаг в тренде; динамическая аллокация — правило распределения капитала по этому индикатору. Обозначение «тактическая аллокация» употребляется для перераспределения между классами активов по сигналам. Здесь точнее название «динамическая аллокация»: отдельная постоянная стратегическая пропорция не задана, а веса могут изменяться от 0 до 100%.
Формула распределения, порог по умолчанию, правило равенства и обработка неизвестных сигналов — решения проекта. Ссылки на отраслевые материалы подтверждают терминологию и принципы раскрытия результатов, а не сертифицируют эту конкретную стратегию. Заявления о соответствии GIPS, IFRS или иному стандарту расчёта доходности не делаются.
Термины
| Термин | Значение в модуле |
|---|---|
| Ширина рынка / Market breadth | Доля исторических участников IMOEX, у которых поддержанный индекс полной доходности не ниже SMA200 |
| TRI / индекс полной доходности | Расчётный ряд, учитывающий доход от распределений по правилам источника; для сигнала используются валовые дивиденды |
| SMA200 | Простое среднее 200 подряд подтверждённых уровней TRI |
| Основной актив | Экспозиция, доля которой увеличивается при росте breadth; по умолчанию MCFTR |
| Защитный актив | Экспозиция, доля которой увеличивается при снижении breadth; по умолчанию синтетическая MM_CBR |
| Порог защитной аллокации | Вычитаемый сдвиг в процентных пунктах; не бинарный сигнал полного переключения |
| Целевой вес | Вес, рассчитанный из индикатора и порога для предстоящей ребалансировки |
| Фактический модельный вес | Доля оценённой позиции после исполнения и последующего изменения цен |
| Гипотетический бэктест | Ретроспективное применение модели к сохранённым историческим данным |
| Анализ чувствительности | Сопоставление заранее заданных порогов на одном наборе активов, данных и дат |
Защитный актив не обязательно обладает меньшим риском в каждом периоде. Золото имеет ценовой риск, валютная экспозиция — риск курса относительно рубля, облигационный фонд — процентный и кредитный риск. Слово «защитный» обозначает роль в модели, а не гарантию сохранности капитала. Эти активы нельзя автоматически объединять термином «кэш». IAS 7 определяет эквиваленты денежных средств через высокую ликвидность, конвертируемость в известную сумму и незначительный риск изменения стоимости; эта бухгалтерская классификация не присваивается всем вариантам модуля.
Индикатор и историческая вселенная
Вселенная сигнала остаётся историческим составом Индекса МосБиржи независимо от выбранных инвестиционных активов. Замена MCFTR фондом, золотом или другой допустимой экспозицией не пересчитывает breadth по составу выбранного фонда.
Одна ценная бумага / класс акций имеет один голос. Обыкновенная и привилегированная акции учитываются отдельно. Веса индекса и капитализация не используются. Для каждой бумаги рассчитываются TRI и SMA200 по 200 подряд поддержанным наблюдениям; разрыв поддержки прерывает непрерывность. Равенство TRI и SMA200 включается в положительную категорию.
N = above + equal + below + unknown
B = (above + equal) / N
U = (below + unknown) / N = 1 - B
unknown включает неподдержанную полную доходность, недостаточную непрерывную историю или отсутствие фактической сигнальной котировки. Такие бумаги остаются в общем знаменателе, но не объявляются находящимися ниже SMA200. График показывает категории отдельно. Полностью отсутствующий месячный индикатор — null; его нельзя заменять нулём, переносить из будущего или трактовать как полный выход из основного актива.
Сигналы берутся из принятого исследования 1.3.0 без изменения его числовых результатов. Полная диагностика содержит 226 месяцев за январь 2008 — октябрь 2026 и 9 413 строк участников. Это месячные срезы, а не ежедневно обновляемая ширина рынка. Отдельный модуль расчёта использует опубликованную историю активов начиная с 2015 года; ранняя диагностика не означает наличие бэктеста с 2008 года.
Календарная метка месяца, сигнальная дата и дата исполнения различаются. В праздники последний сигнальный день перед первой рыночной сессией месяца может лежать уже после первого календарного дня месяца. Поэтому индикатор не объявляется известным в 00:00 календарной даты кадра. Сохранённые ограничения исторической идентичности и доступности публикаций действуют и здесь: три месяца июня — августа 2011 года не имеют принудительного сопоставления MTSS с MTSI-002D; в 37 месяцах сохранены различия поколений ISIN. Подробности — в методике индикатора.
Параметр распределения
tau_pp = пользовательский порог от 0 до 100 п.п.
tau = tau_pp / 100
defensive_weight = max(0, 1 - B - tau)
primary_weight = 1 - defensive_weight
Начальное значение tau_pp равно 0. При допустимых входах оба веса лежат между 0 и 1, их сумма равна 1; плеча и коротких позиций нет. Увеличение порога уменьшает защитную долю. При пороге 100 п.п. модель остаётся полностью в основном активе. При пороге 20 п.п. из дополнения breadth вычитаются ровно 20 процентных пунктов; это не умножение на 0,8 и не правило «если breadth пересёк 20%, перевести всё».
Капитал допускается от 1 до 1 трлн рублей; ставка торговых издержек — от 0 до 500 б.п. Даты задаются в формате YYYY-MM-DD, начало должно предшествовать концу. Неподдерживаемые значения не округляются молча до допустимых границ: расчёт возвращает ошибку валидации.
| Ширина рынка | Порог | Основной актив | Защитный актив |
|---|---|---|---|
| 27,27% | 0 п.п. | 27,27% | 72,73% |
| 27,27% | 20 п.п. | 47,27% | 52,73% |
| 27,27% | 80 п.п. | 100,00% | 0,00% |
| 100,00% | 0 п.п. | 100,00% | 0,00% |
Это иллюстрация формулы, не рекомендация порога. На сохранённом октябрьском сигнале 2026 года: 44 бумаги, 12 выше SMA200, 0 равны, 31 ниже, 1 без сигнала; B = 12 / 44. Дата сигнала — 30.09.2026, плановое исполнение — 01.10.2026. Результат не является новым сигналом на дату открытия страницы.
Активы и их идентичность
Начальный основной актив — MCFTR, Индекс МосБиржи полной доходности «брутто», валюта расчёта RUB. Индекс не является покупаемым паем. Дивиденды уже включены в его уровни и повторно не начисляются.
Начальный защитный актив — MM_CBR, синтетическая модель денежного рынка по исторической ставке Банка России. Процент начисляется по календарным дням ACT/ACT, включая выходные; соответствующее накопление уже входит в уровни между оценочными сессиями. Расходы и tracking error реального фонда, налоги и доходность конкретного продукта эта модель не воспроизводит.
Выбор ограничен опубликованным допустимым набором со своей историей уровней и разрешением ребалансировки. Варианты имеют отдельные признаки: индекс, синтетическая модель, реальный фонд или справочный ряд. Одинаковое экономическое назначение не делает разные коды одним инструментом. Синтетическое продление истории не выдаётся за котировки фонда до его появления.
В версии 1.0.0 опубликовано 18 вариантов. Все могут занимать роль основного или защитного актива; роль не меняет свойства ряда.
| Категория | Коды |
|---|---|
| Индекс полной доходности | MCFTR |
| Синтетические модели российского денежного рынка | MM_CBR, MM_RUONIA, MM_RUSFAR |
| Синтетические модели фондов акций и облигаций | IMOEX_FUND_PROXY, OFZ_FUND_PROXY, CORP_FUND_PROXY |
| Реальные БПИФ | SBMX, SBGB, LQDT, GOLD, TGLD |
| Синтетический долларовый денежный рынок в рублях | USD_MM_RUB |
| Синтетическая валютная корзина | FX_BASKET_RUB |
| Учётная цена золота Банка России | GOLD_RUB |
| Официальные валютные курсы Банка России | USD_RUB, EUR_RUB, CNY_RUB |
Долларовый денежный ряд сочетает накопление SOFR и USD/RUB; используется индекс предыдущей американской даты. Валютная корзина содержит USD, EUR и CNY по трети капитала с внутренней месячной ребалансировкой и без процентов на валюты. Для справочного золота не моделируется хранение, для валютных курсов — процентный доход. Такие свойства не заменяются свойствами MM_CBR. Для реальных фондов принята накопительная интерпретация опубликованной цены; отсутствие выплат и все корпоративные действия за полную историю отдельно не сертифицированы.
Справочные уровни золота и валютных курсов допускаются только как условные оценки модельных экспозиций. Они не являются котировками, по которым гарантировалось исполнение биржевой сделки. Доступность справочного уровня и разрешение условной ребалансировки должны быть раскрыты в метаданных. Выбор основного и защитного актива одного и того же кода не допускается. Начальная валюта оценки и все результаты — рубли.
Календарь, оценка и исполнение
Расчёт идёт по российскому календарю оценки опубликованного финансового среза. Окно ограничено пересечением истории выбранной пары. Начало переносится вперёд до первой общей даты, на которой разрешена ребалансировка обоих активов и доступен предшествующий месячный сигнал. Конец не превышает общее покрытие. Запрошенное и фактически использованное окно сохраняются раздельно; отсутствующая ранняя история не достраивается.
На старте выбирается последнее месячное решение с плановой датой исполнения не позже текущей даты и с сигнальной датой строго раньше неё. Затем решения следуют сохранённому месячному расписанию. На каждой оценочной дате порядок операций такой:
- Оценить уже существующие позиции текущими уровнями.
- Определить ожидающее месячное решение и возможность исполнения обоих активов.
- После закрытия исполнить целевые веса, удержать издержки и определить новые условные количества единиц.
- Следующий интервал доходности начислять на новые позиции.
Новый целевой вес не получает доходность периода до исполнения. Если исполнения нет, позиции продолжают действовать и их веса дрейфуют вслед за ценами. При недоступности текущего уровня уже открытая позиция оценивается последним известным прошлым уровнем только для оценки; такая перенесённая оценка не разрешает сделку. Это относится и к ранее перенесённым ненулевым значениям из исходной базы: поле valuation_carried отдельно отмечает перенесённую оценку без разрешения исполнения, а input_age_days сохраняет возраст исходного значения. Возраст справочного курса или условного синтетического входа не равнозначен разрешению реальной биржевой сделки.
Для ребалансировки нужны разрешения can_rebalance обоих активов на текущую дату, даже если целевой вес одного из них равен нулю. Приостановленный приказ сохраняет исходный сигнал до доступного общего дня; если раньше поступило новое месячное решение, оно заменяет ожидающее. Журнал исполнений содержит сигнал, который фактически был использован; неисполненный прежний сигнал не объявляется сделкой. Это правило нового модуля, а не незаметное изменение архивного исследования.
Реальные фонды исполняются только на допустимом текущем наблюдении. Индексные и синтетические варианты используют отдельно оговорённую условную модель исполнения. Прошлый уровень нельзя взять для сделки только потому, что он используется для оценки. Пропуски и переносы показываются в контрольных полях, а не скрываются удалением дат.
Уровни исполнения и аудит хронологии 1.0.1
Сделка моделируется по точным уровням series.levels на закрытии первой допустимой общей сессии после сигнала и не раньше плановой даты: next_eligible_common_close. Старые позиции получают доходность до этого закрытия; новые веса действуют после него. Месячный сигнал — не внутридневное срабатывание порога. Открытие следующего дня и время суток не моделируются.
Все ряды расчётные: MCFTR выражен в пунктах индекса, ряды фондов и синтетические экспозиции — в нормированных единицах полной стоимости. Их нельзя подписывать как фактическую цену пая в рублях. Для фондов исходный дневной CLOSE не доказывает исполнение на аукционе закрытия; официальная цена LEGALCLOSEPRICE — отдельное поле. Справочные валютные курсы и учётное золото ЦБ не являются исполнимыми рыночными котировками.
Журнал раскрывает signal_date, planned_date, execution_date, точные primary_level / defensive_level, единицы *_level_unit, основания *_execution_basis, возраст входов, условные количества и стоимости до/после операции, оборот и расходы. Манифест результата сохраняет эту конвенцию. Патч 1.0.1 добавляет доказательные поля; прежние экономические результаты сохранены.
В 16 сценарных проверках изменения будущих цен и сигналов не изменили прошлые результаты. Это проверка хронологии кода, а не сертификация исторической доступности всех исходников. Состав индикатора закреплён на плановую дату исполнения; полнота доказательств его публикации к предшествующему сигнальному закрытию отсутствует. Первоначальные даты публикации и все версии корпоративных корректировок также не сертифицированы.
Подробная проверка, единицы и оговорки: Причинность бэктеста и модельное исполнение. При последующих изменениях запускать node tests/backtest-causality.mjs и node tests/backtest-execution.mjs. Нельзя заменять этот вывод фразой «подглядывание полностью исключено».
Издержки и самофинансирование
Пользователь задаёт общую ставку издержек cost_bps; начальное значение — 10 базисных пунктов, то есть 0,10% от каждого покупаемого или продаваемого рубля. Это единая сценарная оценка торговых трений, а не наблюдённый исторический спред или тариф брокера. Внутренние расходы, уже отражённые в опубликованных уровнях фонда, повторно не вычитаются.
Стоимость портфеля после сделки определяется с учётом того, что издержки уменьшают капитал, который распределяется по целевым весам:
c = cost_bps / 10000
T = abs(wP * V_after - oldP) + abs(wD * V_after - oldD)
V_after = V_before - c * T
newP = wP * V_after
newD = wD * V_after
Уравнение решается численно; дополнительное финансирование извне не вносится. Первоначальный капитал до входа считается неинвестированным; обе покупки входят в оборот. При начальном входе V_after = V_before / (1 + c). При переходе между активами продажа одной позиции и покупка другой учитываются обе. Оборот в отчёте — валовой двухсторонний: сумма T / V_before, без деления на два. Сумма издержек выражается в рублях.
На конце стоимость оценивается без финальной ликвидации, поэтому издержки выхода из всех позиций не добавляются. Нет внешних пополнений, изъятий, налогов, кредитного плеча, шортов, отдельного вознаграждения управляющего и моделирования рыночного воздействия сверх выбранной ставки.
Этот режим отличается от архивного исследования 1.3.0: там 10 б.п. применялись к абсолютному обороту только MCFTR, а денежная часть считалась без собственной торговой стороны. Совпадение пары и порога 20 п.п. не обязывает новый бэктест побайтно повторять старый результат.
Бенчмарки и сопоставимость
Стратегия сравнивается с двумя сценариями «купить и держать»: 100% выбранного основного и 100% выбранного защитного актива. Они имеют одинаковые с моделью начальный капитал, фактическое окно оценки и ставку первоначальных издержек. Периодических сделок у этих бенчмарков нет; финальная ликвидация также не моделируется. Это помогает отделить эффект выбора защитного актива от эффекта динамического распределения.
Все значения должны сравниваться на одной шкале капитала и общих датах. Период с 2015 года не приписывается фонду с более короткой историей. Бенчмарк является модельным расчётом, а не доказательством возможности купить сам индекс. NASDAQ / S&P 500 не включаются в эту базовую рублёвую концепцию и пять модельных портфелей сайта.
Метрики
| Метрика | Правило |
|---|---|
| Итоговая стоимость | Оценённая стоимость последней даты, после понесённых издержек, без финального выхода |
| Совокупная доходность | Последняя стоимость / начальный внесённый капитал − 1 |
| CAGR | (final / initial) ^ (365.2425 / calendar_days) − 1 при положительной длительности |
| Годовая волатильность | Выборочное стандартное отклонение дневных доходностей × sqrt(252) |
| Максимальная просадка | Минимальное отношение стоимости к предшествующему максимуму минус 1; начальный капитал включается в максимум |
| Коэффициент Шарпа | Средняя арифметическая дневная избыточная доходность над MM_CBR / её выборочное стандартное отклонение × sqrt(252) |
| Издержки | Сумма фактически удержанных модельных расходов, рубли |
| Валовой оборот | Сумма двухстороннего торгового номинала / стоимости перед соответствующей сделкой |
| Средняя доля основного / защитного актива | Простое среднее фактических модельных весов по оценочным сессиям; не среднее целевых весов и не календарное взвешивание |
Для Шарпа используется MM_CBR на тех же интервалах даже при выборе другого защитного актива; смена защитного актива не меняет базу сравнения избыточной доходности. При менее чем двух дневных доходностях показатель стандартного отклонения остаётся null; для Шарпа также применяется численный порог знаменателя 1e-15, поэтому практически нулевое отклонение не даёт бесконечность. Шкала 252 — соглашение годового пересчёта оценочных доходностей; CAGR использует фактические календарные дни. Сохранённая стоимость на день ребалансировки включает её издержки. Волатильность и Шарп используют изменения между последовательными оценёнными закрытиями, поэтому начальная комиссия до первой сохранённой стоимости не является отдельной дневной доходностью для этих двух метрик. Совокупная доходность, CAGR и просадка учитывают её через сравнение с исходным внесённым капиталом.
Графики и анализ чувствительности
Страница раздельно показывает исходный breadth, целевые веса выбранной пары, капитал и просадку стратегии с бенчмарками. Месячный ползунок и воспроизведение синхронизируют сигнальный срез и целевые веса; доходность и просадка относятся к дневной модели. Цвета и подписи обозначают экономическую роль, а не утверждение, что все защитные варианты — деньги. Целевой график не выдаётся за историю фактических позиций.
Для анализа чувствительности используется заранее заданная сетка 0, 10, 20, 30, 40 и 50 п.п. Пара, даты, капитал, издержки и данные одинаковы. Таблица не выбирает автоматически победителя и не устанавливает «оптимальный» порог. Историческая лучшая доходность может быть результатом подгонки. Для отдельного исследования оптимизации нужны заранее объявленные критерий, обучающий период, проверка вне периода подбора / walk-forward, учёт множественного перебора и проверка устойчивости.
Версии, сохранение и контроль
Версии разделены: общая финансовая база сайта 0.5.1, движок конструктора 0.5.0-rc.2, месячный архив 1.0.0, источник индикатора SMA200 1.3.0 (индикатор 1.3.1 после исправлений 0.5.1) и текущий движок аллокации 1.0.1. Изменение параметра сценария не меняет версии данных. Изменение алгоритма, правил пропусков или состава выгрузки требует новой версии и журнала различий.
Результат сохраняет нормализованные настройки, фактическое окно, версии движка и данных, идентификатор сценария, месячные решения, дневную оценку, сделки и контрольные предупреждения. Идентификатор сценария выводится детерминированно из версии/полного хеша набора данных, версии движка и нормализованного запроса; текущее время расчёта в идентичность не входит. Одинаковые входы и настройки должны давать одинаковый результат.
Пользовательские выгрузки включают настройки и результат JSON, дневную таблицу CSV и журнал исполнения CSV. Локально сохранённый черновик настроек не заменяет канонические данные, подтверждённый расчёт или постоянную память проекта. Исходные базы, реестр и замороженный пакет исследования сохраняются отдельно. Приватные идентификаторы файлов, ключи и учётные данные не включаются в публичную выгрузку.
| Файл | Назначение |
|---|---|
/breadth-strategy.html | Отдельная страница сценария и анализа чувствительности |
/breadth-strategy/data.json | 18 наборов уровней и флагов исполнения, календарь 2 965 сессий, 226 месячных сигналов и начальные настройки |
/breadth-strategy/provenance.json | Хеш выгрузки, версии и хеши источников, правила исполнения, пропусков и издержек |
/breadth-strategy/methodology.html | Эта методика для чтения и печати |
lib/calculation/breadth-allocation.js | Детерминированный движок; браузерная копия в public/calculation/ должна совпадать побайтно |
scripts/export_breadth_allocation.py | Формирование производной выгрузки из замороженной финансовой SQLite и принятого breadth JSON |
tests/breadth-allocation.mjs | Контроли формулы, дат, учёта и повторяемости |
tests/breadth-allocation.py | Независимая сверка всех исходных уровней и разрешений, повторная выгрузка и контроль ежедневного учёта через Decimal |
Производная версия данных 1.0.0: 99f1e4afa8abbf45111499c8ae1da6fc935581ae242710f7d5f08aa3fd1b84b0. Она привязана к SHA-256 замороженной финансовой SQLite 060537796eea286f9ea7e051ba04a4cf56ead1340398da422128d2904bb2b634 и SHA-256 неизменённого breadth JSON 989207b9cd9e9240c448f4dd42a251123ceaed108791484ac71e1b31bb2c5826. Хеш самого файла data.json — fcdfd39433cc5b0e440f4abec505294905fce8e3b9cb667ecfdb614cc3e4b3a4; он приведён отдельно в provenance.json и отличается от логической версии набора данных.
Для воспроизведения восстановить закреплённые входы из реестра, открыть SQLite только для чтения и выполнить в точной версии репозитория:
python3 scripts/export_breadth_allocation.py --database /absolute/path/financial-input-0.5.1.sqlite --breadth /absolute/path/market-breadth/report.json
node tests/breadth-allocation.mjs
python3 tests/breadth-allocation.py
Если входы доступны по штатным путям проекта, аргументы экспорта можно опустить. Для отдельной контрольной выгрузки использовать --output, затем сравнить JSON и хеши, не заменяя эталоны. Новое вычисление пользовательского сценария выполняется тем же модулем runAllocation; идентификатор воспроизведения создаётся makeRunManifest. Данные хранятся отдельно от начальных настроек браузера.
Минимальные контрольные условия:
- Сумма четырёх категорий равна историческому числу бумаг; равенство положительное, неизвестные остаются в знаменателе.
tau = 0,tau = 1, нулевая и полная ширина дают допустимые веса с суммой 1.- Отсутствие индикатора не порождает сделки; новые веса не получают доход до исполнения.
- Сделки требуют разрешения обоих активов; перенос оценки не является разрешением сделки.
- Доходность фондов и MCFTR не получает повторных дивидендов или повторных внутренних расходов.
- Двухсторонние расходы, начальный вход, единый период бенчмарков и суммы позиций сходятся с капиталом.
- Идентификатор сценария, результат и экспорт повторяемы; оригинальные архивные CSV/JSON и их SHA-256 не меняются.
Полная историческая проверка доступности каждого наблюдения на исходный момент публикации не сертифицирована. Обновления исторических источников, условность индексного/синтетического исполнения, переносы оценок и применение справочных уровней остаются ограничениями модели. Числовые проверки подтверждают реализацию объявленных правил; они не доказывают предсказательную эффективность или возможность сделки по справочному уровню.
Первичные источники терминологии и раскрытий
Материалы проверены 19.10.2026. Они не являются утверждением или одобрением модели их авторами.
- Московская биржа — Индекс МосБиржи полной доходности: MCFTR, «брутто», RUB. Идентичность базового индекса; не основание для начисления дополнительных дивидендов.
- StockCharts ChartSchool — Percent Above Moving Average. Отраслевое семейство индикаторов участия бумаг относительно скользящей средней. Использование TRI, равенства и неизвестных в PortfolioLab описано отдельно.
- CFA Institute — Asset Allocation with Real-World Constraints. Сигнальное перераспределение активов и связь тактической аллокации со стратегическими ограничениями.
- IFRS Foundation — IAS 7 Statement of Cash Flows. Определение денежных средств и эквивалентов; не автоматическая классификация всех защитных активов.
- CFA Institute Research Foundation — Investment Model Validation. Look-ahead, survivorship, временная проверка вне обучающего периода и контроль моделей.
- CFA Institute — GIPS Standards Handbook for Firms. Различение теоретической и фактической доходности, прозрачность предположений. Соответствие GIPS проектом не заявляется.
См. также docs/MARKET_BREADTH_RU.md, docs/PROJECT_CONTINUITY_RU.md, docs/PROJECT_DATA_REGISTRY_RU.md и машинный реестр db/project-data-registry.json. Архивная редакция сайта с фиксированными 20 п.п. сохранена в docs/archive/MARKET_BREADTH_UI_0_9_RU.md.