feat: signal math upgrade — probabilistic, regime-aware scoring pipeline
ci/woodpecker/push/test Pipeline was successful
ci/woodpecker/push/build-1 Pipeline was successful
ci/woodpecker/push/build-2 Pipeline was successful
ci/woodpecker/push/build-3 Pipeline was successful
ci/woodpecker/push/finalize Pipeline was successful
Build and Push / lint-and-test (push) Has been cancelled
Build and Push / build-services (map[cmd:python -m services.adapters.broker_adapter name:broker-adapter]) (push) Has been cancelled
Build and Push / build-services (map[cmd:python -m services.aggregation.worker name:aggregation]) (push) Has been cancelled
Build and Push / build-services (map[cmd:python -m services.extractor.worker name:extractor]) (push) Has been cancelled
Build and Push / build-services (map[cmd:python -m services.ingestion.worker name:ingestion]) (push) Has been cancelled
Build and Push / build-services (map[cmd:python -m services.lake_publisher.worker name:lake-publisher]) (push) Has been cancelled
Build and Push / build-services (map[cmd:python -m services.parser.worker name:parser]) (push) Has been cancelled
Build and Push / build-services (map[cmd:python -m services.recommendation.worker name:recommendation]) (push) Has been cancelled
Build and Push / build-services (map[cmd:python -m services.scheduler.app name:scheduler]) (push) Has been cancelled
Build and Push / build-services (map[cmd:uvicorn services.api.app:app --host 0.0.0.0 --port 8000 name:query-api]) (push) Has been cancelled
Build and Push / build-services (map[cmd:uvicorn services.risk.app:app --host 0.0.0.0 --port 8000 name:risk]) (push) Has been cancelled
Build and Push / build-services (map[cmd:uvicorn services.symbol_registry.app:app --host 0.0.0.0 --port 8000 name:symbol-registry]) (push) Has been cancelled
Build and Push / build-services (map[cmd:uvicorn services.trading.app:app --host 0.0.0.0 --port 8000 name:trading-engine]) (push) Has been cancelled
Build and Push / build-dashboard (push) Has been cancelled
Build and Push / build-superset (push) Has been cancelled
Build and Push / integration-test (push) Has been cancelled
Build and Push / beta-gate (push) Has been cancelled
ci/woodpecker/push/test Pipeline was successful
ci/woodpecker/push/build-1 Pipeline was successful
ci/woodpecker/push/build-2 Pipeline was successful
ci/woodpecker/push/build-3 Pipeline was successful
ci/woodpecker/push/finalize Pipeline was successful
Build and Push / lint-and-test (push) Has been cancelled
Build and Push / build-services (map[cmd:python -m services.adapters.broker_adapter name:broker-adapter]) (push) Has been cancelled
Build and Push / build-services (map[cmd:python -m services.aggregation.worker name:aggregation]) (push) Has been cancelled
Build and Push / build-services (map[cmd:python -m services.extractor.worker name:extractor]) (push) Has been cancelled
Build and Push / build-services (map[cmd:python -m services.ingestion.worker name:ingestion]) (push) Has been cancelled
Build and Push / build-services (map[cmd:python -m services.lake_publisher.worker name:lake-publisher]) (push) Has been cancelled
Build and Push / build-services (map[cmd:python -m services.parser.worker name:parser]) (push) Has been cancelled
Build and Push / build-services (map[cmd:python -m services.recommendation.worker name:recommendation]) (push) Has been cancelled
Build and Push / build-services (map[cmd:python -m services.scheduler.app name:scheduler]) (push) Has been cancelled
Build and Push / build-services (map[cmd:uvicorn services.api.app:app --host 0.0.0.0 --port 8000 name:query-api]) (push) Has been cancelled
Build and Push / build-services (map[cmd:uvicorn services.risk.app:app --host 0.0.0.0 --port 8000 name:risk]) (push) Has been cancelled
Build and Push / build-services (map[cmd:uvicorn services.symbol_registry.app:app --host 0.0.0.0 --port 8000 name:symbol-registry]) (push) Has been cancelled
Build and Push / build-services (map[cmd:uvicorn services.trading.app:app --host 0.0.0.0 --port 8000 name:trading-engine]) (push) Has been cancelled
Build and Push / build-dashboard (push) Has been cancelled
Build and Push / build-superset (push) Has been cancelled
Build and Push / integration-test (push) Has been cancelled
Build and Push / beta-gate (push) Has been cancelled
Implement full probabilistic signal processing pipeline gated behind probabilistic_scoring_enabled feature flag in risk_configs: - Bayesian log-likelihood accumulator with Beta posterior and entropy - Regime detector (trend-following, panic, mean-reversion, uncertainty) - Source accuracy tracker with per-source historical prediction accuracy - Sigmoid confidence gate replacing binary gate - Information gain surprise weighting for rare events - Adaptive recency decay with event-specific half-lives - Regime multiplier replacing market context multiplier - Weighted disagreement entropy for contradiction detection - Multiplicative macro exposure with conditional integration - Graph-distance attenuated competitive signal propagation - Exponentially weighted momentum with volatility scaling - Expected value recommendation gate All changes backward-compatible: flag=false preserves exact current behavior. New outputs stored in existing JSONB columns (no schema changes except source_accuracy table via migration 034). Tests: 26 property-based tests (14 correctness properties), 99 unit tests, 1789 total tests passing with zero regressions.
This commit is contained in:
@@ -4,7 +4,7 @@ Computes TrendProjection objects by combining current trend momentum,
|
||||
macro signal decay trajectories, and upcoming catalyst outlook.
|
||||
Projections are persisted alongside trend_window records.
|
||||
|
||||
Requirements: 12.1, 12.2, 12.3, 12.4, 12.5, 12.9
|
||||
Requirements: 12.1, 12.2, 12.3, 12.4, 12.5, 12.9, 13.1, 13.2, 13.3, 13.4, 13.5, 13.6
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
@@ -126,6 +126,87 @@ def _direction_sign(direction: str) -> float:
|
||||
return 0.0
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Exponentially weighted momentum (Requirements: 13.1–13.6)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
def compute_ew_momentum(
|
||||
strength_changes: list[float],
|
||||
lambda_decay: float = 0.7,
|
||||
) -> float:
|
||||
"""Compute exponentially weighted momentum from historical strength changes.
|
||||
|
||||
Formula: M_t = Σ_{k=0}^{K-1} λ^k · ΔS_{t-k}
|
||||
Normalized by geometric series sum Σ λ^k to produce value in [-1, 1].
|
||||
|
||||
When fewer than 2 historical cycles are available, returns 0.0
|
||||
(caller should fall back to heuristic).
|
||||
|
||||
Args:
|
||||
strength_changes: List of signed strength changes ΔS, most recent first.
|
||||
Each value represents the change in signed trend strength from one
|
||||
cycle to the next. Positive = strengthening bullish / weakening bearish.
|
||||
lambda_decay: Decay factor λ (default 0.7). Must be in (0, 1).
|
||||
|
||||
Returns:
|
||||
Normalized momentum in [-1, 1]. Returns 0.0 for empty or single-element lists.
|
||||
|
||||
Requirements: 13.1, 13.2, 13.3, 13.6
|
||||
"""
|
||||
if len(strength_changes) < 2:
|
||||
return 0.0
|
||||
|
||||
# Use up to K=10 most recent changes, filtering out NaN values
|
||||
k_max = min(len(strength_changes), 10)
|
||||
changes = strength_changes[:k_max]
|
||||
|
||||
weighted_sum = 0.0
|
||||
weight_sum = 0.0
|
||||
for k, delta_s in enumerate(changes):
|
||||
if math.isnan(delta_s):
|
||||
continue
|
||||
w = lambda_decay ** k
|
||||
weighted_sum += w * delta_s
|
||||
weight_sum += w
|
||||
|
||||
if weight_sum == 0.0:
|
||||
return 0.0
|
||||
|
||||
normalized = weighted_sum / weight_sum
|
||||
# Guard against NaN propagation
|
||||
if math.isnan(normalized) or math.isinf(normalized):
|
||||
return 0.0
|
||||
return max(-1.0, min(1.0, normalized))
|
||||
|
||||
|
||||
def compute_volatility_scaled_momentum(
|
||||
momentum: float,
|
||||
sigma_20: float,
|
||||
) -> float:
|
||||
"""Compute volatility-scaled momentum.
|
||||
|
||||
Formula: M_adj = M_t / max(σ_20, 0.01), clamped to [-2.0, 2.0].
|
||||
|
||||
Normalizes momentum relative to the ticker's typical price movement.
|
||||
|
||||
Args:
|
||||
momentum: Raw or EW momentum value.
|
||||
sigma_20: 20-day return standard deviation.
|
||||
|
||||
Returns:
|
||||
Volatility-scaled momentum in [-2.0, 2.0].
|
||||
|
||||
Requirements: 13.4, 13.5
|
||||
"""
|
||||
denominator = max(sigma_20, 0.01)
|
||||
scaled = momentum / denominator
|
||||
# Guard against NaN propagation
|
||||
if math.isnan(scaled) or math.isinf(scaled):
|
||||
return 0.0
|
||||
return max(-2.0, min(2.0, scaled))
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Macro signal decay projection
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user