Методика и контрольВыпуск 0.5.1 и запуск

Финансовый выпуск 0.5.1 — исправления выплат и корпоративных действий, 21.10.2026

Выпуск 0.5.1 исправляет подтверждённые ошибки реестра выплат финансовой базы 0.5.0 и одно незаписанное дробление. Рыночный срез (16.10.2026), календарь, цены, состав индекса, синтетические модели, денежная подбаза и расчётный движок 0.5.0-rc.2 не менялись. Индикатор ширины рынка выпущен как 1.3.1: в нём заново оценены только участники, чей ряд полной доходности изменился. Архивный сценарий с фиксированным сдвигом 20 п.п. сохранён как результат 1.3.0.

Идентичность

Параметр0.5.00.5.1
ФайлPortfolioLab_Financial_0_5_0.sqlitePortfolioLab_Financial_0_5_1.sqlite
SHA-256 файла060537796eea…b634d4a69da49bf4905735407087b78e337b3235fef6fe1a705302664ca60fcee96f
Размер, байт311 996 416308 666 368
data_release0.5.0-synthetic9-2026-10-180.5.1-corrections-2026-10-21
data_versione43569f3…83f1f04fde3fb10a9fa455a92548be25ec0f3580898db7e6c76180a16913cf132b1f
Пространство имён D1re43569f3_rf04fde3f_
Строк проекции (42 таблицы)1 946 7451 946 772
manifest_sha256e58b0b33…29d7e3b149a186765e2e9f6e8863be129ee1626f8e968728af27febcecd562f73551
SQL-мастер (финансы + mm_, SQLite 3.53.1)d58b5104…dac1fc60eab7a94e14b8954eac5ae93b3ba2ed70c2ce5e9bce1729ef8618f86acaf4
Индикатор ширины1.3.0, 6d220910…58ca1.3.1, 5a61a8075492412909804e2cc0c95ab7ab8aedcd9e9bb07c6ef5010bf68955ac
Вход аллокации99f1e4af…84b013afdf89a8914f7c95c52481d7c9769caefddfb9c988035917cc5279ce07de7b
Архив индекса (провенанс)faf79a3f…b0d8278de29d6802eddfe24337f4e7946d41347da9db69b8ef1621ff89f9cc202179

data_version 0.5.1 = SHA-256(data_version 0.5.0 ‖ SHA-256 перечня исправлений ‖ SHA-256 сборщика). Метаданные базы содержат ссылки на предыдущий выпуск, перечень и сборщик.

Как получен выпуск

Исходный архив акций (moex_factors.sqlite), из которого движок собирает базовый слой, в рабочем окружении отсутствует, поэтому полная пересборка из первоисточника невозможна. 0.5.1 — документированный корректирующий выпуск поверх принятой 0.5.0:

  1. db/corrections-0.5.1.json перечисляет 23 решения. У каждого — действие, причина и файлы-доказательства с SHA-256 (control/evidence_0_5_1/).
  2. scripts/build_financial_0_5_1.py открывает 0.5.0 только для чтения, проверяет её SHA-256 и хеши всех доказательств и применяет изменения к копии.
  3. Ряд полной доходности базы удовлетворяет TR_t = TR_{t−1}·(P_t·k + D)/P_{t−1}. Поэтому исправление на дату E умножает все уровни с даты E на постоянный множитель. Удаление выплаты D даёт P/(P+D), добавление — (P+D)/P, замена суммы — (P+D₁)/(P+D₀), дробление 1:k — k. Перед применением сборщик проверяет, что в 0.5.0 дневная доходность на дату E точно равна формуле со старыми данными; иначе сборка останавливается.
  4. Удалённые записи переносятся в event_exclusions вместе с полным содержимым и зависимыми строками. Сырые строки distribution_evidence не удаляются. Новые решения записаны в event_reviews и sources.
  5. Сборка детерминирована: два запуска дают побайтно одинаковый файл.

Исправления

