feat: top-pick and open-trade status labels on the ticker page
Deploy / lint (push) Successful in 6s
Deploy / test (push) Successful in 42s
Deploy / deploy (push) Successful in 25s

Two read-only pills in the ticker header, beside the watchlist toggle:
- "Top Pick" when the ticker is the current #1 — the same ranking the dashboard
  highlights, via a shared topPickSymbol() helper so the two stay in sync.
- "Open Trade" when an open paper trade exists on the ticker.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-27 16:04:55 +02:00
parent 2f21c685e8
commit d15acb8741
2 changed files with 68 additions and 0 deletions
+20
View File
@@ -49,6 +49,26 @@ export function qualifiesSetup(setup: TradeSetup, config: ActivationConfig): boo
return true;
}
/**
* Symbol of the current single 'top pick' — the #1 row the dashboard highlights:
* the highest 12-1 momentum percentile among qualified setups (or among all
* setups when none qualify). Returns null when there are no setups. Keep in step
* with the Top Setups ranking in DashboardPage.
*/
export function topPickSymbol(
trades: TradeSetup[] | undefined,
activation: ActivationConfig | undefined,
): string | null {
const all = trades ?? [];
if (all.length === 0) return null;
const qualified = activation ? all.filter((t) => qualifiesSetup(t, activation)) : [];
const pool = qualified.length > 0 ? qualified : all;
const top = [...pool].sort(
(a, b) => (b.momentum_percentile ?? -Infinity) - (a.momentum_percentile ?? -Infinity),
)[0];
return top?.symbol ?? null;
}
/** Short human summary of the active gate, e.g. for tooltips/labels. */
export function activationSummary(config: ActivationConfig): string {
const parts = [];