Показать доходность инвестиций (XIRR) и сравнение с индексом MCFTRR/IMOEX #54

Open
opened 2026-11-07 19:08:04 +03:00 by codex-bot · 2 comments
Owner

Контекст

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

Решения Change Owner (2026-11-07)

  • MVP: прибыль в RUB, XIRR и «те же деньги в индексе Мосбиржи» (MCFTRR) за всё время; IMOEX — справочная линия. TWR и выбор периодов не входят.
  • Только RUB; валютные счета исключаются с явным объяснением без FX-конвертации.
  • Вкладка «Результат» на странице счёта, HTML-прототип — вариант A, без таблицы потоков. В UI понятные названия индексов вместо технических кодов.
  • Процесс SDD (wealth-ledger-sdd-v2).
  • Уточнение: совпадение суммы и времени двух операций без независимого доказательства связи не подтверждает перевод между своими счетами. Такие счета исключаются из рассчитанной части all с причиной неполноты; если включить нечего, результат недоступен. Подтверждённый перевод между включёнными счетами не является внешним потоком.
  • Уточнение: при нескольких ставках XIRR процент и опережение недоступны с причиной неоднозначности; прибыль в рублях остаётся.

Acceptance Criteria

  • Для RUB-счёта с известным началом и полной историей показаны прибыль ₽, XIRR, стоимость и XIRR теневого MCFTRR-портфеля, опережение (п.п. и ₽).
  • При истории менее 365 дней процент подписан «за период», не экстраполируется в годовые.
  • Неизвестное начало истории, неполное покрытие операций, неполная оценка, валютные потоки/позиции и ввод/вывод бумаг без денежной оценки отражаются причиной недоступности, а не нулём.
  • В all подтверждённые переводы между включёнными счетами не считаются внешними потоками; совпадение суммы/времени без подтверждённой связи не используется для автоматического исключения потоков. Затронутые счета исключаются с причиной UNCONFIRMED_TRANSFER, итог помечается неполным; при отсутствии считаемых счетов итог недоступен.
  • Если XIRR не имеет решения или допускает несколько решений, показывается соответствующая причина, а не выбранная произвольно ставка; прибыль в ₽ остаётся видна.
  • История MCFTRR/IMOEX загружается из MOEX ISS и кэшируется локально; недоступность MOEX не ломает остальные вкладки.
  • График показывает чистые вложения, теневой MCFTRR, справочный IMOEX и текущую стоимость портфеля только конечной точкой.
  • Методика зафиксирована в ADR, глоссарий обновлён. Расчёт XIRR и теневого портфеля проверен независимыми примерами и граничными случаями.

Затронутые репозитории

specs (OpenSpec change 2026-11-07-investment-performance-vs-index, HTML-прототип), backend (MOEX, расчёт и endpoint), frontend (вкладка), docs (ADR, глоссарий, домен, интеграция). Порядок: specs → backend → frontend → docs.

