Files
docs/adr/023-investment-performance-vs-index.md
T
codex-bot 7fbd4273ba
Docs security / security (push) Successful in 7s
Docs verify / verify (push) Successful in 13s
docs: describe RUB-only behavior (WealthLedger/main#55) (#68)
2026-11-11 09:19:49 +03:00

94 lines
7.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 023. Результат инвестирования относительно индекса Мосбиржи
**Status:** Accepted. **Date:** 2026-11-07. Дополняет [ADR
019](019-hourly-reads-and-online-instrument-reference.md) исключением для
публичной истории закрытий индексов MOEX (по образцу
[ADR 022](022-stored-instrument-classification.md)). Решение оформлено в
[Issue WealthLedger/main#54](https://git.personal.ksv741.ru/WealthLedger/main/issues/54)
и утверждённом change `specs/openspec/changes/2026-11-07-investment-performance-vs-index/`
в репозитории specs.
## Context
Вкладка «Результат» должна показать, как счёт или «Все счета» справились с
деньгами, которые в него внесли, и сравнить это с вложением тех же денег в
индекс. Простая доходность «стоимость / вложено − 1» искажает оценку, когда
пополнения и выводы распределены во времени. Доходность по времени (TWR)
требует истории стоимости на каждую дату потока, а её в системе нет: хранится
только последний Portfolio.
Сравнение с ценовым IMOEX не отвечает на вопрос пользователя: IMOEX не
включает дивиденды и купоны, а эталон должен учитывать их так же, как
портфель. ADR 019 запрещает хранить справочные данные как долговременный
источник; индексы — публичные временные ряды, для которых онлайн-запрос при
каждом открытии вкладки неприемлем по задержке и лимитам внешнего сервиса.
## Decision
- **«Доходность» для «Результата инвестирования» — money-weighted return (XIRR)**
по внешним денежным потокам счёта и текущей оценке Portfolio. Термин
«доходность» снимается с запрета только для этого понятия; прочие понятия
«не доходность» сохраняют прежний текст.
- **Сравнение — теневой портфель в индексе.** Те же внешние потоки
конвертируются в единицы индекса по закрытию дня потока (или ближайшего
предыдущего торгового дня) и оцениваются по закрытию на дату расчёта.
Эталон — полный доходный индекс MCFTRR; XIRR индекса считается на тех же
потоках. Это идея PME по Long–Nickels; в интерфейсе — «те же деньги в
индексе Мосбиржи».
- **IMOEX — только справочный индекс.** Он показывается рядом, но не
участвует в «опережении» и не является базой сравнения.
- **Только RUB.** Пополнения и выводы в другой валюте не учитываются,
нерублёвые позиции отфильтрованы на входе; конвертация валют не
выполняется (WealthLedger/main#55).
- **Период** начинается с первого внешнего потока, не с открытия счёта.
Короче года — «за N дн.» без annualization; `basis = annual` только если
деньги вложены от 365 дней.
- **Хранение закрытий индексов.** Пара (индекс, торговый день по Москве) →
CLOSE хранится локально с upsert. Это исключение из ADR 019: публичная
история индекса, не привязанная к пользователю или подключению, хранится
как долговременные данные. Остальные справочные сведения ADR 019 не
меняются.
### Отклонённые варианты
- **Простой ROI** (`стоимость / вложено − 1`): искажён моментами пополнений
и выводов, поэтому не сравнивается с индексом на тех же деньгах.
- **TWR (time-weighted return):** требует стоимости портфеля на каждую дату
потока; история оценок в системе отсутствует. Сохранение такой истории
вне этого решения.
- **Ценовой IMOEX как ориентир:** не учитывает дивиденды и купоны, поэтому
сравнение с портфелем, где они учтены, смещено.
- **Конвертация валют (FX):** потребовала бы исторических курсов и
отдельного решения о методике; не нужна для личного RUB-учёта.
## Consequences
- Результат зависит от сохранённых операций T-Bank и последнего полного
Portfolio: неполная история или неполная оценка дают `data: null` или
`completeness: incomplete` по правилам change, а не подменяются оценкой.
- Первая загрузка индекса догружает историю от `from − 10 дней`; при
недостатке закрытий появляется `INDEX_HISTORY_UNAVAILABLE`. Фоновая
синхронизация индексов не вводится.
- Исключение из ADR 019 ограничено закрытиями индексов MOEX.
### Оговорки и условия источника
- **Налоги.** MCFTRR при расчёте дивидендов и купонов использует ставки для
организаций, а не НДФЛ физического лица. Индекс — ориентир альтернативы,
а не точная модель налогов пользователя. Оговорка фиксируется в методике
(«Как считали»).
- **Данные MOEX ISS.** ISS бесплатно отдаёт данные «для ознакомления».
Приложение личное и локальное, данные не распространяются; источник
указывается в «Как считали».
- **Переводы между счетами.** Совпадение суммы и времени операций ещё не
доказывает внутренний перевод. Пока нет подтверждённой связи, такие счета
исключаются из рассчитанной части «Все счета» с явной причиной неполноты.
- **Несколько решений XIRR.** Процент не показывается: нельзя выбрать
произвольную ставку. Прибыль в рублях остаётся видна.
## Links
- Issue: [WealthLedger/main#54](https://git.personal.ksv741.ru/WealthLedger/main/issues/54)
- Change: `specs/openspec/changes/2026-11-07-investment-performance-vs-index/`
(proposal, system-analysis «Расчёт» и «Индексы MOEX», design, Decisions backend 3, 5)