da83f027e1
Answers "why does a too-far-progressed setup still show": setups are only recalculated by the scheduled R:R scan and manual fetch; at creation entry == current price (0% progress), so over-progression is a between-scans drift effect and must be judged at read time. - /trades now attaches current_price (latest close per ticker). - Qualification drops setups whose R:R recomputed from the current price falls below min_rr — i.e. price already ran toward target (reward consumed) or through the stop. Reuses the existing min_rr threshold instead of a separate progress %; far cleaner (a 3:1 is already ~1:1 by 33% progress). Skipped for historical setups (no current_price). - Fix: useFetchSymbolData now invalidates the trades queries, so a fetch/ recompute actually refreshes confidence/setups in the UI (was the cause of the stale 100% confidence lingering after recompute). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
52 lines
1.3 KiB
Python
52 lines
1.3 KiB
Python
"""Pydantic schemas for trade setup endpoints."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from datetime import date, datetime
|
|
|
|
from pydantic import BaseModel, Field
|
|
|
|
|
|
class TradeTargetResponse(BaseModel):
|
|
price: float
|
|
distance_from_entry: float
|
|
distance_atr_multiple: float
|
|
rr_ratio: float
|
|
probability: float
|
|
classification: str
|
|
sr_level_id: int
|
|
sr_strength: float
|
|
is_primary: bool = False
|
|
|
|
|
|
class RecommendationSummaryResponse(BaseModel):
|
|
action: str
|
|
reasoning: str | None
|
|
risk_level: str | None
|
|
composite_score: float
|
|
|
|
|
|
class TradeSetupResponse(BaseModel):
|
|
"""A single trade setup detected by the R:R scanner."""
|
|
|
|
id: int
|
|
symbol: str
|
|
direction: str
|
|
entry_price: float
|
|
stop_loss: float
|
|
target: float
|
|
rr_ratio: float
|
|
composite_score: float
|
|
detected_at: datetime
|
|
confidence_score: float | None = None
|
|
targets: list[TradeTargetResponse] = Field(default_factory=list)
|
|
conflict_flags: list[str] = Field(default_factory=list)
|
|
recommended_action: str | None = None
|
|
reasoning: str | None = None
|
|
risk_level: str | None = None
|
|
actual_outcome: str | None = None
|
|
outcome_date: date | None = None
|
|
evaluated_at: datetime | None = None
|
|
current_price: float | None = None
|
|
recommendation_summary: RecommendationSummaryResponse | None = None
|