""" Insider transaction schemas """ from datetime import date from typing import Any, Dict, List, Optional from pydantic import BaseModel, ConfigDict, Field TRANSACTION_CODE_MAP = { "P": "Purchase", "S": "Sale", "A": "Award/Grant", "M": "Exercise/Conversion", "G": "Gift", "D": "Disposition to Issuer", "F": "Tax Withholding", "C": "Conversion", "J": "Other", } class InsiderTransactionEntry(BaseModel): model_config = ConfigDict(from_attributes=True) filing_date: date transaction_date: date owner_name: str owner_cik: Optional[str] = None is_officer: bool = False is_director: bool = False is_ten_percent_owner: bool = False officer_title: Optional[str] = None security_title: Optional[str] = None transaction_code: str transaction_type: str # human-readable shares: float price_per_share: Optional[float] = None total_value: Optional[float] = None shares_owned_after: Optional[float] = None is_derivative: bool = False @classmethod def from_orm_obj(cls, obj) -> "InsiderTransactionEntry": return cls( filing_date=obj.filing_date.date() if hasattr(obj.filing_date, "date") else obj.filing_date, transaction_date=obj.transaction_date.date() if hasattr(obj.transaction_date, "date") else obj.transaction_date, owner_name=obj.owner_name, owner_cik=obj.owner_cik, is_officer=obj.is_officer or False, is_director=obj.is_director or False, is_ten_percent_owner=obj.is_ten_percent_owner or False, officer_title=obj.officer_title, security_title=obj.security_title, transaction_code=obj.transaction_code, transaction_type=TRANSACTION_CODE_MAP.get(obj.transaction_code, obj.transaction_code), shares=obj.shares, price_per_share=obj.price_per_share, total_value=obj.total_value, shares_owned_after=obj.shares_owned_after, is_derivative=obj.is_derivative or False, ) class InsiderTransactionResponse(BaseModel): symbol: str transactions: List[InsiderTransactionEntry] total_count: int metadata: Dict[str, Any] = Field(default_factory=dict) class InsiderSummaryPeriod(BaseModel): period_label: str buy_count: int = 0 sell_count: int = 0 buy_shares: float = 0.0 sell_shares: float = 0.0 buy_value: float = 0.0 sell_value: float = 0.0 net_shares: float = 0.0 net_value: float = 0.0 unique_buyers: int = 0 unique_sellers: int = 0 class InsiderSummaryResponse(BaseModel): symbol: str periods: List[InsiderSummaryPeriod] notable_transactions: List[InsiderTransactionEntry] metadata: Dict[str, Any] = Field(default_factory=dict)