docs: reorganize system knowledge by domain
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
# Облигации
|
||||
|
||||
Страница облигации объясняет условия конкретного выпуска, его рыночную цену,
|
||||
купонный календарь и личную позицию. Денежная оценка покупки, текущая купонная
|
||||
доходность, доходность источника к целевой дате и результат открытой позиции
|
||||
имеют разный смысл. Раздел сохраняет их отдельно, вместе с валютой,
|
||||
датой и ограничениями исходных данных.
|
||||
|
||||
## Поиск и идентификация выпуска
|
||||
|
||||
Раздел «Облигации» открывает `/bonds`: поиск по названию, тикеру или ISIN
|
||||
с двух символов. `/bonds/:identifier` принимает UID или точный тикер.
|
||||
Название и логотип облигации в портфеле счёта и «Всех счетах» ведут на её
|
||||
страницу по точному UID без предварительной загрузки карточек всех позиций.
|
||||
При открытии выпуска проверенный однозначный тикер заменяет UID в адресе,
|
||||
сохраняя период графика и фильтр событий.
|
||||
|
||||
Поиск выбирает один режим на нормализованный ISIN, сохраняя разные выпуски
|
||||
и записи без ISIN отдельно. Приоритет: доступность API, точный тикер, TQOB,
|
||||
затем UID. Ограничение — 30 результатов после выбора режима. Цена и ссылка
|
||||
принадлежат выбранному UID. Прямая ссылка из портфеля сохраняет исходный UID,
|
||||
если поиск предпочитает другой режим. Неоднозначный точный тикер возвращает
|
||||
`409 BOND_TICKER_AMBIGUOUS`; интерфейс предлагает выбрать выпуск через поиск.
|
||||
Поиск загружает параметры выпусков и котировки, но оставляет ссылки по UID:
|
||||
отдельная проверка тикера для каждого результата не выполняется.
|
||||
|
||||
## Содержание
|
||||
|
||||
Карточка показывает цену в процентах от номинала, время котировки и статус
|
||||
торгов. Изменение выражено в процентных пунктах относительно последней
|
||||
завершённой дневной свечи до московской даты котировки; база ищется за 20 дней.
|
||||
Денежная оценка без НКД равна цене в процентах, умноженной на текущий номинал
|
||||
и делённой на 100. Она округляется до девяти десятичных знаков. Оценка с НКД
|
||||
добавляет текущий накопленный купонный доход только при совпадении валют.
|
||||
Это ориентир без комиссии: котировка может быть старше текущего номинала и НКД.
|
||||
FX-конвертация не выполняется, первоначальный номинал не заменяет текущий.
|
||||
|
||||
Условия выпуска: текущий и первоначальный номинал, погашение, оферта,
|
||||
количество купонов в год, лот. Отдельно отмечены плавающий купон,
|
||||
амортизация, бессрочность и субординация. Неизвестные даты и суммы показываются
|
||||
как недоступные.
|
||||
|
||||
Сводка «Купон, рейтинг и доходность» показывает ближайший купон на одну
|
||||
облигацию, дату выплаты и тип из календаря Т-Банка. Неизвестная сумма ближайшей
|
||||
выплаты не заменяется суммой более позднего купона. Флаг плавающего купона
|
||||
используется только как запасной признак типа; отсутствие флага не означает
|
||||
фиксированный купон.
|
||||
|
||||
Текущая купонная доходность — ближайший купон × 365 / длительность его периода
|
||||
в днях / денежная цена без НКД × 100 %. Decimal-расчёт округляется до четырёх
|
||||
знаков. Требуются известная неотрицательная выплата, положительные цена и
|
||||
период и одинаковая валюта выплаты и цены. Это годовая оценка при сохранении
|
||||
размера купона и номинала, без налогов, комиссий и реинвестирования; она не
|
||||
является доходностью к погашению. Время котировки показывается отдельно.
|
||||
|
||||
Эффективная доходность берётся из `marketdata_yields.EFFECTIVEYIELD` [MOEX ISS](../../integrations/moex.md),
|
||||
с проверкой точных SECID, ISIN и BOARDID. Показываются собственная цена
|
||||
расчёта, дата торгов и целевая дата (погашение, оферта или другая дата источника).
|
||||
Котировка MOEX может отличаться от котировки Т-Банка и поступать с задержкой.
|
||||
Доходность не рассчитывается из неполного календаря будущих выплат.
|
||||
|
||||
Кредитный рейтинг выпуска читается по точному ISIN из публичного
|
||||
[реестра НКР](../../integrations/nkr.md). Отображаются агентство,
|
||||
дата рейтингового действия, время получения реестра и ссылка на выпуск.
|
||||
Отзыв показывается явно; уровень риска Т-Банка и рейтинг эмитента не
|
||||
подставляются вместо рейтинга выпуска. Отсутствие записи в НКР не означает
|
||||
отсутствия рейтингов других агентств. Причины выбора источника и пределы
|
||||
покрытия сохранены в [ADR 013](../../adr/013-nkr-bond-credit-ratings.md).
|
||||
|
||||
HTML-источник, общий кэш и поведение при изменении реестра описаны в
|
||||
[интеграции НКР](../../integrations/nkr.md#загрузка-кэш-и-отказ-источника).
|
||||
|
||||
График и таблица дневных цен сохраняют проценты от номинала и признак
|
||||
завершённости свечи. Исторические котировки не пересчитываются в деньги
|
||||
по сегодняшнему номиналу. Денежная средняя покупки не наносится на процентную
|
||||
шкалу. Периоды: месяц, полгода, год и вся известная история. Окна upstream
|
||||
не превышают 365 дней, одинаковые границы дедуплицируются. Если начало истории
|
||||
неизвестно, запрос «вся история» возвращает `BOND_HISTORY_START_UNAVAILABLE`.
|
||||
|
||||
Позиция агрегирует только `BOND` с точным UID по доступным счетам, используя
|
||||
[снимок портфеля](../portfolio/overview.md) и decimal-арифметику. Средняя покупка взвешена
|
||||
по количеству. Неполные или разновалютные суммы недоступны; общая средняя
|
||||
и процент доступны только при положительных включённых позициях. Для
|
||||
коротких позиций и сочетания длинных с короткими эти показатели не синтезируются.
|
||||
Результат открытой позиции не включает выплаченные купоны и продажи и не
|
||||
называется доходностью к погашению. При отсутствии позиции блок скрыт.
|
||||
|
||||
## Купоны и личные события
|
||||
|
||||
Календарь охватывает пять прошлых лет и следующий год. Будущие купоны
|
||||
сортируются по дате выплаты, прошедшие и недатированные доступны отдельно.
|
||||
Показаны сумма на облигацию, номер, тип, длительность периода и дата реестра,
|
||||
если они известны. Неопределённый будущий купон не заменяется нулём.
|
||||
|
||||
Личная оценка доступна только при положительных позициях, известной сумме,
|
||||
будущей выплате и известном ещё не прошедшем реестре. Она не подтверждает право
|
||||
на выплату и не учитывает налоги и будущие сделки. Время позиции и устаревание
|
||||
снимка показываются отдельно от календаря выпуска.
|
||||
|
||||
Личная история использует [журнал операций](../operations/overview.md) всех счетов с точным
|
||||
`instrumentUid`, включая прошлые годы. Фильтры: все, сделки, купоны, прочее.
|
||||
Смена фильтра сбрасывает пагинацию; истёкший курсор восстанавливается запросом
|
||||
первой страницы. Выплаты выпуска не подменяют личные зачисления.
|
||||
|
||||
## Получение данных и восстановление
|
||||
|
||||
Страницу облигации обслуживает инвестиционная подсистема backend.
|
||||
Запросы `/api/v1/bonds` требуют действующей сессии с Bearer token и текущего
|
||||
подключения T-Bank. Backend разрешает идентификатор и получает условия
|
||||
выпуска, котировку, свечи, позицию, купоны и показатели. Точную форму
|
||||
транспортного контракта задаёт [HTTP API](../../architecture/http-api.md).
|
||||
|
||||
`BondBy`, `FindInstrument` и `GetBondCoupons` используют способ
|
||||
декодирования, сохраняющий отсутствие полей. Рыночные RPC проходят
|
||||
общие TLS, очередь, ограничение частоты, deadline и повторные попытки. Кэш успешных и совместных
|
||||
незавершённых запросов ограничен LRU и сроком 30 секунд по пользователю,
|
||||
поколению подключения и параметрам. Ошибки не кэшируются; ошибки авторизации
|
||||
не подавляются при дополнительной загрузке данных поиска.
|
||||
Исходный ответ `BondBy` совместно используется поиском, карточкой, котировкой,
|
||||
графиком, купонами и сводкой показателей в пределах того же пользователя, поколения и TTL.
|
||||
Одновременная загрузка секций вызывает один `BondBy` на UID. Календарь
|
||||
и сводка совместно используют один запрос купонов; котировка переиспользуется
|
||||
при расчёте купонной доходности. MOEX и НКР загружаются только для открытого
|
||||
выпуска, независимо от поиска. Для 30 новых
|
||||
результатов поиск выполняет 32 RPC до повторных попыток: один `FindInstrument`,
|
||||
30 `BondBy` и один пакетный запрос цен. Общий ограничитель backend не заменяет
|
||||
квоты Т-Банка; при их исчерпании сохраняется `TBANK_UNAVAILABLE`.
|
||||
|
||||
Разделы загружаются независимо, показывают каркас загрузки и локальную повторную попытку.
|
||||
Ошибка фонового обновления сохраняет последние данные. Смена подключения
|
||||
сбрасывает поддерево клиентских запросов облигаций вместе с остальными финансовыми запросами;
|
||||
выход очищает кэш сессии. Общие график, позиция и личные события
|
||||
имеют общее представление на страницах акций и облигаций.
|
||||
|
||||
Основные спецификации [портфеля](../../../specs/openspec/specs/portfolio-view/spec.md)
|
||||
и [журнала](../../../specs/openspec/specs/brokerage-account-ledger/spec.md)
|
||||
описывают исходные финансовые понятия. Отдельная основная спецификация
|
||||
страницы облигации в текущем OpenSpec Store не найдена; условия вычислений
|
||||
подтверждены [сервисом облигаций](../../../backend/src/tbank/bond.service.ts)
|
||||
и его [проверками](../../../backend/src/tbank/bond.service.spec.ts).
|
||||
Границы источников описаны в [разделе интеграций](../../integrations/README.md),
|
||||
сходное разделение рыночных и личных данных — в [акциях](stocks.md).
|
||||
@@ -0,0 +1,172 @@
|
||||
# Акции
|
||||
|
||||
Страница акции связывает три разных вида сведений: публичные данные
|
||||
конкретного выпуска и компании, текущую личную позицию и исполненную
|
||||
историю операций. Публичная цена и календарь дивидендов доступны даже без
|
||||
открытой позиции; личная часть относится только к счетам текущего
|
||||
подключения T-Bank. Эти сведения не заменяют друг друга и имеют разное время
|
||||
наблюдения.
|
||||
|
||||
## Поиск и точная бумага
|
||||
|
||||
Авторизованный пользователь открывает `/stocks/SBERP` по тикеру. Старые
|
||||
адреса `/stocks/:uid` продолжают работать. Сервер возвращает `slug`: проверенный
|
||||
однозначный тикер либо исходный UID. При открытии UUID-ссылки страница заменяет
|
||||
адрес на тикер только при совпадении UID, сохраняя период и фильтр событий.
|
||||
Прямое открытие и обновление страницы с тикером сначала разрешает его в UID;
|
||||
цены, позиция и личные операции затем запрашиваются только по этому UID.
|
||||
Ссылки находятся в названиях и логотипах акций отдельного портфеля и обзора
|
||||
«Все счета». Названия сохраняют обычный цвет текста; буквенная заглушка
|
||||
логотипа также ведёт на страницу акции. Карточки получают проверенный `slug`
|
||||
через запрос акции по UID: при подтверждённом тикере обе ссылки используют
|
||||
его, иначе сохраняют UID. Одинаковые UID в разных счетах используют один запрос и общий
|
||||
кэш страницы акции. До загрузки и при ошибке остаётся рабочая ссылка по UID;
|
||||
загрузка адресов не блокирует портфель.
|
||||
Раздел «Акции» в боковой и мобильной навигации ведёт на `/stocks`: поиск
|
||||
по названию или тикеру через каталог Т-Банка, начиная с двух символов.
|
||||
Результаты разных выпусков, включая обыкновенные и привилегированные акции,
|
||||
имеют отдельные UID. Карточка результата показывает логотип, последнюю цену
|
||||
с её временем, тип бумаги, площадку, код режима, ISIN и доступность торгов через
|
||||
API. Поиск показывает одну карточку на нормализованный ISIN. До ограничения
|
||||
в 30 результатов выбирается представитель выпуска: доступность через API,
|
||||
точное совпадение тикера, затем режим TQBR; равные варианты упорядочены по UID.
|
||||
Записи без ISIN сохраняются отдельно по UID. Обыкновенные и привилегированные
|
||||
акции с разными ISIN не объединяются. Цена и ссылка принадлежат выбранному
|
||||
UID; данные разных режимов не смешиваются. Прямые ссылки из портфеля сохраняют
|
||||
исходный UID, даже если поиск выбрал другой режим этого выпуска; такая страница
|
||||
сохраняет UUID в адресе. Если один точный тикер относится к разным выпускам,
|
||||
сервер возвращает `409 STOCK_TICKER_AMBIGUOUS`, а страница предлагает поиск.
|
||||
Поиск тикера нечувствителен к регистру, но использует точное совпадение:
|
||||
SBER не заменяется на SBERP. Однобуквенные тикеры также поддерживаются.
|
||||
Прямая ссылка не требует предварительного открытия портфеля. Хлебные крошки
|
||||
«Акции → название» возвращают к поиску.
|
||||
|
||||
## Содержание и состояния
|
||||
|
||||
Верхний блок объединяет название, тип акции, текущую цену и показатели компании.
|
||||
Денежные показатели используют символ валюты; описание компании видно сразу
|
||||
под логотипом и названием, перед ценой. Далее идут график, моя позиция, предстоящие
|
||||
дивиденды и личная история событий.
|
||||
Логотип загружается из публичного CDN; при отсутствии изображения показывается буквенная заглушка.
|
||||
Позиция отсутствующей или полностью проданной бумаги не создаёт пустого блока;
|
||||
рыночные данные и личная история остаются доступны.
|
||||
|
||||
Каждый раздел загружается независимо. Первичная загрузка показывает каркас
|
||||
раздела, ошибка — локальную повторную попытку. При ошибке фонового обновления
|
||||
сохраняются предыдущие данные и предупреждение. Цена содержит собственное время
|
||||
UTC, которое может быть старше времени получения ответа. Статус торгов не
|
||||
выводится из свежести цены. Отсутствующее значение не заменяется нулём.
|
||||
|
||||
## Связь с портфелем и операциями
|
||||
|
||||
Серверная инвестиционная подсистема предоставляет поиск, карточку инструмента,
|
||||
котировку, дневные свечи, сводку позиции, дивиденды и доступные данные компании.
|
||||
Все запросы `/api/v1/stocks` требуют действующей сессии с Bearer token и актуального подключения
|
||||
T-Bank; точные маршруты и поля принадлежат [HTTP API](../../architecture/http-api.md).
|
||||
Frontend не получает брокерский токен и не обращается к T-Bank напрямую.
|
||||
|
||||
Личная история использует существующий
|
||||
`GET /api/v1/brokerage-accounts/all/operations?instrumentUid=...`.
|
||||
Фильтр UID валидируется и передаётся upstream как `instrumentId`; ответ также
|
||||
проверяется по UID. Без `from` такой запрос начинается с самой ранней известной
|
||||
даты открытия доступных счетов; если даты неполны, нижняя граница — Unix epoch.
|
||||
Обычный журнал без фильтра инструмента сохраняет начало текущего года.
|
||||
UID включён в ключ кэша и подпись общего курсора: курсор другой бумаги,
|
||||
пользователя, поколения подключения или фильтра отклоняется. Истечение курсора
|
||||
восстанавливается переходом на первую страницу с повторным запросом.
|
||||
|
||||
[Портфель](../portfolio/overview.md) остаётся владельцем снимков и оценки позиций. Сводка
|
||||
фильтрует `STOCK` по точному UID и использует точную десятичную арифметику, без конвертации валют.
|
||||
Средняя цена равна сумме количеств, умноженных на средние цены, делённой на
|
||||
общее количество; она округляется сервером до девяти знаков, проценты — до шести.
|
||||
Неполные или разновалютные денежные итоги недоступны. Общая средняя и процент доступны только если все включённые позиции
|
||||
положительны; для нулевого количества, коротких позиций и сочетания
|
||||
длинных с короткими они не синтезируются.
|
||||
Результат открытой позиции исключает продажи и дивиденды и не называется полной
|
||||
доходностью. Время и `isStale` сохраняют семантику исходного Portfolio Snapshot.
|
||||
|
||||
## Рыночная цена и график
|
||||
|
||||
Изменение рассчитывается относительно последней завершённой дневной свечи
|
||||
строго до календарной даты последней цены по Москве. Поиск базы охватывает
|
||||
20 дней до последней цены; если подходящей свечи нет, сравнение недоступно.
|
||||
Дата базы указана рядом с изменением. `GetClosePrices` не используется:
|
||||
его основное закрытие может относиться к текущему дню.
|
||||
|
||||
График показывает дневные `close`, сохраняет `isComplete` и предупреждает
|
||||
о формирующейся свече. Окна RPC не превышают 365 дней, общие границы
|
||||
дедуплицируются. «Вся история» начинается с `first_1dayCandleDate`; если источник
|
||||
не сообщает начало истории, этот период недоступен, остальные работают.
|
||||
Пустое окно до начала торгов не считается ошибкой. Линия текущей средней
|
||||
покупки доступна только в валюте графика; шкала включает её значение.
|
||||
Таблица цен раскрывается под графиком: новые даты первыми, валюта в цене,
|
||||
статус завершённости свечи, закреплённая шапка и прокрутка с клавиатуры.
|
||||
Стили графиков подключены на уровне приложения и каталога, поэтому оформление
|
||||
подсказки не зависит от ранее посещённых страниц.
|
||||
|
||||
Метки старых сделок и дивидендов на графике не добавлены: соответствие шкалы
|
||||
после корпоративных изменений не подтверждено. Лента использует дату операции;
|
||||
количество сделки берётся из `quantityDone`, а не порученного `quantity`.
|
||||
Отсутствующее исполненное количество не подменяется порученным. Сами исполнения
|
||||
не превращаются в точные точки графика.
|
||||
|
||||
## Дивиденды и финансовые показатели
|
||||
|
||||
События компании отделены от личных зачислений. Известные будущие выплаты
|
||||
определяются по `paymentDate`, при её отсутствии — по `recordDate`; прошедшие
|
||||
и недатированные события помещены в отдельную историю компании. Отменённые
|
||||
события исключаются. Личная оценка умножает сумму на акцию на текущее положительное
|
||||
количество. Для уже прошедшего реестра оценка не строится. Время позиции и
|
||||
предупреждение об устаревшем снимке или недоступной оценке показаны отдельно.
|
||||
|
||||
Оценка не доказывает право на выплату, не учитывает будущие сделки и не обещает
|
||||
индивидуальную дату зачисления. Статусы «рекомендован/утверждён», сумма отдельного
|
||||
зачисления после налога и налоговый смысл `dividend_net` не выводятся из API.
|
||||
Пустой список означает отсутствие известных событий только за указанный период.
|
||||
|
||||
`GetAssetFundamentals` использует отдельный способ декодирования ответа,
|
||||
который сохраняет отсутствие полей (`defaults: false`). Это важно для
|
||||
отличия неизвестного показателя от известного нуля; настройка остальных
|
||||
клиентов при этом не изменяется. Финансовый сектор
|
||||
показывает капитализацию, P/E, P/B, ROE и чистую прибыль; остальные — капитализацию,
|
||||
P/E, выручку, EBITDA, чистую прибыль, общий долг и чистый долг / EBITDA, если
|
||||
значения доступны. Денежные показатели без валюты не показываются.
|
||||
TTM означает последние 12 месяцев, MRQ — последний отчётный квартал;
|
||||
время получения не выдаётся за дату отчётности. Годовых финансовых рядов нет.
|
||||
|
||||
## Получение данных и ограничения
|
||||
|
||||
Запросы T-Bank проходят общую серверную интеграцию с TLS, лимитом частоты,
|
||||
очередью, предельным временем ожидания и повторными попытками. Проверка доступа
|
||||
и расшифровка token выполняются только backend. Успешные ответы и совместные незавершённые запросы кэшируются
|
||||
в ограниченном кэше LRU на 30 секунд по пользователю, поколению подключения и параметрам.
|
||||
Для поиска `FindInstrument` дополняется сведениями `ShareBy` через тот же
|
||||
кэш карточки инструмента и одним пакетным `GetLastPrices` для списка. Ошибка
|
||||
дополнительной загрузки или исчезнувшая карточка не скрывает исходную запись
|
||||
каталога; недоступные логотипы и цены имеют заглушки. Ошибки авторизации
|
||||
не подавляются.
|
||||
Ошибка целого запроса не кэшируется; отсутствие дополнительного источника
|
||||
обозначается в ответе. Поддерево клиентских запросов акций сбрасывается вместе с финансовыми
|
||||
данными при изменении подключения; выход очищает кэш сессии.
|
||||
|
||||
Полные даты в интерфейсе имеют формат ДД.ММ.ГГГГ; ISO-формат транспорта и
|
||||
временные зоны расчётов не меняются. Личная история использует общий с портфелем формат строки операции,
|
||||
дополненный количеством, ценой и ссылкой на счёт. История
|
||||
дивидендов компании раскрывается в оформленном блоке с отдельными карточками
|
||||
выплат, датой реестра, доступной датой выплаты и суммой на акцию.
|
||||
Ограничения источника требуют различать отсутствие финансового поля и ноль.
|
||||
Время получения не подтверждает дату отчётности, а совпадение даты не позволяет
|
||||
однозначно связать налог с отдельным дивидендом.
|
||||
Алгоритм корректировки исторических цен после корпоративных событий не
|
||||
подтверждён, поэтому точное наложение старых личных сделок на график не обещается.
|
||||
Доступность данных по отдельным бумагам не доказывает полноту покрытия рынка.
|
||||
История открытых счетов не обещает полную историю владения, включая закрытые
|
||||
счета, переводы и универсальные корпоративные события.
|
||||
|
||||
Основные спецификации [портфеля](../../../specs/openspec/specs/portfolio-view/spec.md)
|
||||
и [журнала](../../../specs/openspec/specs/brokerage-account-ledger/spec.md)
|
||||
задают исходные финансовые понятия. Отдельная основная спецификация страницы
|
||||
акции в текущем OpenSpec Store не найдена; описанные механизмы проверяются
|
||||
по [сервису акций](../../../backend/src/tbank/stock.service.ts) и его
|
||||
[проверкам](../../../backend/src/tbank/stock.service.spec.ts).
|
||||
Сопоставление с облигациями — на [странице облигаций](bonds.md).
|
||||
Reference in New Issue
Block a user