openapi: 3.1.0
info:
  title: ValueRay API
  version: "1.2"
  description: >
    Comprehensive technical, quantitative and sentiment overview for stocks and ETFs.
    Aggregates price data, moving averages, support/resistance levels, risk metrics,
    performance, peer percentiles, dividend data, sector rotation and proprietary
    VRO sentiment signals.

    Endpoints: /symbolData (technical overview), /symbolPeers (peer percentiles),
    /marketRegime (market regime and sector rotation).

    Examples:
    https://www.valueray.com/api/v1/symbolData?symbol=AAPL
    https://www.valueray.com/api/v1/symbolPeers?symbol=AAPL
    https://www.valueray.com/api/v1/marketRegime

    Optimized for AI/LLM Agents. Field definitions and scoring logic:
    https://www.valueray.com/prompts/_explanations.md
  contact:
    name: ValueRay
    url: https://www.valueray.com
  license:
    name: Proprietary

externalDocs:
  description: Field definitions and scoring logic
  url: https://www.valueray.com/prompts/_explanations.md

servers:
  - url: https://www.valueray.com/api/v1

paths:
  /symbolData:
    get:
      operationId: getSymbolData
      summary: Get comprehensive technical overview for a symbol
      parameters:
        - name: symbol
          in: query
          required: true
          schema:
            type: string
            examples:
              - AAPL
        - name: exchange
          in: query
          required: false
          schema:
            type: string
            examples:
              - NASDAQ
      responses:
        "200":
          description: Symbol data returned successfully
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SymbolDataResponse"
        "400":
          description: Bad request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "404":
          description: Resource not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "429":
          description: Rate limit exceeded
        "500":
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  /symbolPeers:
    get:
      operationId: getSymbolPeers
      summary: Get peer comparison percentiles for a symbol
      parameters:
        - name: symbol
          in: query
          required: true
          schema:
            type: string
            examples:
              - AAPL
        - name: exchange
          in: query
          required: false
          schema:
            type: string
            examples:
              - NASDAQ
      responses:
        "200":
          description: Peer comparison data returned successfully
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SymbolPeersResponse"
        "400":
          description: Bad request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "404":
          description: Resource not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "429":
          description: Rate limit exceeded (30 req/hour per IP)
        "500":
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  /marketRegime:
    get:
      operationId: getMarketRegime
      summary: Get current market regime, sector rotation and breadth indicators
      description: >
        Returns VIX, SKEW, MOVE, correlation, TRIN, breadth signals, yield curve,
        credit stress proxies, DXY and industry rotation scores.
        Data updates end-of-day — polling more frequently won't yield new results.
      responses:
        "200":
          description: Market regime data returned successfully
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/MarketRegimeResponse"
        "429":
          description: Rate limit exceeded
        "500":
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

