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 - 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' }