from __future__ import annotations from datetime import datetime from typing import Any, Literal from pydantic import BaseModel, ConfigDict, Field class TradeContextResponse(BaseModel): requested_date: str actual_date: str | None previous_date: str | None observed_at: datetime | None state: str | None carried_forward: bool message: str class MarketSummaryResponse(BaseModel): context: TradeContextResponse values: dict[str, Any] | None class SearchResultResponse(BaseModel): entity_type: Literal["stock", "sector", "theme", "index"] identifier: str code: str name: str sector: str | None class SearchGroupResponse(BaseModel): entity_type: Literal["stock", "sector", "theme", "index"] label: str items: list[SearchResultResponse] class SearchResponse(BaseModel): query: str groups: list[SearchGroupResponse] class ChartPointResponse(BaseModel): time: str open: float high: float low: float close: float volume: float amount: float average: float | None class ChartResponse(BaseModel): entity_type: str identifier: str code: str name: str interval: Literal["day", "minute"] trade_date: str observed_at: datetime previous_close: float | None range_start: str | None range_end: str | None points: list[ChartPointResponse] class EntityDetailResponse(BaseModel): model_config = ConfigDict(extra="allow") entity: SearchResultResponse trade_date: str observed_at: datetime price: float previous_close: float | None change: float | None metrics: list[dict[str, Any]] = Field(default_factory=list) money_flow: dict[str, Any] | None = None event: dict[str, Any] | None = None class ReferenceSyncResponse(BaseModel): calendar_days: int = Field(ge=1) entities: int = Field(ge=1) observed_at: datetime class SnapshotSyncResponse(BaseModel): trade_date: str observed_at: datetime coverage: float stocks: int limit_up: int limit_down: int broken: int temperature: int class MarketWorkspaceResponse(BaseModel): trade_date: str | None observed_at: datetime | None = None carried_forward: bool = False message: str = "" overview: dict[str, Any] = Field(default_factory=dict) sentiment: dict[str, Any] | None = None history: list[dict[str, Any]] | None = None items: list[dict[str, Any]] | None = None class RotationMembersResponse(BaseModel): trade_date: str sector_name: str sector_code: str member_count: int = Field(ge=0) quoted_count: int = Field(ge=0) coverage: float = Field(ge=0, le=1) items: list[dict[str, Any]] = Field(default_factory=list) class MarketInsightResponse(BaseModel): model_config = ConfigDict(extra="allow") requested_date: str trade_date: str observed_at: datetime | None = None state: str | None = None carried_forward: bool = False message: str = "" summary: dict[str, Any] = Field(default_factory=dict) class ThemeDetailResponse(BaseModel): model_config = ConfigDict(extra="allow") trade_date: str observed_at: datetime | None = None state: str | None = None message: str = "" theme: dict[str, Any] summary: dict[str, Any] members: list[dict[str, Any]] class SeatAliasRequest(BaseModel): seat_name: str = Field(min_length=1, max_length=200) alias_name: str = Field(min_length=1, max_length=80) class SeatAliasResponse(BaseModel): seat_name: str alias_name: str