№БумагаСобытиеРешениеМножитель TR с датыОснование
01GAZP52,53 ₽, экс-дата 19.07.2022удалить: ГОСА 30.06.2022 решило не платить за 2021 год0,782970 (−21,70%)новость 30.06.2022, dohod.ru
02MAGN3,55 ₽, 31.03.2022удалить: дивиденд за 4 кв. 2021 отменён0,925184 (−7,48%)dohod.ru, investfuture
03NLMK2,60 ₽, 09.01.2023удалить: за 2022 год дивиденды не объявлялись0,976991 (−2,30%)эмитент, dohod.ru
04GMKN248,48 ₽, 05.06.2014удалить дубль: реестр 06.06.2014 — дата решениявне окна TRэмитент
05PHOR21 ₽, 30.12.2016удалить: такой выплаты нет0,991985 (−0,80%)эмитент
06PHOR126 ₽, 11.10.2023удалить: ВОСА 30.09.2023 «решение не принято»0,981579 (−1,84%)эмитент
07PHOR201 ₽, 04.07.2025удалить: ВОСА 24.06.2025 «решение не принято»0,967685 (−3,23%)эмитент
08MSTT11,29 ₽, 20.12.2019удалить: ВОСА 12.12.2019 не состоялось (нет кворума)0,912946 (−8,71%)НРД 577974, 568534
09MSNG0,2261 ₽, 03.03.2026удалить: «решение о выплате не принято общим собранием»0,907618 (−9,24%)НРД 1360329
10RTKM5,9155 ₽, 28.04.2016удалить дубль: 03.05.2016 — реестр для участия в ГОСА0,944144 (−5,59%)НРД 179443, 183026
11RTKMP5,9155 ₽, 28.04.2016удалить дубль, как № 100,924802 (−7,52%)НРД 179443
12GMKN248,0 → 248,48 ₽, 16.06.2014точная сумма эмитента1,000070 (+0,007%)эмитент
13RTKM5,92 → 5,915466946266 ₽, 07.07.2016точная сумма решения ГОСА0,999952НРД 179443
14RTKMP5,92 → 5,915466946266 ₽, 07.07.2016как № 130,999939НРД 179443
15PHOR25 → 250 ₽, 27.10.2011250 ₽ на акцию до дробления (3 111 927 000 ₽ на 12 447 708 акций)1,020064 (+2,01%)НРД 49355 (решение ВОСА 01.12.2011)
16MSTT+7,09 ₽, 15.07.2014добавить пропущенную выплату за 2013 год1,066573 (+6,66%)investfunds, investmint, vsdelke, okama
17MSTT+7,09 ₽, 22.05.2015добавить выплату за 2014 год1,080477 (+8,05%)те же
18MSTT+10,64 ₽, 08.07.2016добавить выплату за 2015 год1,120498 (+12,05%)те же и 2stocks
19PHORдробление 1:10, 26.03.2012записать корпоративное действие×10 (TR, price_level, PHOR_PRICE)MOEX n422, ISS, НРД 49355
20MSTTвыделение АО «Дороги и Мосты», 12.10.2020раскрыть: новые акции не оценены в TR—НРД 656337
21NMTP0,06 ₽, реестр 12.07.2021подтверждено, без изменений—НРД 743310
22MDMG47 ₽, реестр 14.07.2026подтверждено, без изменений—НРД 1414829
23MCFTR09–11.01.2023база верна, расхождение на стороне okama—MOEX ISS

Итог по последнему уровню полной доходности: GAZP −21,70%, MSNG −9,24%, MAGN −7,48%, RTKMP −7,53%, RTKM −5,59%, NLMK −2,30%, GMKN +0,007%, MSTT +17,89%. У PHOR провал на −90,8% 26.03.2012 снят; без учёта самого дробления уровень ниже на 3,88%.

Годовой контроль dividend_annual_control после исправлений согласован для GAZP 2022, GMKN 2014, MSNG 2026, NLMK 2023, PHOR 2023 и 2025, RTKM и RTKMP 2016. Расхождения MAGN 2022 и PHOR 2017 — перенос выплат между календарными годами у второго источника; суммы по смежным годам совпадают.

Исправления прежних выводов 2.4.2

Ширина рынка 1.3.1

Принятое исследование 1.3.0 не пересчитывается целиком. scripts/correct_market_breadth.py берёт его участников и для девяти бумаг с изменённым рядом (GAZP, GMKN, MAGN, MSNG, MSTT, NLMK, PHOR, RTKM, RTKMP) пересчитывает отношение TR к SMA200 тем же правилом: 200 последовательных поддерживаемых уровней, те же даты. Перед изменением строки инструмент проверяет, что TR исследования равен финансовому TR с постоянным множителем и что отношение к SMA200 совпадает до 1e-9. Неизвестные статусы, идентичности, даты и все прочие участники не меняются.

Пересчитано 608 строк участников; статус изменился у 13 — во всех случаях с «выше» на «ниже». Число участников выше SMA200 изменилось в 12 месяцах:

