# Аналитика прибыльности брокерского счёта Дата: 2026-06-24 Статус: реализовано Эпик: [Портфель брокера](../../epics/BrokerPortfolio.md) ## Цель Дать пользователю брокерского счёта T-Bank отдельный раздел, где можно увидеть агрегированную аналитику прибыльности портфеля: сколько всего было вложено (нетто), сколько получено (дивиденды + купоны) и общую доходность. ## Пользовательский результат Пользователь может: - открыть вкладку `Аналитика` внутри брокерского счёта; - увидеть, сколько всего денег было внесено на счёт (пополнения); - увидеть, сколько всего денег было выведено со счёта; - увидеть нетто-вложения (пополнения минус выводы); - увидеть сумму полученных дивидендов; - увидеть сумму полученных купонов; - увидеть общую сумму полученного дохода (дивиденды + купоны); - увидеть доходность в процентах от нетто-вложений. ## Область изменений Фича относится только к брокерским счетам T-Bank и включает: - новый backend endpoint `GET /api/v1/broker/accounts/:accountId/analytics`; - новый сервис `BrokerAnalyticsService` с агрегацией через raw SQL; - новую вкладку `Аналитика` в навигации брокерского счёта; - страницу аналитики с отображением вложений, полученного дохода и сводки. ## Требования ### 1. Источники данных - Все данные агрегируются из таблицы `BrokerOperation`. - Для расчёта вложений используются операции с типами пополнений (`OPERATION_TYPE_INPUT` и аналоги) и выводов (`OPERATION_TYPE_OUTPUT` и аналоги). - Для расчёта полученного дохода используются операции с типами дивидендов (`OPERATION_TYPE_DIVIDEND`, `OPERATION_TYPE_DIV_EXT`) и купонов (`OPERATION_TYPE_COUPON`). - Данные считаются «навсегда»: без фильтра по дате, за всё время существования счёта. - Аналитика read-only и не изменяет данные. ### 2. Endpoint - `GET /api/v1/broker/accounts/:accountId/analytics` — возвращает агрегированные показатели. - Кешируется с TTL 5 минут (как существующие broker-эндпоинты). - При отсутствии счёта возвращает 404. ### 3. Показатели Endpoint возвращает: | Поле | Описание | |------|----------| | `totalDeposits` | Сумма всех пополнений счёта | | `totalWithdrawn` | Сумма всех выводов со счёта | | `netInvested` | `totalDeposits − totalWithdrawn` (нетто-вложения) | | `totalDividends` | Сумма полученных дивидендов | | `totalCoupons` | Сумма полученных купонов | | `totalReceived` | `totalDividends + totalCoupons` | | `totalReturnPercent` | `(totalReceived / netInvested) × 100`, если `netInvested > 0`, иначе `null` | | `currency` | Валюта (RUB) | ### 4. Агрегация - Запрос выполняется одним агрегирующим запросом к таблице `BrokerOperation`. - Из выборки исключаются операции с `payment IS NULL`. - Учитываются только исполненные операции (state = `OPERATION_STATE_EXECUTED` или `null`). ### 5. Вкладка - В навигации брокерского счёта появляется вкладка `Аналитика` рядом с `События`. - Вкладка использует `useBrokerAccountContext()` для получения `accountId`. - Страница показывает три блока: 1. **Вложено** — пополнения, выводы, нетто-итог 2. **Получено** — дивиденды, купоны, итог 3. **Сводка** — нетто-вложения, полученный доход, доходность в процентах ### 6. Пустые состояния и ошибки - Если аналитика недоступна (нет операций), показывается пустое состояние. - Если нетто-вложения равны нулю, `totalReturnPercent` не показывается. - Ошибка загрузки не ломает навигацию счёта. ## Ограничения - Фича работает только внутри маршрутов `/broker/:accountId/*`. - Ручные портфели `PortfolioModule` не входят в область фичи. - Фича не учитывает налоги, комиссии и валютную конвертацию. - Фича не учитывает нереализованную прибыль/убыток по текущим позициям. - Доходность считается только по полученным выплатам (дивиденды + купоны), без учёта изменения цены бумаг. ## Acceptance Criteria - На странице брокерского счёта есть вкладка `Аналитика`. - Вкладка показывает нетто-вложения (пополнения минус выводы). - Вкладка показывает сумму полученных дивидендов. - Вкладка показывает сумму полученных купонов. - Вкладка показывает общую сумму полученного дохода. - Доходность в процентах отображается, если нетто-вложения > 0. - Данные кешируются на 5 минут. - Пустое состояние отображается при отсутствии данных. - Ошибка загрузки не ломает навигацию. ## Вне области фичи - учёт налогов и комиссий; - нереализованная прибыль/убыток по текущим позициям; - ручные портфели; - мультивалютность; - графики и визуализация динамики; - экспорт данных.