| """ |
| Pydantic schemas — typed contracts between every agent. |
| No free-text. Every LLM output is schema-constrained. |
| """ |
| from pydantic import BaseModel, Field |
| from typing import Optional |
| from enum import Enum |
|
|
|
|
| class Neutralization(str, Enum): |
| SECTOR = "sector" |
| INDUSTRY = "industry" |
| SUBINDUSTRY = "subindustry" |
| NONE = "none" |
|
|
|
|
| class AnomalyTag(str, Enum): |
| PEAD = "pead" |
| VALUE = "value" |
| MOMENTUM = "momentum" |
| REVERSAL = "reversal" |
| LOW_VOL = "low_vol" |
| QUALITY = "quality" |
| LIQUIDITY = "liquidity" |
| SENTIMENT = "sentiment" |
| ANALYST = "analyst" |
| OPTION_SURFACE = "option_surface" |
| SOCIAL = "social" |
| FUNDAMENTAL = "fundamental" |
| TECHNICAL = "technical" |
| EVENT = "event" |
| OTHER = "other" |
|
|
|
|
| class Component(BaseModel): |
| """A single component of a multi-factor alpha.""" |
| name: str = Field(description="Descriptive name for this component") |
| fields: list[str] = Field(description="BRAIN data fields used") |
| operators: list[str] = Field(description="BRAIN operators applied") |
| horizon_days: int = Field(ge=1, le=252, description="Lookback horizon") |
| weight: float = Field(ge=-2.0, le=2.0, description="Weight in composite") |
| sign_direction: str = Field(description="Expected cross-sectional sign: 'long_high' or 'long_low'") |
|
|
|
|
| class Blueprint(BaseModel): |
| """Output of the Hypothesis Hunter. A structured factor idea.""" |
| theme: str = Field(description="High-level theme/anomaly category") |
| archetype: str = Field(description="Known archetype name or 'novel'") |
| components: list[Component] = Field(min_length=1, max_length=5) |
| neutralization: Neutralization |
| decay: int = Field(ge=0, le=20, default=5) |
| novelty_claim: str = Field(min_length=10, description="Why this is different from existing alphas") |
| academic_anchor: Optional[str] = Field(default=None, description="arXiv ID or DOI") |
| anomaly_tag: AnomalyTag |
|
|
|
|
| class Expression(BaseModel): |
| """Output of the Expression Compiler. A valid BRAIN expression.""" |
| expression: str = Field(min_length=10, description="The BRAIN expression string") |
| fields_used: list[str] |
| operators_used: list[str] |
| archetype_used: str = Field(description="Which template/archetype was used") |
|
|
|
|
| class LintResult(BaseModel): |
| """Output of the Static Lint layer.""" |
| passed: bool |
| errors: list[str] = Field(default_factory=list) |
| warnings: list[str] = Field(default_factory=list) |
|
|
|
|
| class SignSweepResult(BaseModel): |
| """Output of the sign direction sweep.""" |
| pos_sharpe: float |
| neg_sharpe: float |
| verdict: str = Field(description="'pos' or 'neg' — which direction works") |
| info_value: float = Field(description="abs(pos - neg), higher = more signal") |
|
|
|
|
| class BrainMetrics(BaseModel): |
| """Metrics harvested from BRAIN simulation.""" |
| alpha_id: str |
| sharpe_full: float |
| sharpe_is: float |
| sharpe_os: float |
| fitness: float |
| turnover: float |
| returns: float |
| max_drawdown: float |
| yearly_sharpe: list[float] |
| yearly_returns: list[float] |
| margin_pct: Optional[float] = None |
| long_count: Optional[int] = None |
| short_count: Optional[int] = None |
|
|
|
|
| class Verdict(str, Enum): |
| PROMOTE = "promote" |
| ITERATE = "iterate" |
| KILL = "kill" |
|
|
|
|
| class CrowdScoutResult(BaseModel): |
| """Output of the Crowd Scout agent.""" |
| max_corr_to_library: float |
| is_thematic_duplicate: bool |
| anomaly_already_saturated: bool |
| verdict: Verdict |
| reason: str |
|
|
|
|
| class SurgeonResult(BaseModel): |
| """Output of the Performance Surgeon agent.""" |
| regime_dependent: bool |
| decay_detected: bool |
| sign_error_likely: bool |
| dominant_regime: Optional[str] = None |
| iteration_suggestion: str |
| verdict: Verdict |
| reason: str |
|
|
|
|
| class GatekeeperMemo(BaseModel): |
| """Output of the Production Gatekeeper (Bigfish).""" |
| go_no_go: bool |
| confidence: float = Field(ge=0.0, le=1.0) |
| strengths: list[str] |
| weaknesses: list[str] |
| risks: list[str] |
| recommendation: str |
| full_memo: str |
|
|