МесяцБумагиШирина 1.3.0 → 1.3.1
2016-08RTKM76,0% → 74,0%
2016-10RTKMP76,0% → 74,0%
2016-11RTKMP68,0% → 66,0%
2016-12RTKM, RTKMP74,0% → 70,0%
2017-08PHOR46,0% → 44,0%
2022-09GAZP17,1% → 14,6%
2022-11GAZP25,0% → 22,5%
2022-12GAZP30,0% → 27,5%
2023-01GAZP45,0% → 42,5%
2023-02NLMK62,5% → 60,0%
2024-03PHOR63,3% → 61,2%
2026-04MSNG52,2% → 50,0%

Полный перечень с прежними и новыми значениями: public/market-breadth/corrections-1.3.1.json. Выгрузки 1.3.0 сохранены в public/market-breadth/archive-1.3.0/.

Влияние на результаты

Отдельная стратегия аллокации MCFTR / MM_CBR, 05.01.2015–16.10.2026, 1 000 000 ₽, расходы 10 б.п.:

τКапитал 0.5.0 / 1.3.0Капитал 0.5.1 / 1.3.1CAGRВолатильностьМакс. просадка
04 664 022 ₽4 660 585 ₽ (−3 437 ₽)13,967% → 13,960%10,06% → 10,04%−22,84% без изменений
10 п.п.4 706 788 ₽4 703 859 ₽14,055% → 14,049%12,02% → 11,99%−26,15% без изменений
20 п.п.4 655 676 ₽4 653 317 ₽13,949% → 13,945%14,01% → 13,99%−28,97% без изменений

Ряды 100% MCFTR и 100% MM_CBR не изменились. Пять модельных портфелей состоят из фондов и индексов и не затронуты: изменились только ссылки провенанса. Пользовательские портфели с GAZP, MAGN, NLMK, PHOR, MSTT, MSNG, RTKM, RTKMP или GMKN после переключения дадут другие результаты, поэтому прежние паспорта расчётов нужно повторить.

Проверка

ПроверкаРезультат
Независимая сверка 0.5.1 с 0.5.0 (scripts/verify_financial_0_5_1.py)16/16 PASS. Изменились только 14 таблиц перечня. Ряды 232 незатронутых инструментов совпадают построчно. У затронутых рядов те же даты и признаки, а множители совпадают с документированными до 1e-12. Независимый пересчёт TR из цен, выплат и дроблений даёт ошибку ≤ 6e-16
Повторная сборкапобайтно тот же SHA-256
SQL-проекция 0.5.1 (verify_database.py --available-inputs-only)42 таблицы, 1 946 772 строки по всем полям. Статус PASS_PARTIAL: базовая 0.4.3 и сырые входы синтетических моделей в окружении не восстановлены
Независимая пересборка проекции (master42.py, SQLite 3.53.1, пакет SQL-склада)мастер совпал побайтно; 42/42 таблицы, 541/541 пакет, manifest_sha256 совпадает
Миграция drizzle/0003_financial_0_5_1.sql42 таблицы, 5 представлений, 5 индексов, без DROP. Пространства 0.5.0 и 0.4.3 остаются в схеме
Загрузка через API (tests/sql-api.mjs, tests/launch-api.mjs)PASS: 541 пакет записан и прочитан обратно по всем полям
Python ↔ JS (tests/reconcile-engines.py)PASS: 51 сценарий, 3 сравнения, максимальная разница NAV 2,5e-8 ₽
Остальные контроли (parity, comparison, history, money-market, primary-review, workspace, модели, таймлапс, аллокация, хронология, шрифты, мобильные, interface-contract)PASS

Не выполнялось в этом окружении (нет входов или прав):

Открытые вопросы

Запуск финансового выпуска 0.5.1 на сайте — порядок действий

Переключение выполняется в два развёртывания: сначала загрузка нового среза рядом с работающим, затем переключение. Сначала рабочий API продолжает отдавать запечатанный 0.5.0, а 0.5.1 загружается в собственное пространство таблиц rf04fde3f_ через временный маршрут /api/staging/. Только после полной сверки второе развёртывание делает 0.5.1 активным и убирает маршрут загрузки. Аудитория сайта не меняется: доступ остаётся закрытым, как раньше.

Развёртывание, секреты и запросы к рабочему сайту выполняет владелец. Ключи вводятся только в скрытый stdin загрузчика; в файлы, аргументы и журналы они не попадают.

0. Предусловия

Локальная репетиция обеих фаз (рабочий 0.5.0 → загрузка 0.5.1 → переключение) уже выполнена:

python3 tests/prepare-staging-rehearsal.py
node tests/staging-rehearsal.mjs        # tests/staging-rehearsal-validation.json: 10/10 PASS

1. Фаза 1 — развёртывание с маршрутом загрузки

python3 launch/apply_phase.py phase1 /path/to/live-checkout

