Fix sidebar username, Signals filter clarity and layout
- JWT now carries a username claim; sidebar shows "Signed in as <name>" instead of the bare user id (sub). Re-login required for the new claim. - Signals: Min R:R / Min Confidence inputs reflect the effective filter — auto-filled from the activation gate when "Qualified only" is on, reset to 0 when off (no more misleading 0 while the gate is active). - Signals layout: Run Scanner moved to its own action row (it's a job trigger, not a filter); qualified toggle grouped with the refinement filters under one Filters panel. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -59,6 +59,7 @@ async def login(db: AsyncSession, username: str, password: str) -> str:
|
||||
|
||||
payload = {
|
||||
"sub": str(user.id),
|
||||
"username": user.username,
|
||||
"role": user.role,
|
||||
"exp": datetime.now(timezone.utc) + timedelta(minutes=settings.jwt_expiry_minutes),
|
||||
}
|
||||
|
||||
@@ -443,6 +443,29 @@ def _build_reasoning(
|
||||
)
|
||||
|
||||
|
||||
PRIMARY_TARGET_MIN_RR = 1.5
|
||||
|
||||
|
||||
def _select_primary_target(targets: list[dict], min_rr: float = PRIMARY_TARGET_MIN_RR) -> dict | None:
|
||||
"""Primary = the most LIKELY target that still offers real asymmetry.
|
||||
|
||||
Among targets clearing a minimal R:R floor, pick the highest probability
|
||||
(tie-break by R:R). This fixes the old pick, which ignored probability and
|
||||
could land on the furthest, least-likely 'lottery' level. Stronger-reward
|
||||
levels remain in the table as stretch targets. Falls back to the highest-R:R
|
||||
target if nothing clears the floor.
|
||||
"""
|
||||
if not targets:
|
||||
return None
|
||||
|
||||
worthwhile = [t for t in targets if float(t.get("rr_ratio", 0.0)) >= min_rr]
|
||||
pool = worthwhile or targets
|
||||
return max(
|
||||
pool,
|
||||
key=lambda t: (float(t.get("probability", 0.0)), float(t.get("rr_ratio", 0.0))),
|
||||
)
|
||||
|
||||
|
||||
async def enhance_trade_setup(
|
||||
db: AsyncSession,
|
||||
ticker: Ticker,
|
||||
@@ -494,6 +517,17 @@ async def enhance_trade_setup(
|
||||
config=config,
|
||||
)
|
||||
|
||||
# Primary target = most-likely target with real asymmetry (see
|
||||
# _select_primary_target), not the old quality-score pick that ignored
|
||||
# probability. Sync the setup's headline target/rr_ratio so the chart, gate
|
||||
# and outcome eval all agree with the table's starred row.
|
||||
primary = _select_primary_target(targets)
|
||||
if primary is not None:
|
||||
for target in targets:
|
||||
target["is_primary"] = target is primary
|
||||
setup.target = round(float(primary["price"]), 4)
|
||||
setup.rr_ratio = round(float(primary["rr_ratio"]), 4)
|
||||
|
||||
# Per-setup conflicts (target availability is specific to this setup)
|
||||
setup_conflicts = list(conflicts)
|
||||
if len(targets) < 3:
|
||||
|
||||
Reference in New Issue
Block a user