spec: plan investment performance vs Moscow Exchange index (WealthLedger/main#54)
This commit is contained in:
+25
@@ -0,0 +1,25 @@
|
||||
sequenceDiagram
|
||||
participant API as WealthLedger backend
|
||||
participant Idx as Saved index history
|
||||
participant MOEX as MOEX ISS
|
||||
API->>Idx: Последняя сохранённая дата, время последней попытки (по индексу)
|
||||
alt Покрыто до дня `to` или попытка была < 1 ч назад
|
||||
Idx-->>API: Сохранённые закрытия
|
||||
else Нужна догрузка (одна одновременная попытка на индекс)
|
||||
loop Страницы по 100 строк (start = 0, 100, …) до TOTAL
|
||||
API->>MOEX: GET /iss/history/engines/stock/markets/index/securities/{SECID}.json<br/>?from&till&start&iss.meta=off&history.columns=TRADEDATE,CLOSE
|
||||
alt 200 с валидными строками
|
||||
MOEX-->>API: TRADEDATE, CLOSE + history.cursor(INDEX,TOTAL,PAGESIZE)
|
||||
API->>Idx: Upsert (индекс, торговый день) → точное закрытие
|
||||
else Таймаут 10 с / не-2xx / невалидный ответ
|
||||
MOEX-->>API: сбой
|
||||
Note over API: Прервать догрузку; сохранённое не удалять;<br/>лог integration.moex.index_history.failed
|
||||
end
|
||||
end
|
||||
Idx-->>API: Сохранённые закрытия
|
||||
end
|
||||
alt Последнее закрытие ≥ to − 10 календарных дней
|
||||
Note over API: Покрытие достаточно; asOf = последняя дата закрытия
|
||||
else Иначе
|
||||
Note over API: INDEX_HISTORY_UNAVAILABLE для этого индекса
|
||||
end
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
sequenceDiagram
|
||||
actor User
|
||||
participant UI as WealthLedger frontend
|
||||
participant API as WealthLedger backend
|
||||
participant Store as Saved investment data
|
||||
participant Idx as Saved index history
|
||||
participant MOEX as MOEX ISS
|
||||
User->>UI: Открывает вкладку «Результат» (accountId | all)
|
||||
UI->>API: GET /brokerage-accounts/{accountId|all}/performance
|
||||
API->>Store: Сессия, connection, доступ к счёту(ам)
|
||||
alt Нет сессии / нет подключения / счёт недоступен
|
||||
API-->>UI: Problem Details 401 / 503 TBANK_NOT_CONNECTED / 404
|
||||
UI-->>User: Существующие состояния ошибки счёта
|
||||
else Доступ подтверждён
|
||||
API->>Store: Граница истории, покрытие операций, последняя полная оценка Portfolio
|
||||
Note over API: По каждому счёту: причины недоступности<br/>(HISTORY_START_UNKNOWN, OPERATIONS_HISTORY_INCOMPLETE,<br/>NON_RUB_ACTIVITY, UNVALUED_SECURITIES_TRANSFER,<br/>PORTFOLIO_VALUATION_INCOMPLETE)
|
||||
alt Не осталось счетов для расчёта
|
||||
API-->>UI: 200 {data: null, meta.unavailable: [...]}
|
||||
UI-->>User: «Доходность недоступна» + причина
|
||||
else Есть счета для расчёта
|
||||
API->>API: Внешние потоки по дате, чистые вложения, прибыль, XIRR
|
||||
API->>Idx: Закрытия MCFTRR, IMOEX за [from, to]
|
||||
opt История не покрывает период (см. index-refresh.mmd)
|
||||
Idx->>MOEX: Догрузка недостающих торговых дней
|
||||
end
|
||||
alt MCFTRR покрывает период
|
||||
API->>API: Теневой портфель, XIRR индекса, опережение, series
|
||||
else MCFTRR недоступен
|
||||
API->>API: benchmark/outperformance недоступны (INDEX_HISTORY_UNAVAILABLE), series = []
|
||||
end
|
||||
API-->>UI: 200 {data: Performance, meta.dependencies}
|
||||
UI-->>User: Показатели, график, «Как считали», предупреждение о неполноте
|
||||
end
|
||||
end
|
||||
alt Технический сбой backend
|
||||
API-->>UI: Problem Details 5xx
|
||||
UI-->>User: Ошибка только во вкладке «Результат», с повтором
|
||||
end
|
||||
Reference in New Issue
Block a user