- Add EvaluationHook for post-execution agent evaluation - Add SkillAdaptationHook for dynamic skill adaptation - Add team/ directory with team coordination logic - Add TEAM_PIPELINE.yaml for smoke_fullstack pipeline config - Update RuntimeView, TraderView and RuntimeSettingsPanel UI - Add runtimeApi and websocket services - Add runtime_state.json to smoke_fullstack state Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
195 lines
5.5 KiB
Python
195 lines
5.5 KiB
Python
# -*- coding: utf-8 -*-
|
|
from pydantic import BaseModel
|
|
|
|
|
|
class Price(BaseModel):
|
|
open: float
|
|
close: float
|
|
high: float
|
|
low: float
|
|
volume: int
|
|
time: str
|
|
|
|
|
|
class PriceResponse(BaseModel):
|
|
ticker: str
|
|
prices: list[Price]
|
|
|
|
|
|
class FinancialMetrics(BaseModel):
|
|
ticker: str
|
|
report_period: str
|
|
period: str
|
|
currency: str
|
|
market_cap: float | None
|
|
enterprise_value: float | None
|
|
price_to_earnings_ratio: float | None
|
|
price_to_book_ratio: float | None
|
|
price_to_sales_ratio: float | None
|
|
enterprise_value_to_ebitda_ratio: float | None
|
|
enterprise_value_to_revenue_ratio: float | None
|
|
free_cash_flow_yield: float | None
|
|
peg_ratio: float | None
|
|
gross_margin: float | None
|
|
operating_margin: float | None
|
|
net_margin: float | None
|
|
return_on_equity: float | None
|
|
return_on_assets: float | None
|
|
return_on_invested_capital: float | None
|
|
asset_turnover: float | None
|
|
inventory_turnover: float | None
|
|
receivables_turnover: float | None
|
|
days_sales_outstanding: float | None
|
|
operating_cycle: float | None
|
|
working_capital_turnover: float | None
|
|
current_ratio: float | None
|
|
quick_ratio: float | None
|
|
cash_ratio: float | None
|
|
operating_cash_flow_ratio: float | None
|
|
debt_to_equity: float | None
|
|
debt_to_assets: float | None
|
|
interest_coverage: float | None
|
|
revenue_growth: float | None
|
|
earnings_growth: float | None
|
|
book_value_growth: float | None
|
|
earnings_per_share_growth: float | None
|
|
free_cash_flow_growth: float | None
|
|
operating_income_growth: float | None
|
|
ebitda_growth: float | None
|
|
payout_ratio: float | None
|
|
earnings_per_share: float | None
|
|
book_value_per_share: float | None
|
|
free_cash_flow_per_share: float | None
|
|
|
|
|
|
class FinancialMetricsResponse(BaseModel):
|
|
financial_metrics: list[FinancialMetrics]
|
|
|
|
|
|
class LineItem(BaseModel):
|
|
ticker: str
|
|
report_period: str
|
|
period: str
|
|
currency: str
|
|
|
|
# Allow additional fields dynamically
|
|
model_config = {"extra": "allow"}
|
|
|
|
|
|
class LineItemResponse(BaseModel):
|
|
search_results: list[LineItem]
|
|
|
|
|
|
class InsiderTrade(BaseModel):
|
|
ticker: str
|
|
issuer: str | None
|
|
name: str | None
|
|
title: str | None
|
|
is_board_director: bool | None
|
|
transaction_date: str | None
|
|
transaction_shares: float | None
|
|
transaction_price_per_share: float | None
|
|
transaction_value: float | None
|
|
shares_owned_before_transaction: float | None
|
|
shares_owned_after_transaction: float | None
|
|
security_title: str | None
|
|
filing_date: str
|
|
|
|
|
|
class InsiderTradeResponse(BaseModel):
|
|
insider_trades: list[InsiderTrade]
|
|
|
|
|
|
class CompanyNews(BaseModel):
|
|
category: str | None = None
|
|
ticker: str
|
|
title: str
|
|
related: str | None = None
|
|
source: str
|
|
date: str | None = None
|
|
url: str
|
|
summary: str | None = None
|
|
|
|
|
|
class CompanyNewsResponse(BaseModel):
|
|
news: list[CompanyNews]
|
|
|
|
|
|
class CompanyFacts(BaseModel):
|
|
ticker: str
|
|
name: str
|
|
cik: str | None = None
|
|
industry: str | None = None
|
|
sector: str | None = None
|
|
category: str | None = None
|
|
exchange: str | None = None
|
|
is_active: bool | None = None
|
|
listing_date: str | None = None
|
|
location: str | None = None
|
|
market_cap: float | None = None
|
|
number_of_employees: int | None = None
|
|
sec_filings_url: str | None = None
|
|
sic_code: str | None = None
|
|
sic_industry: str | None = None
|
|
sic_sector: str | None = None
|
|
website_url: str | None = None
|
|
weighted_average_shares: int | None = None
|
|
|
|
|
|
class CompanyFactsResponse(BaseModel):
|
|
company_facts: CompanyFacts
|
|
|
|
|
|
class Position(BaseModel):
|
|
"""Position information - for Portfolio mode"""
|
|
|
|
long: int = 0 # Long position quantity (shares)
|
|
short: int = 0 # Short position quantity (shares)
|
|
long_cost_basis: float = 0.0 # Long position average cost
|
|
short_cost_basis: float = 0.0 # Short position average cost
|
|
|
|
|
|
class Portfolio(BaseModel):
|
|
"""Portfolio - for Portfolio mode"""
|
|
|
|
cash: float = 100000.0 # Available cash
|
|
positions: dict[str, Position] = {} # ticker -> Position mapping
|
|
# Margin requirement (0.0 means shorting disabled, 0.5 means 50% margin)
|
|
margin_requirement: float = 0.0
|
|
margin_used: float = 0.0 # Margin used
|
|
|
|
|
|
class AnalystSignal(BaseModel):
|
|
signal: str | None = None
|
|
confidence: float | None = None
|
|
reasoning: dict | str | None = None
|
|
# Extended fields for richer signal information
|
|
reasons: list[str] | None = None # Core drivers/reasons for the signal
|
|
risks: list[str] | None = None # Key risk factors
|
|
invalidation: str | None = None # Conditions that would invalidate the thesis
|
|
next_action: str | None = None # Suggested next action for PM
|
|
# Valuation-related fields
|
|
intrinsic_value: float | None = None # DCF intrinsic value
|
|
fair_value_range: dict | None = None # {bear, base, bull} fair value range
|
|
value_gap_pct: float | None = None # Value gap percentage
|
|
valuation_methods: list[str] | None = None # List of valuation methods used
|
|
max_position_size: float | None = None # For risk management signals
|
|
|
|
|
|
class TickerAnalysis(BaseModel):
|
|
ticker: str
|
|
analyst_signals: dict[str, AnalystSignal] # agent_name -> signal mapping
|
|
|
|
|
|
class AgentStateData(BaseModel):
|
|
tickers: list[str]
|
|
portfolio: Portfolio
|
|
start_date: str
|
|
end_date: str
|
|
ticker_analyses: dict[str, TickerAnalysis] # ticker -> analysis mapping
|
|
|
|
|
|
class AgentStateMetadata(BaseModel):
|
|
show_reasoning: bool = False
|
|
model_config = {"extra": "allow"}
|