## Контекст Сейчас приложение показывает только нереализованный результат открытых позиций относительно средней цены покупки. Он не учитывает пополнения и выводы, закрытые позиции, купоны, дивиденды, налоги, комиссии и время работы денег. Поэтому пользователь не может узнать, какую доходность дали деньги и обгоняет ли он индекс Московской биржи. ## Решения Change Owner (2026-11-07) - MVP: прибыль в RUB, XIRR и «те же деньги в индексе Мосбиржи» (MCFTRR) за всё время; IMOEX — справочная линия. TWR и выбор периодов не входят. - Только RUB; валютные счета исключаются с явным объяснением без FX-конвертации. - Вкладка «Результат» на странице счёта, HTML-прототип — вариант A, без таблицы потоков. В UI понятные названия индексов вместо технических кодов. - Процесс SDD (`wealth-ledger-sdd-v2`). - Уточнение: совпадение суммы и времени двух операций без независимого доказательства связи **не подтверждает перевод между своими счетами**. Такие счета исключаются из рассчитанной части `all` с причиной неполноты; если включить нечего, результат недоступен. Подтверждённый перевод между включёнными счетами не является внешним потоком. - Уточнение: при нескольких ставках XIRR процент и опережение **недоступны** с причиной неоднозначности; прибыль в рублях остаётся. ## Acceptance Criteria - [ ] Для RUB-счёта с известным началом и полной историей показаны прибыль ₽, XIRR, стоимость и XIRR теневого MCFTRR-портфеля, опережение (п.п. и ₽). - [ ] При истории менее 365 дней процент подписан «за период», не экстраполируется в годовые. - [ ] Неизвестное начало истории, неполное покрытие операций, неполная оценка, валютные потоки/позиции и ввод/вывод бумаг без денежной оценки отражаются причиной недоступности, а не нулём. - [ ] В `all` подтверждённые переводы между включёнными счетами не считаются внешними потоками; совпадение суммы/времени без подтверждённой связи не используется для автоматического исключения потоков. Затронутые счета исключаются с причиной `UNCONFIRMED_TRANSFER`, итог помечается неполным; при отсутствии считаемых счетов итог недоступен. - [ ] Если XIRR не имеет решения или допускает несколько решений, показывается соответствующая причина, а не выбранная произвольно ставка; прибыль в ₽ остаётся видна. - [ ] История MCFTRR/IMOEX загружается из MOEX ISS и кэшируется локально; недоступность MOEX не ломает остальные вкладки. - [ ] График показывает чистые вложения, теневой MCFTRR, справочный IMOEX и текущую стоимость портфеля только конечной точкой. - [ ] Методика зафиксирована в ADR, глоссарий обновлён. Расчёт XIRR и теневого портфеля проверен независимыми примерами и граничными случаями. ## Затронутые репозитории `specs` (OpenSpec change `2026-11-07-investment-performance-vs-index`, HTML-прототип), `backend` (MOEX, расчёт и endpoint), `frontend` (вкладка), `docs` (ADR, глоссарий, домен, интеграция). Порядок: specs → backend → frontend → docs.
codex-bot added the Kind/Feature
Priority
Medium
3
labels 2026-11-07 19:08:04 +03:00
Author
Owner

Реализация готова к ревью:

Решения Change Owner, принятые в ходе реализации:

  • all считается только при оценках счетов в один московский день, иначе ACCOUNT_VALUATION_DATES_DIFFER;
  • если у потоков больше одной смены знака, возвращается AMBIGUOUS_RETURN;
  • период отсчитывается от первого пополнения.

Порядок merge: specs → backend → frontend → docs.

До закрытия Issue:

  • ручная приёмка на реальных счетах (правдоподобие результата, какие счета попадают в UNCONFIRMED_TRANSFER);
  • OpenSpec verify и archive.
Реализация готова к ревью: - specs: WealthLedger/specs#85 (план и уточнения по ходу реализации); - backend: WealthLedger/backend#200; - frontend: WealthLedger/frontend#167; - docs: WealthLedger/docs#67. Решения Change Owner, принятые в ходе реализации: - `all` считается только при оценках счетов в один московский день, иначе `ACCOUNT_VALUATION_DATES_DIFFER`; - если у потоков больше одной смены знака, возвращается `AMBIGUOUS_RETURN`; - период отсчитывается от первого пополнения. Порядок merge: specs → backend → frontend → docs. До закрытия Issue: - ручная приёмка на реальных счетах (правдоподобие результата, какие счета попадают в `UNCONFIRMED_TRANSFER`); - OpenSpec verify и archive.
Author
Owner

Все PR слиты в develop (squash) с зелёным CI, в таком порядке: specs#85 → backend#200 → frontend#167 → docs#67.

По ходу:

  • исправлены сообщения коммитов, которые не прошли commitlint (длина заголовка, заглавная буква в subject), код при этом не менялся;
  • jobs security и verify в specs перезапущены после сбоя загрузки инструментов (HTTP 503).

Issue пока не закрываю. Осталось:

  • ручная приёмка на реальных счетах;
  • OpenSpec verify и archive change 2026-11-07-investment-performance-vs-index.
Все PR слиты в `develop` (squash) с зелёным CI, в таком порядке: specs#85 → backend#200 → frontend#167 → docs#67. По ходу: - исправлены сообщения коммитов, которые не прошли commitlint (длина заголовка, заглавная буква в subject), код при этом не менялся; - jobs security и verify в specs перезапущены после сбоя загрузки инструментов (HTTP 503). Issue пока не закрываю. Осталось: - ручная приёмка на реальных счетах; - OpenSpec verify и archive change `2026-11-07-investment-performance-vs-index`.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: WealthLedger/main#54