components:
  schemas:
    ErrorResponse:
      type: object
      properties:
        error:
          type: string

    # ── market regime ──────────────────────────────────────────
    MarketRegimeResponse:
      type: object
      properties:
        regime_values:
          type: object
          properties:
            VIX:
              type: string
            SKEW:
              type: string
            MOVE:
              type: string
            COR10D:
              type: string
            TRIN arms index:
              type: string
              description: "> 2.0 = panic, < 0.5 = FOMO"

        regime_signals:
          type: object
          properties:
            SPX distance to EMA20 pct:
              type: number
            SPX distance to SMA200 pct:
              type: number
            SPX drawdown from 52w High pct:
              type: number
            SPX Cap-Weight to Equal-Weight ratio:
              type: number
            SPX Cap-Weight to Equal-Weight 1w pct:
              type: number
            COR10D distance to SMA200 pts:
              type: number
            COR 10D to 90D ratio:
              type: number
            VIX strength RSI14:
              type: string
            VIX to VIX3M ratio:
              type: number
            SKEW distance to SMA50 pts:
              type: number
            Yield Curve 10Y minus 2Y pts:
              type: number
            US10Y perf 1w pct:
              type: string
            MOVE distance to SMA200 pts:
              type: number
            Credit Proxy High Yield Bond perf 1w pct:
              type: string
              description: "Going down = more credit stress"
            DXY is below SMA50:
              type: boolean
            DXY perf 1w pct:
              type: string
            SPX stocks above their SMA20 pct:
              type: number

        industry_rotation:
          type: array
          items:
            type: object
            properties:
              industry:
                type: string
              6w_ago:
                type: integer
              now:
                type: integer
              rel_delta:
                type: string

        disclaimer:
          type: string
        field_explanations:
          type: string

    # ── peers response wrapper ─────────────────────────────────
    SymbolPeersResponse:
      type: object
      additionalProperties: true
      properties:
        explanation:
          type: string
        disclaimer:
          type: string
        field_explanations:
          type: string
      description: >
        The main payload is keyed by "<type>: <code> (<name>) on <exchange>".
        Each value is a PeerEntry object.

    PeerEntry:
      type: object
      properties:
        last_update:
          type: string
        code:
          type: string
        exchange:
          type: string
        type:
          type: string
          enum: [ common stock, etf ]
        peer_group:
          type: string
        num_of_peers:
          type: integer
        marketcap_pctl:
          type: string

        performance_pctl:
          type: object
          properties:
            perf_1m:
              type: string
            perf_3m:
              type: string
            perf_6m:
              type: string
            perf_12m:
              type: string
            rel_str_ibd:
              type: string

        valuation_pctl:
          type: object
          description: As reported by data provider
          properties:
            pe_trail:
              type: string
            pe_forward:
              type: string
            ps:
              type: string
            pb:
              type: string
            peg:
              type: string
            ev_fcf:
              type: string

        profitability_pctl:
          type: object
          properties:
            roic:
              type: string
            roe:
              type: string
            gross_margin:
              type: string
            net_margin:
              type: string
            fcf_margin:
              type: string
            fcf_yield_ev:
              type: string

        debt_pctl:
          type: object
          properties:
            debt_equity:
              type: string
            net_debt_ebitda:
              type: string

        risk_pctl:
          type: object
          properties:
            sharpe_ratio:
              type: string
            volatility:
              type: string

    # ── top-level response wrapper ──────────────────────────────
    SymbolDataResponse:
      type: object
      additionalProperties: true
      properties:
        disclaimer:
          type: string
        field_explanations:
          type: string
      description: >
        The main payload is keyed by "<type>: <code> (<name>) on <exchange>".
        Each value is a SymbolEntry object.

    SymbolEntry:
      type: object
      properties:
        last_update:
          type: string
        code:
          type: string
        exchange:
          type: string
        isin:
          type: string
        name:
          type: string
        type:
          type: string
          enum: [ common stock, etf ]
        currency:
          type: string
        country:
          type: string
        country_origin:
          type: string
        ipo:
          type: string
          format: date
        market_cap_in_millions:
          type: string
        keywords:
          type: string
        sector:
          type: string
        industry:
          type: string
        subindustry:
          type: string
        etf_category:
          type: string
          description: Only present for ETFs

        dividends:
          type: object
          properties:
            dividend_rate_ttm:
              type: string
            dividend_yield:
              type: string
            payout_ratio:
              type: string
            dividend_growth_5y_cagr:
              type: string
            streak_years:
              type: integer
            next_dividend:
              type: string

        technical:
          type: object
          properties:
            last_price:
              type: string
            52w_high:
              type: string
            52w_low:
              type: string
            ema_20:
              type: string
            sma_50:
              type: string
            sma_200:
              type: string
            ema8_dist_pctl:
              type: string
            atr:
              type: string
            atr_percent:
              type: string
            current_volume:
              type: integer
            average_volume:
              type: integer
            relative_volume:
              type: string
            average_turnover:
              type: integer
            trend_correlation_1m:
              type: string
            trend_correlation_3m:
              type: string
            trend_correlation_6m:
              type: string
            trend_correlation_12m:
              type: string
            hurst_exponent:
              type: string

        support_resistance:
          type: array
          items:
            type: object
            properties:
              level:
                type: number
              strength:
                type: number
              type:
                type: string
                enum: [ s, r ]
              start:
                type: string
                format: date
              end:
                type: string
                format: date

        zigzag_pivot_points:
          type: array
          items:
            type: object
            properties:
              date:
                type: string
                format: date
              price:
                type: number
              move_pct:
                type: number

        changepoints:
          type: array
          items:
            type: string
            format: date

        risk:
          type: object
          properties:
            beta:
              type: string
            beta_downside:
              type: string
            alpha_jensen:
              type: string
            sharpe_ratio:
              type: string
            volatility:
              type: string
            var_5pct:
              type: string
            relative_tail_risk:
              type: string
            max_drawdown:
              type: string
            mean_drawdown:
              type: string

        performance:
          type: object
          properties:
            perf_1d:
              type: string
            perf_1w:
              type: string
            perf_1m:
              type: string
            perf_3m:
              type: string
            perf_6m:
              type: string
            perf_ytd:
              type: string
            perf_12m:
              type: string
            perf_5y:
              type: string
            cagr_3y:
              type: string
            rel_str_ibd:
              type: string

        sentiment:
          type: object
          properties:
            rsi_14:
              type: string
            vro_score:
              type: string
            vro_trend:
              type: string
            buy_signal:
              type: string
            signals_positive:
              type: string
            signals_negative:
              type: string
            sector_rotation:
              oneOf:
                - type: object
                  properties:
                    group:
                      type: string
                    rel_delta:
                      type: string
                - type: string
                  enum: [ "N/A" ]
