fix(macro): dead placeholder indicators no longer compress composite score
scoring.py docstring promises: 'Missing indicators are excluded and the remaining weights renormalised — so a single dead API doesn't drag the whole score toward zero.' But _stablecoin_supply_signal and _open_interest_signal returned 0.0 (not None) as placeholders — so they stayed in the alive set, kept their combined 0.10 weight in the denominator, and contributed 0, systematically compressing the composite toward zero by ~10%. Example: ahr999 deeply cheap (+1) alone should score +100, but the two 0.0 placeholders dragged it to 80. Now they return None → excluded + renormalised, matching the module's own stated design. Verified: same input now scores 100. Re-activate either by returning a real [-1,+1] signal once a trend lookup is wired in. 72 tests pass. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -74,11 +74,16 @@ def _eth_btc_signal(v: Optional[float]) -> Optional[float]:
|
|||||||
|
|
||||||
|
|
||||||
def _stablecoin_supply_signal(v: Optional[float]) -> Optional[float]:
|
def _stablecoin_supply_signal(v: Optional[float]) -> Optional[float]:
|
||||||
"""Absolute supply tells us little day-over-day; we need the delta. Since
|
"""Absolute supply tells us little day-over-day; we need the delta, which
|
||||||
this scorer sees only the snapshot, we treat presence as 0 and let the
|
this snapshot-only scorer doesn't have yet.
|
||||||
visual chart show the trend. Returns 0 if we have any value at all."""
|
|
||||||
if v is None: return None
|
Return None (NOT 0.0) so this indicator is EXCLUDED from the weighted sum
|
||||||
return 0.0 # contribution = 0 until we wire in a trend lookup
|
and its weight is renormalised away — exactly the "a dead indicator must
|
||||||
|
not drag the score toward zero" rule stated in the module docstring.
|
||||||
|
Returning 0.0 would keep its 0.05 weight in the denominator and silently
|
||||||
|
compress every other indicator's contribution. Wire in a trend lookup to
|
||||||
|
re-activate it."""
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def _etf_flow_signal(v: Optional[float]) -> Optional[float]:
|
def _etf_flow_signal(v: Optional[float]) -> Optional[float]:
|
||||||
@@ -95,9 +100,10 @@ def _etf_flow_signal(v: Optional[float]) -> Optional[float]:
|
|||||||
|
|
||||||
def _open_interest_signal(v: Optional[float]) -> Optional[float]:
|
def _open_interest_signal(v: Optional[float]) -> Optional[float]:
|
||||||
"""OI in isolation doesn't tell us direction — we'd need OI vs price
|
"""OI in isolation doesn't tell us direction — we'd need OI vs price
|
||||||
correlation. Until we have a trend window, contribute 0."""
|
correlation. Return None (NOT 0.0) until we have a trend window, so this
|
||||||
if v is None: return None
|
indicator is excluded + its weight renormalised away rather than diluting
|
||||||
return 0.0
|
every other indicator. (Same reasoning as _stablecoin_supply_signal.)"""
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
# Weights (sum to 1.0 across all). When an indicator is missing, we drop its
|
# Weights (sum to 1.0 across all). When an indicator is missing, we drop its
|
||||||
|
|||||||
Reference in New Issue
Block a user