Инструмент сначала проверяет, что checkout — проверенный рабочий 0.5.0: SHA-256 db/runtime-manifest.json, lib/sql-api.mjs, db/schema.ts и журнала миграций. Затем копирует файлы из launch/phase1-staging/:

ФайлНазначение
drizzle/0003_financial_0_5_1.sql, drizzle/meta/*создают 42 таблицы, 5 представлений и 5 индексов rf04fde3f_; без DROP
db/schema.ts, db/releases/base-schema-0-5-0.tsграф схемы сохраняет 0.4.3 и 0.5.0
lib/sql-api-core.mjs, lib/sql-api.mjsтот же API, отдельный экземпляр на каждый манифест; активный манифест остаётся 0.5.0
lib/sql-api-staging.mjs, app/api/staging/[...path]/route.tsвременный маршрут /api/staging/: только загрузка и чтение 0.5.1, расчёты запрещены
db/next-runtime-manifest.jsonманифест 0.5.1, manifest_sha256 e3b149a1…3551

Сборка npm run build должна показать маршруты /api/:path+ и /api/staging/:path+. После развёртывания проверить:

2. Загрузка 0.5.1

Нужны пакеты work/sql-seed/00000.json…00540.json и work/sql-seed/manifest.json из этого пакета; манифест совпадает с db/runtime-manifest.json побайтно.

python3 scripts/seed_site_database_async.py https://<адрес сайта> \
  --manifest db/runtime-manifest.json --seed-dir work/sql-seed \
  --api-prefix staging/ --workers 6 --report tests/staging-0.5.1-live-import.json

Загрузчик запрашивает ключ обхода и ключ импорта скрыто. Каждый пакет сверяется по SHA-256 и после записи читается обратно по всем полям. Повтор пакета допустим: ранее подтверждённый вернёт already_verified. finish проверяет число строк всех 42 таблиц, внешние ключи и метаданные, затем запечатывает выпуск (ready). После этого маршрут отвечает 403 на любую попытку загрузки.

Сверка загруженного среза до переключения. Скрипт сравнивает 290 историй со статическими выгрузками 0.5.1, а также каталог и денежную модель. Манифест и выгрузки он берёт из этого пакета, ключ обхода читает из скрытого stdin.

python3 tests/live-sql-api.py https://<адрес сайта> --api-prefix staging/ --report tests/staging-0.5.1-live-api-validation.json

3. Фаза 2 — переключение

Развернуть дерево этого пакета (данные 0.5.1, UI 0.13.0). Перед развёртыванием проверить:

python3 launch/apply_phase.py verify-phase2 .

Проверка требует, чтобы активный манифест был 0.5.1, временные файлы загрузки были удалены, миграция 0003 оставалась на месте, а public/data/catalog.json был выгрузкой 0.5.1.

После развёртывания:

Затем отозвать временный ключ импорта. Независимо от ключа запечатанные срезы закрыты для загрузки состоянием ready.

4. Откат

Откат — повторное развёртывание прежнего коммита 0.13.0 / 0.5.0. Таблицы 0.5.0 не изменялись (это проверено в репетиции по хешам манифеста), поэтому прежний код сразу работает со своим пространством. Строки готовых срезов не перезаписываются и не удаляются.

5. Чек-лист перед открытием

ПунктСтатус
Финансовая база 0.5.1 собрана и независимо проверена (16/16)готово
SQL-проекция и миграция 0.5.1, загрузка и чтение 541 пакета локальноготово
Репетиция двух фаз запускаготово, 10/10
Все контроли сайта на данных 0.5.1PASS, кроме не запускавшихся из-за отсутствия входов (см. RELEASE_0_5_1_RU.md)
Загрузка в рабочий D1 и HTTP-сверкавыполняет владелец по разделам 1–3
Браузерная приёмка на телефоне и компьютерене выполнена; статические и DOM-проверки её не заменяют
Нагрузочная проверкане выполнена; лимит пилота — один активный расчёт на isolate
Права на использование данных (MOEX, ЦБ, агрегаторы, okama) для выбранной аудиториине подтверждены
TCSG/AGRO RUB, неполные годовые реестры, правила 15 БПИФ, available_atоткрыты, раскрыты в методике
MSTT: невыясненная стоимость выделения «Дорог и Мостов» (2020)раскрыто
Систематическая сверка одиночных выплат с сообщениями НРДследующий шаг

Без отдельного решения владельца аудитория не меняется и публичный доступ не открывается.

Описание выпуска (Markdown)

Порядок запуска (Markdown)

Финансовый выпуск 0.5.0 · движок 0.5.0-rc.2 · интерфейс 0.13.0 · рыночный срез 16.10.2026Наверх ↑