diff --git a/README.md b/README.md index e97d2ad..6e70d69 100644 --- a/README.md +++ b/README.md @@ -108,6 +108,13 @@ price. Hover a bar to inspect its price, crossing count, strength and source. The violet profile is deliberately distinct from the Structural S/R lines and is off by default; it is a research aid, not another trade overlay. +Below the chart, the **Production rank** strip makes the current 80/20 ordering +snapshot explicit: a blue residual-momentum contribution and amber realized- +volatility contribution add to the stored strategy rank, while separate +percentile rails show each input. Only momentum carries the live activation- +gate marker. These are cross-sectional scan percentiles, not historical chart +indicators. + ### Daily Load — the full refresh Once a day (default 07:00). Steps run **in dependency order**, each consuming the previous step's fresh output: @@ -284,6 +291,7 @@ Corollaries: never let an unvalidated score gate setups; the outcome evaluator m - Interactive candlestick chart (Canvas 2D) with hover tooltips showing OHLCV values - Support/Resistance level overlays on chart (top 6 by strength, dashed lines with labels) - Optional GTL price-traffic profile on the ticker chart (right-edge diagnostic; explicitly not volume) +- Production-rank strip below the ticker chart (80/20 contribution ledger plus separate momentum and volatility percentiles) - Data freshness bar showing availability and recency of each data source - Watchlist with composite scores, R:R ratios, and S/R summaries - Ticker detail page: chart, scores, sentiment breakdown, fundamentals, technical indicators, S/R table diff --git a/frontend/src/components/ticker/ProductionRankStrip.tsx b/frontend/src/components/ticker/ProductionRankStrip.tsx new file mode 100644 index 0000000..33df0ab --- /dev/null +++ b/frontend/src/components/ticker/ProductionRankStrip.tsx @@ -0,0 +1,205 @@ +import type { TradeSetup } from '../../lib/types'; + +const MOMENTUM_WEIGHT = 0.8; +const VOLATILITY_WEIGHT = 0.2; + +interface ProductionRankStripProps { + setup?: TradeSetup; + momentumGate: number; +} + +function clampPercent(value: number): number { + return Math.min(100, Math.max(0, value)); +} + +function topShare(value: number): string { + return `${Math.max(1, Math.round(100 - clampPercent(value)))}%`; +} + +function PercentileRail({ + value, + colorClass, + gate, + gateLabel, +}: { + value: number | null; + colorClass: string; + gate?: number; + gateLabel?: string; +}) { + const normalized = value == null ? 0 : clampPercent(value); + const normalizedGate = gate == null ? null : clampPercent(gate); + + return ( +
+ Production rank +
+ {rank != null ? ( ++ {normalizedRank.toFixed(1)} + %ile +
+ ) : ( +Unavailable
+ )} +top {topShare(normalizedRank)} of the universe
+ )} + {momentum != null && gateEnabled && ( ++ momentum gate {gatePassed ? 'passed' : 'not passed'} +
+ )} +80/20 weighted rank
++ {hasBlend + ? `${momentumContribution.toFixed(1)} momentum + ${volatilityContribution.toFixed(1)} volatility` + : 'momentum-only fallback / volatility rank unavailable'} +
+Residual 12-1 momentum
+80% weight / activation signal
++ {momentum == null ? '-' : momentum.toFixed(1)} +
+ {momentum != null && ( +top {topShare(momentum)}
+ )} +6-month realized volatility
+20% weight / ordering tilt only
++ {volatility == null ? '-' : volatility.toFixed(1)} +
+ {volatility != null && ( +top {topShare(volatility)}
+ )} ++ Cross-sectional snapshot from the latest setup scan - not a historical price indicator. + Volatility can improve ordering, but it never opens the activation gate by itself. +
+