Spaces:
Sleeping
Sleeping
File size: 2,326 Bytes
645673f d5ba3a3 645673f d5ba3a3 e813ce3 d5ba3a3 645673f e813ce3 d5ba3a3 645673f d5ba3a3 645673f d5ba3a3 645673f d5ba3a3 e813ce3 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | import re
from typing import Literal
from pydantic import BaseModel, Field
_HEADER_RE = re.compile(r"^#{1,4}\s+.*$", re.MULTILINE)
def _strip_headers(text: str) -> str:
"""Remove any markdown headers the LLM embedded in a field value."""
return _HEADER_RE.sub("", text).strip()
class InvestmentVerdict(BaseModel):
"""Structured analyst verdict returned by the Senior Broker LLM."""
quantitative_base: str = Field(
description="Price vs calculated valuation, margin of safety math"
)
lynch_pitch: str = Field(
description="What insiders are doing + the one catalyst"
)
munger_invert: str = Field(
description="How an investor could lose money, the bear evidence"
)
verdict: Literal["STRONG BUY", "BUY", "WATCH", "AVOID"]
bottom_line: str = Field(
description="One-sentence final summary"
)
position_size: float = Field(
default=0.0,
description="Kelly-derived position size as % of portfolio (set post-LLM)",
)
kelly_win_rate: float = Field(
default=0.0,
description="Historical win rate used for Kelly calc (set post-LLM)",
)
kelly_total_trades: int = Field(
default=0,
description="Number of trades used for Kelly calc (set post-LLM)",
)
def to_report(self) -> str:
"""Render as the markdown report format the pipeline expects."""
qb = _strip_headers(self.quantitative_base)
lp = _strip_headers(self.lynch_pitch)
mi = _strip_headers(self.munger_invert)
report = (
f"### THE QUANTITATIVE BASE (Graham / Asset Play)\n"
f"{qb}\n\n"
f"### THE LYNCH PITCH (Why I would own this)\n"
f"{lp}\n\n"
f"### THE MUNGER INVERT (How I could lose money)\n"
f"{mi}\n\n"
f"### FINAL VERDICT\n"
f"**{self.verdict}** — {self.bottom_line}"
)
if self.position_size > 0:
report += (
f"\n\n### POSITION SIZING (Kelly Criterion)\n"
f"**Recommended allocation: {self.position_size:.1f}% of portfolio**\n"
f"Based on historical win rate of {self.kelly_win_rate * 100:.0f}% "
f"across {self.kelly_total_trades} trades."
)
return report
|