openapi: 3.0.3
info:
  title: 10Y STOCK VALUE Calculator API
  version: 1.0.0
  description: >-
    現在の理論価値、10年後価値、Bear/Base/Bullと市場参考値を、サイトと同じ計算エンジンで返します。
    率は画面と同じ百分率表記（6は6%）、総額はinternational.amountScaleで指定した決算通貨単位です。
servers:
  - url: https://docomosoftbankstock.pages.dev
    description: Cloudflare Pages Production
  - url: https://stock-value-model-lab.docomosoftbank.chatgpt.site
    description: Custom Domain Production
paths:
  /api/v1/health:
    get:
      operationId: getValuationApiHealth
      summary: API稼働状態を確認する
      responses:
        '200':
          description: 稼働中
          content:
            application/json:
              schema:
                type: object
                properties:
                  status: { type: string, example: ok }
                  api_version: { type: string, example: 1.0.0 }
  /api/v1/valuation:
    post:
      operationId: calculateStockValuation
      summary: 株式価値を計算する
      description: >-
        valuesには選択モデルの入力を渡します。現在株価は上場表示単位、1株値は決算通貨・原普通株、
        総額はinternational.amountScaleの単位で指定してください。sectorモデルではsector_idが必須です。
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ValuationRequest'
            examples:
              profitable_japan:
                summary: 日本の黒字上場企業
                value:
                  model: profitable
                  input_convention: ui_percent
                  values:
                    currentPrice: 1000
                    eps: 80
                    epsGrowth: 6
                    exitPe: 16
                    fcfPerShare: 60
                    fcfGrowth: 5
                    riskFreeRate: 2
                    beta: 1
                    equityRiskPremium: 5
                    terminalGrowth: 2
                    interimDistributionPvPerShare: 0
              profitable_us:
                summary: 米国の黒字上場企業
                value:
                  model: profitable
                  input_convention: ui_percent
                  international:
                    countryOrRegion: US
                    exchange: NASDAQ
                    ticker: EXAMPLE
                    quoteCurrency: USD
                    financialCurrency: USD
                    functionalCurrency: USD
                    outputCurrency: USD
                    quoteUnitCode: USD
                    quoteUnitToCurrency: 1
                    amountScale: million
                    quoteToFinancialFx: 1
                    financialToOutputFx: 1
                    futureFxPolicy: constant_spot
                    financialToOutputFxYear10: 1
                    instrumentType: ordinary
                    shareClass: Common
                    ordinarySharesPerListedSecurity: 1
                    fxAsOfDate: ''
                  values:
                    currentPrice: 100
                    eps: 6
                    epsGrowth: 8
                    exitPe: 20
                    fcfPerShare: 5
                    fcfGrowth: 7
                    riskFreeRate: 4
                    beta: 1
                    equityRiskPremium: 5
                    terminalGrowth: 2.5
                    interimDistributionPvPerShare: 0
      responses:
        '200':
          description: 計算結果。blockedはモデル条件を満たさず価格を生成しなかったことを表します。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValuationResponse'
        '400':
          description: モデル、業種、入力、通貨設定が不正
          content:
            application/json:
              schema: { $ref: '#/components/schemas/ErrorResponse' }
        '413':
          description: リクエストが大きすぎる
        '422':
          description: 計算処理エラー
components:
  schemas:
    ValuationRequest:
      type: object
      required: [model, input_convention, values]
      additionalProperties: false
      properties:
        model:
          type: string
          enum: [profitable, lossmaking, private, bank, sector-simple, dcf-listed, dcf-loss, dcf-private, bank-advanced, sector-advanced]
        input_convention:
          type: string
          enum: [ui_percent]
          description: 率は画面と同じ百分率。6は0.06ではなく6%を表します。
        sector_id:
          type: string
          description: sector-simpleまたはsector-advancedで必須。サイトの業種ID。
        values:
          type: object
          description: 画面と同じフィールド名・百分率・金額単位。未知キーは拒否されます。
          additionalProperties:
            type: number
            nullable: true
        international:
          $ref: '#/components/schemas/InternationalContext'
    InternationalContext:
      type: object
      description: 省略項目はJPY/TSE/1億通貨単位/普通株の既定値で補完されます。
      properties:
        countryOrRegion: { type: string }
        exchange: { type: string }
        ticker: { type: string }
        instrumentType: { type: string, enum: [ordinary, preferred, adr, gdr, reit_unit, etf_unit] }
        shareClass: { type: string }
        quoteCurrency: { type: string, minLength: 3, maxLength: 3 }
        financialCurrency: { type: string, minLength: 3, maxLength: 3 }
        functionalCurrency: { type: string, minLength: 3, maxLength: 3 }
        outputCurrency: { type: string, minLength: 3, maxLength: 3 }
        quoteUnitCode: { type: string, description: JPY、USD、GBXなどの取引所表示単位 }
        quoteUnitToCurrency: { type: number, nullable: true, exclusiveMinimum: true, minimum: 0 }
        amountScale: { type: string, enum: [one, thousand, million, hundred_million, billion] }
        quoteToFinancialFx: { type: number, nullable: true, exclusiveMinimum: true, minimum: 0 }
        financialToOutputFx: { type: number, nullable: true, exclusiveMinimum: true, minimum: 0 }
        futureFxPolicy: { type: string, enum: [constant_spot, explicit_year10] }
        financialToOutputFxYear10: { type: number, nullable: true, exclusiveMinimum: true, minimum: 0 }
        ordinarySharesPerListedSecurity: { type: number, nullable: true, exclusiveMinimum: true, minimum: 0 }
        fxAsOfDate: { type: string, format: date }
    ValuationResponse:
      type: object
      required: [api_version, status, model, summary, result]
      properties:
        api_version: { type: string }
        status: { type: string, enum: [ok, blocked] }
        model: { type: string }
        sector_id: { type: string }
        summary:
          type: object
          properties:
            today: { type: number, nullable: true }
            year10: { type: number, nullable: true }
            market_reference: { type: number, nullable: true }
            basis: { type: string, enum: [per_listed_security, total] }
            unit: { type: string }
            value_at: { type: string }
        result:
          type: object
          additionalProperties: true
        scenarios:
          type: array
          items:
            type: object
            additionalProperties: true
    ErrorResponse:
      type: object
      required: [error]
      properties:
        error: { type: string }
        details:
          type: array
          items: { type: string }
        message: { type: string }
