Files
docs/domains/portfolio/data-reference.md
T
ksv741 97069d6f6d
Docs security / security (pull_request) Successful in 6s
Docs verify / verify (pull_request) Successful in 11s
Conventional commits / commits (pull_request) Successful in 16s
Docs security / security (push) Successful in 9s
Docs verify / verify (push) Successful in 10s
docs: make documentation checks self-contained
2026-09-15 20:45:40 +03:00

11 KiB
Raw Blame History

Данные и показатели портфеля

Этот справочник объясняет значения снимка одного счёта. Он нужен при чтении экрана, API-ответа или разборе расхождения сумм. Для общего портфеля действуют те же денежные правила, но данные счетов получаются не одновременно.

Точные значения и неизвестность

Деньги представлены значением Money: ISO-код валюты и десятичная строка, например { "currency": "RUB", "value": "12500.5" } — условный пример. Количества также передаются десятичными строками. Backend выполняет десятичную арифметику без промежуточного Number, нормализует отрицательные целую и дробную части и убирает незначащие конечные нули. Экспоненциальной записи нет. Frontend форматирует полученные строки в русской локали без сокращения, округления сумм и потери присланных дробных цифр.

null означает, что показатель нельзя определить из доступных данных. Это не ноль. Известная нулевая цена отличается от отсутствующей; позиция с ненулевым количеством и неизвестной стоимостью остаётся в составе. Несколько валют никогда не складываются в одну общую стоимость.

Состав и денежные показатели

Понятие или показатель Смысл и источник Ограничение
Позиция Ненулевое количество обычного инструмента из GetPortfolio.positions Виртуальные позиции не включаются; порядок источника сохраняется
quantity Количество из текущей позиции брокера Допустимы дробные и отрицательные количества; это не число лотов
currentValue Количество × текущая цена из GetPortfolio null, если цена или её валюта недоступны
averagePurchasePrice Средняя цена позиции, переданная брокером Это цена единицы, а не сумма затрат или рассчитанная приложением история покупок
absoluteReturn Количество × (текущая цена − средняя цена) Требует обеих цен в одной известной валюте; не включает продажи, купоны и дивиденды
Cash Balance Суммы из GetPositions.money, объединённые по валюте Заблокированные деньги не прибавляются; торгуемый инструмент CURRENCY остаётся позицией
totalsByCurrency Стоимости позиций + доступные деньги той же валюты Не включает невычислимую стоимость; не обещает полную оценку портфеля
lastSuccessfulAt Время формирования успешного снимка, UTC Не является временем каждой котировки; запасной снимок сохраняет исходное время
isStale Backend вернул предыдущий полный снимок после временной ошибки Не описывает состояние клиентского кэша или ошибку фонового запроса

Ненулевые денежные остатки одной валюты суммируются. Позиции одинаковых инструментов в ответе отдельного счёта не объединяются; визуальная группировка между счетами описана отдельно. Сводка уже включает Cash Balance: прибавление денег к ней второй раз неверно.

При отсутствии вычислимой стоимости у части позиций известный итог остаётся полезен, но представляет только оценённую часть. Известные нулевые итоги отдельного счёта не создают валютные карточки. Если totalsByCurrency пуст, но позиции или деньги присутствуют, это не пустой портфель.

Идентификация и оформление инструмента

UID определяет конкретный инструмент брокера и используется для перехода на его страницу. FIGI, ISIN и тикер сохраняются как доступные идентификаторы; одно название или совпадение тикера не доказывает тождество инструментов. Для получения метаданных backend сначала использует UID, затем FIGI. Отображаемое имя выбирается в порядке: полное имя, тикер, FIGI. Если нет и FIGI, текущая реализация использует Unknown instrument.

ISIN, тикер и logoName могут быть null. logoName — имя файла бренда, а не URL: frontend строит ссылку на публичный CDN. Ошибка изображения или метаданных не меняет количество, суммы и свежесть снимка и не скрывает финансовые данные. Имя ожидается перед завершением нового снимка; ошибка поиска оставляет доступный идентификатор.

Структура и доли

structure распределяет стоимость по четырём категориям: акции (STOCK), облигации (BOND), прочие инструменты (OTHER) и деньги (CASH). Торгуемые валютные инструменты входят в OTHER; денежные остатки — в CASH. Сервер строит структуру из позиций и денег, без повторного добавления totalsByCurrency.

Доля категории — её стоимость / известная стоимость позиций и денег в выбранной валюте × 100. Backend округляет процент до шести знаков; frontend показывает до сотых. Положительное значение меньше 0,01% отображается как «< 0,01 %», если серверное округление не превратило его в ноль. В геометрию диаграммы передаются только числовые проценты; суммы в списке и подсказке форматируются из исходных точных строк.

Доля на карточке отдельной позиции использует другой знаменатель: сумму стоимостей всех позиций той же валюты без денег. Это приблизительный показатель для отображения, рассчитанный frontend. Он не изменяет Money. В режиме всех счетов знаменатель охватывает все показанные счета.

Состояние Доступное представление
Все составляющие оценены, неотрицательны, итог положителен Суммы, доли и кольцевая диаграмма выбранной валюты
Есть позиция без оценки unvaluedCategories содержит её категорию и количество; суммы известной части остаются, доли и кольцо недоступны для всех валют
Есть отрицательная составляющая Суммы со знаком остаются; доли и кольцо отключены для её валюты, даже если итог категории положителен
Состав пуст или имеет нулевую стоимость Текстовое состояние вместо кольца

Неоценённой позиции нельзя достоверно назначить валюту по её стоимости, поэтому ограничение долей действует на все валюты. В общем портфеле проверка отрицательных денег выполняется по остаткам счетов до взаимозачёта.

Нормативные основы: нормализованный состав и точные значения и валютные агрегаты. Структура и общий режим подтверждены реализацией и её проверками; отдельных требований к ним в основной спецификации портфеля пока нет. Поля транспорта следует сверять с HTTP API, а свежесть — с потоком загрузки.