spec: plan investment performance vs Moscow Exchange index (WealthLedger/main#54) (#85)
This commit was merged in pull request #85.
This commit is contained in:
+192
@@ -0,0 +1,192 @@
|
||||
openapi: 3.1.0
|
||||
info:
|
||||
title: WealthLedger investment performance (target contract, WealthLedger/main#54)
|
||||
version: 1.0.0
|
||||
description: |
|
||||
Целевой контракт новых маршрутов. После реализации исполняемым источником
|
||||
становится backend-generated OpenAPI, который MUST быть семантически
|
||||
совместим с этим файлом. Общие схемы `MoneyDto`, `ProblemDetailsDto` и
|
||||
`InvestmentDependencyDto` остаются в опубликованном OpenAPI и здесь только
|
||||
упоминаются.
|
||||
paths:
|
||||
/api/v1/brokerage-accounts/{accountId}/performance:
|
||||
get:
|
||||
operationId: getBrokerageAccountPerformance
|
||||
summary: Результат инвестирования счёта за всё время
|
||||
parameters:
|
||||
- name: accountId
|
||||
in: path
|
||||
required: true
|
||||
schema: { type: string, minLength: 1 }
|
||||
responses:
|
||||
'200': { $ref: '#/components/responses/Performance' }
|
||||
'401': { $ref: '#/components/responses/Problem' }
|
||||
'404': { $ref: '#/components/responses/Problem' }
|
||||
'503': { $ref: '#/components/responses/Problem' }
|
||||
/api/v1/brokerage-accounts/all/performance:
|
||||
get:
|
||||
operationId: getAllBrokerageAccountsPerformance
|
||||
summary: Результат инвестирования режима «Все счета»
|
||||
responses:
|
||||
'200': { $ref: '#/components/responses/Performance' }
|
||||
'401': { $ref: '#/components/responses/Problem' }
|
||||
'503': { $ref: '#/components/responses/Problem' }
|
||||
components:
|
||||
responses:
|
||||
Problem:
|
||||
description: Ошибка доступа, подключения или технический сбой (существующий Problem Details; коды из PROBLEM_CODES)
|
||||
content:
|
||||
application/problem+json:
|
||||
schema: { $ref: 'openapi.json#/components/schemas/ProblemDetailsDto' }
|
||||
Performance:
|
||||
description: Результат либо явная недоступность. Недоступность расчёта — не ошибка HTTP.
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: '#/components/schemas/PerformanceResource' }
|
||||
schemas:
|
||||
Decimal:
|
||||
type: string
|
||||
pattern: '^-?(0|[1-9][0-9]*)(\.[0-9]*[1-9])?$'
|
||||
description: Точное десятичное значение без экспоненты и незначащих нулей
|
||||
Rate:
|
||||
allOf: [{ $ref: '#/components/schemas/Decimal' }]
|
||||
description: Доля, не проценты. 0.151 = 15,1 %. Округление до 6 знаков, half away from zero.
|
||||
Money:
|
||||
$ref: 'openapi.json#/components/schemas/MoneyDto'
|
||||
UnavailableReason:
|
||||
type: string
|
||||
enum:
|
||||
- HISTORY_START_UNKNOWN
|
||||
- OPERATIONS_HISTORY_INCOMPLETE
|
||||
- NON_RUB_ACTIVITY
|
||||
- UNVALUED_SECURITIES_TRANSFER
|
||||
- UNCONFIRMED_TRANSFER
|
||||
- ACCOUNT_VALUATION_DATES_DIFFER
|
||||
- PORTFOLIO_VALUATION_INCOMPLETE
|
||||
- NO_SOLUTION
|
||||
- AMBIGUOUS_RETURN
|
||||
- INDEX_HISTORY_UNAVAILABLE
|
||||
description: |
|
||||
Новые значения MAY добавляться; клиент MUST показывать неизвестное
|
||||
значение как общую недоступность, а не как ошибку.
|
||||
ReturnValue:
|
||||
type: object
|
||||
required: [value, basis, unavailableReason]
|
||||
properties:
|
||||
value:
|
||||
oneOf: [{ $ref: '#/components/schemas/Rate' }, { type: 'null' }]
|
||||
basis:
|
||||
type: string
|
||||
enum: [annual, period]
|
||||
description: annual при period.days >= 365, иначе period (доля за весь период)
|
||||
unavailableReason:
|
||||
oneOf: [{ $ref: '#/components/schemas/UnavailableReason' }, { type: 'null' }]
|
||||
IndexResult:
|
||||
type: object
|
||||
required: [code, value, return, asOf, unavailableReason]
|
||||
properties:
|
||||
code:
|
||||
type: string
|
||||
enum: [MCFTRR, IMOEX]
|
||||
value:
|
||||
oneOf: [{ $ref: '#/components/schemas/Money' }, { type: 'null' }]
|
||||
description: Стоимость тех же потоков в индексе на конец периода (RUB)
|
||||
return: { $ref: '#/components/schemas/ReturnValue' }
|
||||
asOf:
|
||||
oneOf: [{ type: string, format: date }, { type: 'null' }]
|
||||
description: Дата последнего использованного закрытия индекса (Europe/Moscow)
|
||||
unavailableReason:
|
||||
oneOf: [{ $ref: '#/components/schemas/UnavailableReason' }, { type: 'null' }]
|
||||
Outperformance:
|
||||
type: object
|
||||
required: [percentagePoints, money]
|
||||
properties:
|
||||
percentagePoints:
|
||||
$ref: '#/components/schemas/Rate'
|
||||
description: Разница долей return пользователя и benchmark (того же basis)
|
||||
money: { $ref: '#/components/schemas/Money' }
|
||||
SeriesPoint:
|
||||
type: object
|
||||
required: [date, netInvested, benchmarkValue, referenceValue]
|
||||
properties:
|
||||
date: { type: string, format: date }
|
||||
netInvested: { $ref: '#/components/schemas/Decimal' }
|
||||
benchmarkValue: { $ref: '#/components/schemas/Decimal' }
|
||||
referenceValue:
|
||||
oneOf: [{ $ref: '#/components/schemas/Decimal' }, { type: 'null' }]
|
||||
description: Значения RUB на торговый день MCFTRR; валюта точки всегда RUB
|
||||
ExcludedAccount:
|
||||
type: object
|
||||
required: [accountId, name, reason]
|
||||
properties:
|
||||
accountId: { type: string }
|
||||
name: { type: string }
|
||||
reason: { $ref: '#/components/schemas/UnavailableReason' }
|
||||
Performance:
|
||||
type: object
|
||||
required:
|
||||
- accountId
|
||||
- period
|
||||
- netInvested
|
||||
- currentValue
|
||||
- profit
|
||||
- return
|
||||
- benchmark
|
||||
- reference
|
||||
- outperformance
|
||||
- series
|
||||
- completeness
|
||||
- excludedAccounts
|
||||
- calculatedAt
|
||||
properties:
|
||||
accountId: { type: string, description: 'id счёта или all' }
|
||||
period:
|
||||
type: object
|
||||
required: [from, to, days]
|
||||
properties:
|
||||
from: { type: string, format: date }
|
||||
to: { type: string, format: date, description: 'дата последней полной оценки Portfolio' }
|
||||
days: { type: integer, minimum: 0 }
|
||||
netInvested: { $ref: '#/components/schemas/Money' }
|
||||
currentValue: { $ref: '#/components/schemas/Money' }
|
||||
profit: { $ref: '#/components/schemas/Money' }
|
||||
return: { $ref: '#/components/schemas/ReturnValue' }
|
||||
benchmark:
|
||||
allOf: [{ $ref: '#/components/schemas/IndexResult' }]
|
||||
description: code = MCFTRR
|
||||
reference:
|
||||
allOf: [{ $ref: '#/components/schemas/IndexResult' }]
|
||||
description: code = IMOEX; только справка
|
||||
outperformance:
|
||||
oneOf: [{ $ref: '#/components/schemas/Outperformance' }, { type: 'null' }]
|
||||
description: null, если недоступен return пользователя или benchmark
|
||||
series:
|
||||
type: array
|
||||
items: { $ref: '#/components/schemas/SeriesPoint' }
|
||||
description: Пусто, если benchmark недоступен
|
||||
completeness:
|
||||
type: string
|
||||
enum: [complete, incomplete]
|
||||
excludedAccounts:
|
||||
type: array
|
||||
items: { $ref: '#/components/schemas/ExcludedAccount' }
|
||||
description: Только для all; incomplete <=> непустой массив
|
||||
calculatedAt: { type: string, format: date-time }
|
||||
PerformanceResource:
|
||||
type: object
|
||||
required: [data, meta]
|
||||
properties:
|
||||
data:
|
||||
oneOf: [{ $ref: '#/components/schemas/Performance' }, { type: 'null' }]
|
||||
description: null, если результат недоступен целиком
|
||||
meta:
|
||||
type: object
|
||||
required: [dependencies, unavailable]
|
||||
properties:
|
||||
dependencies:
|
||||
type: array
|
||||
items: { $ref: 'openapi.json#/components/schemas/InvestmentDependencyDto' }
|
||||
unavailable:
|
||||
type: array
|
||||
description: Непусто <=> data = null; причины по каждому счёту
|
||||
items: { $ref: '#/components/schemas/ExcludedAccount' }
|
||||
Reference in New Issue
Block a user