promote residual momentum ranking
Deploy / lint (push) Successful in 7s
Deploy / test (push) Successful in 1m8s
Deploy / deploy (push) Successful in 35s

This commit is contained in:
2026-07-02 21:00:39 +02:00
parent 849489a4b5
commit aadec7d403
21 changed files with 310 additions and 185 deletions
+5 -5
View File
@@ -33,9 +33,9 @@ export function qualifiesSetup(setup: TradeSetup, config: ActivationConfig): boo
return false;
}
if ((setup.confidence_score ?? 0) < config.min_confidence) return false;
// Cross-sectional momentum is the core selection (long-only). While the gate is
// active, shorts never qualify; the percentile floor is enforced only when a
// percentile is attached, otherwise defer to the floors.
// Residual cross-sectional momentum is the core selection (long-only). While
// the gate is active, shorts never qualify; the percentile floor is enforced
// only when a percentile is attached, otherwise defer to the floors.
if (config.min_momentum_percentile > 0) {
if (setup.direction === 'short') return false;
if (setup.momentum_percentile != null && setup.momentum_percentile < config.min_momentum_percentile) {
@@ -53,7 +53,7 @@ export function qualifiesSetup(setup: TradeSetup, config: ActivationConfig): boo
/**
* 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
* the highest residual 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.
*/
@@ -74,7 +74,7 @@ export function topPickSymbol(
/** Short human summary of the active gate, e.g. for tooltips/labels. */
export function activationSummary(config: ActivationConfig): string {
const parts = [];
if (config.min_momentum_percentile > 0) parts.push(`top ${(100 - config.min_momentum_percentile).toFixed(0)}% momentum`);
if (config.min_momentum_percentile > 0) parts.push(`top ${(100 - config.min_momentum_percentile).toFixed(0)}% residual momentum`);
parts.push(`R:R ≥ ${config.min_rr.toFixed(1)}`, `conf ≥ ${config.min_confidence.toFixed(0)}%`);
if (config.exclude_neutral) parts.push('directional');
if (config.require_high_conviction) parts.push('high-conviction');