You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

183 lines
4.4 KiB
Python

"""Pydantic response models for Stock Oracle API."""
from __future__ import annotations
from typing import Any
from pydantic import BaseModel, Field
# ---------------------------------------------------------------------------
# Company Info
# ---------------------------------------------------------------------------
class CompanyInfo(BaseModel):
ticker: str
name: str | None = None
cik: str | None = None
exchange: str | None = None
sector: str | None = None
industry: str | None = None
country: str | None = None
market_cap: float | None = None
extra: dict[str, Any] = Field(default_factory=dict)
# ---------------------------------------------------------------------------
# SEC Filings
# ---------------------------------------------------------------------------
class FilingEntry(BaseModel):
accession_no: str
form_type: str
filing_date: str # ISO date string
accepted_at: str | None = None
primary_document: str | None = None
description: str | None = None
items: list[str] = Field(default_factory=list)
class FilingSearchResponse(BaseModel):
ticker: str
filings: list[FilingEntry] = Field(default_factory=list)
total: int = 0
class ExhibitDocument(BaseModel):
exhibit_type: str
filename: str | None = None
url: str | None = None
class FilingDocumentsResponse(BaseModel):
accession_no: str
exhibits: list[ExhibitDocument] = Field(default_factory=list)
class ExhibitResponse(BaseModel):
accession_no: str
exhibit_type: str
content: str
content_type: str = "text/plain"
# ---------------------------------------------------------------------------
# Price / Market Data
# ---------------------------------------------------------------------------
class PriceBar(BaseModel):
date: str # ISO date
open: float
high: float
low: float
close: float
volume: int
vwap: float | None = None
trade_count: int | None = None
class PriceDataResponse(BaseModel):
ticker: str
bars: list[PriceBar] = Field(default_factory=list)
source: str = "yfinance"
class PriceQuote(BaseModel):
ticker: str
price: float
bid: float | None = None
ask: float | None = None
volume: int | None = None
timestamp: str | None = None
class IntradayBar(BaseModel):
timestamp: str
open: float
high: float
low: float
close: float
volume: int
class IntradayResponse(BaseModel):
ticker: str
bars: list[IntradayBar] = Field(default_factory=list)
timeframe: str = "1m"
# ---------------------------------------------------------------------------
# Financial / XBRL
# ---------------------------------------------------------------------------
class FinancialPeriod(BaseModel):
period: str # e.g. "2025-Q4"
period_end: str # ISO date
revenue: float | None = None
net_income: float | None = None
eps: float | None = None
gross_margin: float | None = None
operating_margin: float | None = None
extra: dict[str, Any] = Field(default_factory=dict)
class FinancialDataResponse(BaseModel):
ticker: str
periods: list[FinancialPeriod] = Field(default_factory=list)
# ---------------------------------------------------------------------------
# FRED
# ---------------------------------------------------------------------------
class FredObservation(BaseModel):
date: str # ISO date
value: float | None = None
class FredProxyResponse(BaseModel):
series_id: str
observations: list[FredObservation] = Field(default_factory=list)
realtime_start: str | None = None
realtime_end: str | None = None
class FredSeriesInfo(BaseModel):
id: str
title: str | None = None
frequency: str | None = None
units: str | None = None
notes: str | None = None
# ---------------------------------------------------------------------------
# FINRA Short Volume
# ---------------------------------------------------------------------------
class ShortVolumeEntry(BaseModel):
date: str # ISO date
short_volume: int
short_exempt_volume: int | None = None
total_volume: int | None = None
class ShortVolumeResponse(BaseModel):
symbol: str
data: list[ShortVolumeEntry] = Field(default_factory=list)
class ShortRatioPoint(BaseModel):
date: str
short_ratio: float | None = None
short_percent: float | None = None
class ShortRatioResponse(BaseModel):
symbol: str
data: list[ShortRatioPoint] = Field(default_factory=list)