feat: Pattern Lab Discover + fix history run display
Fix: history runs now always show results — create synthetic selected preset from run data when no matching preset found (was broken for custom events). Also force mode='events' and reset matchResults on history load. Discover tab: new "Discover" panel in left sidebar (AI knowledge search). - GPT-4o generates 6 matching events from a free-text query (date, assets, hint) - Confidence score + category badge per event - Click → pre-fills experiment form exactly like a preset → ready to Run - Backend: POST /api/pattern-lab/discover (DiscoverRequest, sorted by confidence) - Frontend: useDiscoverEvents hook + DiscoveredEvent type + Discover UI with Enter-to-search, spinner, empty states Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -49,6 +49,11 @@ class FindMatchingRequest(BaseModel):
|
||||
pattern_index: int
|
||||
|
||||
|
||||
class DiscoverRequest(BaseModel):
|
||||
query: str
|
||||
n: int = 6
|
||||
|
||||
|
||||
class InstrumentScanRequest(BaseModel):
|
||||
ticker: str
|
||||
instrument_name: str
|
||||
@@ -270,6 +275,57 @@ def evaluate_instrument_run(run_id: str):
|
||||
return {"run_id": run_id, "outcomes": outcomes}
|
||||
|
||||
|
||||
@router.post("/discover")
|
||||
async def discover_events(req: DiscoverRequest):
|
||||
"""Use GPT-4o to generate historical/recent event suggestions matching the query."""
|
||||
from openai import AsyncOpenAI
|
||||
key = get_config("openai_api_key") or ""
|
||||
if not key:
|
||||
raise HTTPException(400, "OpenAI API key not configured")
|
||||
client = AsyncOpenAI(api_key=key)
|
||||
|
||||
prompt = f"""You are a financial markets research expert specialized in geopolitical and macro events.
|
||||
|
||||
Query: "{req.query}"
|
||||
|
||||
Identify {req.n} specific real events (2000-2025) that match this query and are relevant for options/derivatives trading analysis.
|
||||
Prioritize events with clear market impact and dateable start points.
|
||||
|
||||
Return ONLY valid JSON:
|
||||
{{
|
||||
"events": [
|
||||
{{
|
||||
"label": "Concise event name",
|
||||
"date": "YYYY-MM-DD",
|
||||
"category": "geopolitical|macro|volatility|commodities|fx_macro|credit",
|
||||
"horizon_days": 60,
|
||||
"assets": ["TICKER1", "TICKER2", "TICKER3"],
|
||||
"hint": "2-3 sentence market context for a trader: what happened, why it matters, key dynamics.",
|
||||
"confidence": 90
|
||||
}}
|
||||
]
|
||||
}}
|
||||
|
||||
Rules:
|
||||
- Use valid Yahoo Finance tickers (SPY, GLD, USO, EURUSD=X, BTC-USD, etc.)
|
||||
- horizon_days: typical holding period to capture the event's full market impact
|
||||
- confidence: 0-100, how well-documented and dateable this event is
|
||||
- Diversify dates and instruments across the {req.n} results"""
|
||||
|
||||
resp = await client.chat.completions.create(
|
||||
model="gpt-4o",
|
||||
messages=[{"role": "user", "content": prompt}],
|
||||
response_format={"type": "json_object"},
|
||||
temperature=0.3,
|
||||
timeout=30,
|
||||
)
|
||||
result = json.loads(resp.choices[0].message.content)
|
||||
events = result.get("events", [])
|
||||
# Sort by confidence desc
|
||||
events.sort(key=lambda e: e.get("confidence", 0), reverse=True)
|
||||
return {"events": events, "source": "ai", "query": req.query}
|
||||
|
||||
|
||||
@router.post("/find-matching")
|
||||
async def find_matching_pattern(req: FindMatchingRequest):
|
||||
"""Ask GPT-4o-mini if this lab pattern matches / counter-scenario an existing library pattern."""
|
||||
|
||||
Reference in New Issue
Block a user