totalsByCurrency (tbank-portfolio.mapper.ts) суммирует cash из getPositions().moneyи все позиции портфеля, включая CURRENCY (RUB000UTSTOM, USD800UTSTOM), которые являются тем же кэшем. portfolioStructure кладёт CURRENCY в OTHER, а кэш — в CASH. Завышенные totals сохраняются в TbankPortfolioValuePoint и складываются в сводке «все счета».
dev.db, счёт 2197225275: фонд 120.24 + cash 1.25 → сохранено 122.74 вместо 121.49.
brokerage-accounts.service.ts уже исключает CURRENCY ("must not duplicate the separately returned cash balances"), totals/structure — нет.
unrealizedReturnByCurrency.percent делит на cost basis avgPrice × quantity, который у короткой позиции отрицателен: qty −2, avg 100, current 110 → absolute −20, cost −200, percent +10 (убыток показан как прибыль). Лонг и шорт одной валюты взаимно гасят cost basis.
structure не содержит CURRENCY позиций в OTHER; кэш учитывается только в CASH.
percent = null, если в валюте есть позиция с quantity ≤ 0 (как в instrument-position.ts).
Regression-тесты: currency position + cash; короткая позиция.
Out of scope
Уже сохранённые точки TbankPortfolioValuePoint (решение отдельно).
Blocked cash, НКД, FX-конвертация.
Уточнение формулировки specs/portfolio-view («сумма позиций и Cash Balance») — follow-up в specs; связано с WealthLedger/frontend#59.
## Problem
1. `totalsByCurrency` (`tbank-portfolio.mapper.ts`) суммирует cash из `getPositions().money` **и** все позиции портфеля, включая `CURRENCY` (`RUB000UTSTOM`, `USD800UTSTOM`), которые являются тем же кэшем. `portfolioStructure` кладёт `CURRENCY` в `OTHER`, а кэш — в `CASH`. Завышенные totals сохраняются в `TbankPortfolioValuePoint` и складываются в сводке «все счета».
- dev.db, счёт 2197225275: фонд 120.24 + cash 1.25 → сохранено 122.74 вместо 121.49.
- `brokerage-accounts.service.ts` уже исключает `CURRENCY` ("must not duplicate the separately returned cash balances"), totals/structure — нет.
2. `unrealizedReturnByCurrency.percent` делит на cost basis `avgPrice × quantity`, который у короткой позиции отрицателен: qty −2, avg 100, current 110 → absolute −20, cost −200, percent `+10` (убыток показан как прибыль). Лонг и шорт одной валюты взаимно гасят cost basis.
## Acceptance Criteria
- [ ] `totalsByCurrency` = сумма currentValue не-`CURRENCY` позиций + Cash Balance по валюте.
- [ ] `structure` не содержит `CURRENCY` позиций в `OTHER`; кэш учитывается только в `CASH`.
- [ ] `percent` = `null`, если в валюте есть позиция с quantity ≤ 0 (как в `instrument-position.ts`).
- [ ] Regression-тесты: currency position + cash; короткая позиция.
## Out of scope
- Уже сохранённые точки `TbankPortfolioValuePoint` (решение отдельно).
- Blocked cash, НКД, FX-конвертация.
- Уточнение формулировки `specs/portfolio-view` («сумма позиций и Cash Balance») — follow-up в specs; связано с WealthLedger/frontend#59.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Problem
totalsByCurrency(tbank-portfolio.mapper.ts) суммирует cash изgetPositions().moneyи все позиции портфеля, включаяCURRENCY(RUB000UTSTOM,USD800UTSTOM), которые являются тем же кэшем.portfolioStructureкладётCURRENCYвOTHER, а кэш — вCASH. Завышенные totals сохраняются вTbankPortfolioValuePointи складываются в сводке «все счета».brokerage-accounts.service.tsуже исключаетCURRENCY("must not duplicate the separately returned cash balances"), totals/structure — нет.unrealizedReturnByCurrency.percentделит на cost basisavgPrice × quantity, который у короткой позиции отрицателен: qty −2, avg 100, current 110 → absolute −20, cost −200, percent+10(убыток показан как прибыль). Лонг и шорт одной валюты взаимно гасят cost basis.Acceptance Criteria
totalsByCurrency= сумма currentValue не-CURRENCYпозиций + Cash Balance по валюте.structureне содержитCURRENCYпозиций вOTHER; кэш учитывается только вCASH.percent=null, если в валюте есть позиция с quantity ≤ 0 (как вinstrument-position.ts).Out of scope
TbankPortfolioValuePoint(решение отдельно).specs/portfolio-view(«сумма позиций и Cash Balance») — follow-up в specs; связано с WealthLedger/frontend#59.