Setup views: primary-target column, floor-target prune, liveness cutoff
Three follow-ups to the gate probability floor (8f41143):
- Signals table shows the starred primary target (shared primaryTarget
helper) instead of an independently computed max-probability best,
so Overview, Signals and ticker details agree by construction.
- Targets pinned at the 3% probability clamp floor collapse to the
nearest one (enhance_trade_setup + backtest candidates in parity):
floor-pinned levels are indistinguishable to the model, so farther
ones were duplicate 3% rows inviting lottery headlines.
- get_trade_setups only returns setups re-emitted within
LIVE_SETUP_MAX_AGE_DAYS (3): an older latest row means the daily
scan no longer confirms the setup, and such rows otherwise surface
forever on Overview/Signals/ticker/alerts. History endpoints keep
full history.
Backtest on the Jul-3 snapshot is metric-identical to the gate-floor
run on all qualified stats (1089 qualified, Sharpe 2.02, CAGR +49.6%,
DD -15.8%): the prune only removes noise the gate already rejected.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import type { ActivationConfig, TradeSetup } from './types';
|
||||
import type { ActivationConfig, TradeSetup, TradeTarget } from './types';
|
||||
|
||||
const HIGH_CONVICTION_ACTIONS = new Set(['LONG_HIGH', 'SHORT_HIGH']);
|
||||
|
||||
@@ -16,15 +16,18 @@ function actionDirection(action: TradeSetup['recommended_action']): 'long' | 'sh
|
||||
return 'neutral';
|
||||
}
|
||||
|
||||
export function bestTargetProbability(setup: TradeSetup): number {
|
||||
return setup.targets?.length ? Math.max(...setup.targets.map((t) => t.probability)) : 0;
|
||||
/** The starred primary target (the one the headline R:R refers to), falling
|
||||
* back to the most likely target when no star is stored. */
|
||||
export function primaryTarget(setup: TradeSetup): TradeTarget | null {
|
||||
const starred = setup.targets?.find((t) => t.is_primary);
|
||||
if (starred) return starred;
|
||||
if (!setup.targets?.length) return null;
|
||||
return [...setup.targets].sort((a, b) => b.probability - a.probability)[0];
|
||||
}
|
||||
|
||||
/** Probability of the starred primary target (the one the headline R:R refers to). */
|
||||
export function primaryTargetProbability(setup: TradeSetup): number | null {
|
||||
const primary = setup.targets?.find((t) => t.is_primary);
|
||||
if (primary) return primary.probability;
|
||||
return setup.targets?.length ? bestTargetProbability(setup) : null;
|
||||
return primaryTarget(setup)?.probability ?? null;
|
||||
}
|
||||
|
||||
/** R:R recomputed from the current price (0 if no reward/risk left). */
|
||||
|
||||
Reference in New Issue
Block a user