153 lines
27 KiB
Markdown
153 lines
27 KiB
Markdown
# Proposal
|
||
|
||
Issue: WealthLedger/main#48
|
||
|
||
## Why
|
||
|
||
Страница счёта показывает состав Portfolio списком позиций и распределением по классам активов. Ответа на вопрос «где сконцентрированы деньги» нет: чтобы понять, какие бумаги, отрасли и компании занимают основную часть счёта, владельцу приходится вручную сравнивать карточки позиций. Распределение по классам активов этого не даёт: оно не показывает ни крупнейшие позиции, ни отраслевой или эмитентский перекос.
|
||
|
||
## What Changes
|
||
|
||
- На странице счёта рядом с вкладкой «Позиции» появляется вкладка «Концентрация».
|
||
- Вкладка содержит четыре разреза текущего состава Portfolio выбранного счёта: «Акции», «Облигации», «Секторы», «Эмитенты».
|
||
- В каждом разрезе показаны пять крупнейших элементов по текущей денежной оценке, каждый с суммой и долей, а при семи и более элементах все остальные объединены в одну строку «Прочее» (при шести или меньше элементах каждый показан своей строкой). По нажатию на «Прочее» раскрывается полный перечень остальных элементов, каждый с суммой и долей; пять первых строк при этом не меняются. Рядом с перечнем показана диаграмма распределения, согласованная с перечнем, и суммарная доля пяти первых элементов как показатель концентрации.
|
||
- «Акции» и «Облигации» ранжируют позиции типов `STOCK` и `BOND` соответственно. Фонды в эти два разреза не входят.
|
||
- «Секторы» агрегируют только позиции типов `STOCK`, `BOND` и `FUND`. Позиции типов `CURRENCY`, `FUTURE`, `OPTION`, `STRUCTURED_NOTE`, `DIGITAL_FINANCIAL_ASSET` и `OTHER` в разрез не входят. Позиции перечисленных трёх типов без сектора попадают в явную группу «Сектор не указан».
|
||
- «Секторы» используют сектор инструмента в том виде, как его определяет T-Bank, с русской подписью; государственные облигации определяются значением сектора T-Bank `government` с подписью «Государственный сектор», других собственных классификаций WealthLedger не вводит.
|
||
- «Эмитенты» объединяют акции и облигации одной компании в один элемент. Эмитент — бренд актива по данным T-Bank; название эмитента — название бренда (при разных названиях одного бренда — название позиции с наибольшей стоимостью). Эмитент заполняется в данных Portfolio и у фондов, а разрез «Эмитенты» фонды отбрасывает. Позиции без бренда попадают в явную группу «Эмитент не указан» с видимой долей; если бренда нет у многих позиций, разрез всё равно остаётся в MVP, а объём scope не меняется. Фонды в разрез не входят: их эмитент — управляющая компания, а не компании внутри фонда.
|
||
- Значения показываются в одной валюте за раз. У вкладки свой список валют и свой выбор, независимые от «Структуры портфеля»: в списке валюты позиций акций, облигаций и фондов; по умолчанию выбрана первая по ISO-коду. При одной валюте выбор не показывается. Конвертации нет, общего итога по нескольким валютам нет. Выбранные разрез и валюта сохраняются, пока User остаётся на странице счёта, и сбрасываются при новом заходе и перезагрузке. Доли показываются в формате карточек позиций (обычное округление до одного знака, «< 0,1 %» для очень малых).
|
||
- Для разрезов «Секторы» и «Эмитенты» в данных позиций Portfolio появляются сектор и признак эмитента. Это расширение ответа Portfolio новыми необязательными данными; существующие данные позиций и их смысл не меняются. Изменение не является BREAKING.
|
||
|
||
## Scope
|
||
|
||
### In Scope
|
||
|
||
- Вкладка «Концентрация» на странице одного счёта.
|
||
- Разрезы «Акции», «Облигации», «Секторы», «Эмитенты» с топ-5, «Прочее», суммой и долей по элементам, диаграммой распределения и суммарной долей топ-5.
|
||
- Раскрытие «Прочее» по нажатию с полным перечнем остальных элементов.
|
||
- Явные группы «Сектор не указан» и «Эмитент не указан» с видимой долей.
|
||
- Выбор одной валюты, пересчёт всех разрезов вкладки под выбранную валюту.
|
||
- Состояния вкладки при отсутствии позиций в выбранной валюте, при отсутствии нужных данных (сектор, эмитент) и при ошибке или устаревании Portfolio — в рамках уже действующего поведения Portfolio.
|
||
- Расширение данных позиций Portfolio сектором и признаком эмитента (аддитивно).
|
||
- Обновление AS-IS документации домена Portfolio, интеграции T-Bank и глоссария (термины «Концентрация», «Сектор», «Эмитент»).
|
||
|
||
### Out of Scope / Non-Goals
|
||
|
||
- Общий топ-5 по всем типам позиций вместе (исходная формулировка Issue): рейтинги строятся только внутри разрезов «Акции», «Облигации», «Секторы», «Эмитенты».
|
||
- Страна риска и региональное распределение.
|
||
- Сроки погашения облигаций.
|
||
- Лидеры роста и падения, доход по позициям и вклад выплат в доход.
|
||
- Показатель `riskLevel` T-Bank и кредитный рейтинг агентств.
|
||
- Индекс концентрации (HHI) и эффективное число позиций.
|
||
- Конвертация валют, единый рейтинг или единая диаграмма по нескольким валютам.
|
||
- Замена, изменение или повтор существующей «Структуры портфеля» и вкладки «Позиции».
|
||
- Режим «Все счета»: вкладка относится только к странице одного счёта.
|
||
- Изменение порядка, состава и свежести Portfolio Snapshot.
|
||
|
||
## Capabilities
|
||
|
||
### New Capabilities
|
||
|
||
- `specs/portfolio-concentration/spec.md`: вкладка «Концентрация» — разрезы, ранжирование топ-5, «Прочее», доли и суммарная доля топ-5, выбор валюты, правила учёта позиций, состояния.
|
||
|
||
### Modified Capabilities
|
||
|
||
- `specs/portfolio-view/spec.md`: нормализованный состав Portfolio расширяется сектором и эмитентом позиции (требование «Нормализованный состав Portfolio»); добавляются требования о сроке обновления, последнем известном значении и ошибках получения сектора и эмитента. Требование «Точные значения и валютные агрегаты» не меняется; новая capability `portfolio-concentration` на него ссылается.
|
||
|
||
## Impact
|
||
|
||
- Владелец счёта получает новый экран анализа; существующие экраны и их поведение не меняются.
|
||
- Затрагиваются backend (обогащение данных Portfolio), frontend (новая вкладка и её разрезы), specs и AS-IS документация.
|
||
- Ответ Portfolio расширяется аддитивно: клиенты, не знающие новых данных, продолжают работать без изменений. Публичные API-артефакты потребуют обновления.
|
||
- Часовая синхронизация с T-Bank дополнительно получает данные об инструментах и брендах для позиций; это может увеличить число обращений к T-Bank и время синхронизации. Оценка нагрузки и способ получения — в Design.
|
||
- Сбой или неполнота этих данных не должны ухудшать успешность и свежесть Portfolio Snapshot (решено, см. Open Decisions); без новых данных позиции показываются в явных группах «Сектор не указан» и «Эмитент не указан».
|
||
- Сектор и бренд актива обновляются не чаще раза в сутки (значения могут отставать от T-Bank не более чем на сутки плюс интервал часового обхода); при неуспешном обновлении сохраняется последнее известное значение. Пробелы по краям обрезаются, значение из одних пробелов считается отсутствующим. Отказ token при получении сектора или бренда обрабатывается как существующая недействительность подключения T-Bank.
|
||
- На вкладке: в центре диаграммы «Топ-5 · N %» (при шести и более элементах) и сумма разреза, без логотипов и переходов в строках, предупреждение «Данные неполные» при неполном Portfolio; вкладки нет при загрузке, ошибке и пустом Portfolio.
|
||
- Существующие данные Portfolio, порядок позиций и итоги по валютам не меняются.
|
||
|
||
## Success Criteria
|
||
|
||
- На странице счёта вкладка «Концентрация» доступна рядом с «Позиции»; вкладка «Позиции» и «Структура портфеля» выглядят и работают как раньше.
|
||
- В каждом из четырёх разрезов при выбранной валюте при семи и более элементах видны пять строк и «Прочее», при шести или меньше — отдельные строки без «Прочее»; точная сумма строк равна общей сумме разреза в этой валюте.
|
||
- Доля каждого элемента и суммарная доля первых пяти считаются от одной и той же базы, а диаграмма и перечень показывают одни и те же элементы и значения; доли показаны в формате карточек позиций и могут в сумме отличаться от 100 % из-за округления.
|
||
- Суммы точны и не конвертируются: при выборе валюты в разрезах нет позиций других валют.
|
||
- Нажатие на «Прочее» раскрывает все остальные элементы разреза с суммой и долей каждого; состав и порядок топ-5 не меняются.
|
||
- В разрезе «Секторы» присутствуют только позиции `STOCK`, `BOND`, `FUND`; позиции других типов в нём отсутствуют. Позиция этих типов без сектора учитывается в группе «Сектор не указан».
|
||
- Акция и облигация одного эмитента в разрезе «Эмитенты» показываются одним элементом с общей суммой; фонд в этом разрезе отсутствует.
|
||
- Позиция без бренда учитывается в группе «Эмитент не указан», и её доля видна пользователю.
|
||
- Общего топ-5 по всем типам позиций на вкладке нет.
|
||
- Позиция без вычислимой текущей стоимости не влияет на суммы и доли.
|
||
|
||
## Evidence
|
||
|
||
Исследование: `analysis/research.md` (ссылки в формате его источников; здесь не копируются).
|
||
|
||
- [F] Потребность: показать крупнейшие акции, облигации и секторы по денежной оценке с переключением критерия и диаграммой распределения. Источник: запрос Change Owner, WealthLedger/main#48; `analysis/research.md`, Problem Statement.
|
||
- [F] Страница счёта уже содержит распределение по классам активов с выбором одной валюты и вкладку «Позиции» с разделением «Акции / Облигации / Прочее». Источник: `analysis/research.md`, Problem Statement.
|
||
- [F] Каноническая `portfolio-view` фиксирует отсутствие валютной конвертации и отдельные итоги по каждой валюте; позиция без вычислимой текущей стоимости остаётся в ответе, но не входит в агрегаты; в Portfolio входят только позиции с ненулевым количеством. Источник: `specs/portfolio-view/spec.md`, требования «Нормализованный состав Portfolio», «Точные значения и валютные агрегаты».
|
||
- [F] Карточки позиций показывают долю позиции среди позиций той же валюты. Источник: `specs/portfolio-view/spec.md`, требование «Представление карточек позиций на клиенте».
|
||
- [F] Текущие данные позиции Portfolio не содержат сектора и эмитента. Источник: `analysis/research.md` [L4].
|
||
- [F] Сектор есть у инструментов Share, Bond и Etf в интеграционном описании T-Bank. Источник: `backend/src/integrations/tbank/proto/contracts/instruments.proto` (Share, Bond, Etf, поле `sector`).
|
||
- [F] Бренд с компанией и сектором (`Brand`, :1220-1229) доступен в полном описании актива `AssetFull.brand` (:1051-1067). Краткое описание актива `Asset` бренда не содержит, а `BrandData` внутри инструментов хранит только данные логотипа. Ссылка инструмента на актив (`asset_uid`) есть у Share (:776), Bond (:543) и Etf (:657). Источник: тот же `instruments.proto`; `analysis/research.md` [L9].
|
||
- [F] Разрез «Эмитенты» перенесён из Later research в MVP решением Change Owner (комментарий в Issue #48, issuecomment-3077): условие research «после подтверждения issuer identity» снято наличием `AssetFull.brand`.
|
||
- [F] Группировка по эмитенту акций и облигаций описана в публичной справке Т-Инвестиций; секторное распределение подтверждено несколькими продуктами. Источник: `analysis/research.md`, Evidence & Sources [E1, E3, E6, E7].
|
||
- [F] Внешние продукты — источник кандидатов, но не доказательство спроса. Источник: `analysis/research.md`, Target Audience.
|
||
- [H] Бренд актива T-Bank пригоден как идентичность эмитента; полнота бренда на позициях владельца неизвестна. Группировка по совпадающему названию позиций ненадёжна и не используется. Fallback согласован владельцем: нет бренда → «Эмитент не указан»; полнота проверяется в data-mapping.
|
||
- [H] У позиций владельца сектор заполнен в большинстве случаев; доля стоимости без сектора и состав значений (включая «государственные ценные бумаги») неизвестны. Проверяется до Specs на данных Portfolio владельца.
|
||
- [H] Сектор у фондов в данных T-Bank присутствует не всегда. Проверяется вместе с предыдущей гипотезой.
|
||
- [H] Отрицательная текущая стоимость (короткая позиция) возможна в Portfolio. Спецификация допускает отрицательные значения, но наличие таких позиций у владельца не подтверждено.
|
||
- [H] Недоступность сектора или эмитента не должна ломать загрузку Portfolio — по аналогии с логотипом, который является только presentation metadata. Не подтверждено.
|
||
|
||
## Assumptions / Dependencies
|
||
|
||
- Базой для вкладки служит сохранённый Portfolio Snapshot со своей свежестью и статусами; вкладка не запускает собственных обновлений.
|
||
- У вкладки собственный выбор валюты, независимый от «Структуры портфеля» (решение владельца, [комментарий 3079](https://git.personal.ksv741.ru/WealthLedger/main/issues/48#issuecomment-3079)).
|
||
- «Структура портфеля» остаётся отдельным блоком; её замена вкладкой «Концентрация» не планируется.
|
||
- Данные о секторе и бренде берутся из T-Bank; способ получения и хранения — предмет Design.
|
||
- Пять элементов — фиксированный размер топа для всех разрезов; настройка размера не нужна.
|
||
- Элементы разрезов «Акции» и «Облигации» — отдельные позиции; одна и та же бумага на одном счёте с одинаковым FIGI не объединяется (действующее правило `portfolio-view`).
|
||
|
||
## Open Decisions
|
||
|
||
Все вопросы решает Change Owner. Ни один из них не меняет набор разрезов и не требует нового G1.
|
||
|
||
**Решены Change Owner до G1** (дата 2026-10-30; дословные формулировки — [комментарий в Issue #48](https://git.personal.ksv741.ru/WealthLedger/main/issues/48#issuecomment-3077); решения внесены в What Changes):
|
||
|
||
- Эмитент — бренд актива T-Bank; позиции без бренда показываются в группе «Эмитент не указан» с видимой долей. Если бренда нет у многих позиций, разрез остаётся, scope не меняется, новый G1 не нужен.
|
||
- Фонды в разрез «Эмитенты» не входят.
|
||
- Государственные облигации в «Секторах» — по сектору, как его определяет T-Bank, без собственной классификации.
|
||
- «Секторы» включают только `STOCK`, `BOND`, `FUND`; остальные типы позиций в разрез не входят.
|
||
- «Прочее» раскрывается по нажатию с полным перечнем остальных элементов; состав топ-5 не меняется.
|
||
- Общий топ-5 по всем типам из исходного Issue — вне scope.
|
||
- Отклонение от research: там «Эмитенты» были в Later «после подтверждения issuer identity». Условие снято, так как бренд актива T-Bank (`AssetFull.brand`) даёт стабильную идентичность компании; полнота бренда на позициях владельца остаётся гипотезой, её покрывает fallback «Эмитент не указан».
|
||
|
||
**Решены Change Owner до G2** (дата 2026-10-30; дословные формулировки — [комментарий в Issue #48](https://git.personal.ksv741.ru/WealthLedger/main/issues/48#issuecomment-3078); решения внесены в Delta Specs):
|
||
|
||
- Знаменатель доли — сумма учитываемых позиций разреза в выбранной валюте; денежные остатки в него не входят.
|
||
- Позиции с отрицательной стоимостью и без оценки исключаются из ранжирования, долей и диаграммы; сноска показывает, сколько позиций не учтено.
|
||
- Группы «Сектор не указан» и «Эмитент не указан» ранжируются наравне с остальными элементами и заметно обозначены.
|
||
- Отсутствие сектора или эмитента не влияет на успешность и свежесть Portfolio Snapshot, как и логотип; у позиций в таких случаях пустые значения.
|
||
|
||
**Решены Change Owner после G2-review** ([комментарий 3079](https://git.personal.ksv741.ru/WealthLedger/main/issues/48#issuecomment-3079); внесены в Delta Specs):
|
||
|
||
- Вкладка имеет собственный список валют и выбор, независимые от «Структуры портфеля».
|
||
- Доли показываются с округлением карточек позиций; точные доли в сумме дают 100 %.
|
||
- «Прочее» появляется только при семи и более элементах.
|
||
|
||
**Подтверждены Change Owner** ([комментарий 3080](https://git.personal.ksv741.ru/WealthLedger/main/issues/48#issuecomment-3080); внесены в Delta Specs):
|
||
|
||
- Список валют вкладки: валюты ненулевых `currentValue` позиций акций, облигаций и фондов, включая отрицательные; валюта только с нулевой стоимостью в список не входит.
|
||
- В сноске «Не учтено позиций» позиции без оценки считаются при любой выбранной валюте; при пропаже выбранной валюты берётся первая из списка; равные суммы упорядочиваются по названию.
|
||
- Название эмитента — название бренда T-Bank.
|
||
- Подпись сектора `government` — «Государственный сектор» (добавление WealthLedger к подписям скринера).
|
||
|
||
**Подтверждены Change Owner** ([комментарий 3081](https://git.personal.ksv741.ru/WealthLedger/main/issues/48#issuecomment-3081); внесены в Delta Specs):
|
||
|
||
- Эмитент заполняется у фондов в данных Portfolio, разрез «Эмитенты» их отбрасывает.
|
||
- Отказ token при получении сектора или бренда — как существующая недействительность подключения.
|
||
- Сектор и бренд обновляются раз в сутки; при ошибке сохраняется последнее известное значение.
|
||
- Пробелы обрезаются; при разных названиях одного эмитента берётся название позиции с наибольшей стоимостью.
|
||
- Разрез и валюта сохраняются в пределах страницы счёта; выбор валюты скрыт при одной валюте; метрика «доля топ-5» скрыта при пяти и менее элементах; при неполных данных — предупреждение «Данные неполные»; в центре диаграммы «Топ-5 · N %» и сумма; в «Эмитентах» без логотипов и переходов.
|
||
|
||
Открытых решений нет.
|