Skip to content

SIGNAL-SCORE-001: Implement explainable signal-strength scoring #37

Description

@jamalfrnk

Problem

technical-analysis.ts computes real indicators (EMA/MACD/RSI/ADX/Fisher Transform/Keltner/ATR per prior audit) but there is no unified, explainable 0-100 "signal strength" score model -- indicator outputs aren't currently composed into a single defensible score.

Repository evidence

server/src/technical-analysis.ts -- indicator computation exists; no scoring/composition layer or versioning scheme found.

Risk

P2 -- valuable product/educational feature, not release-blocking, but load-bearing for BACKTEST-001 (which needs a stable, versioned signal to grade) and for the "signal strength vs backtest evidence vs sample adequacy" distinction the mission requires.

Scope

  • Deterministic, versioned score model (0-100) from actually-implemented indicators only -- no invented indicators.
  • Documented, non-arbitrary weighting rationale for trend agreement, momentum agreement, trend-strength confirmation, volatility suitability, data freshness, indicator availability, conflicting conditions, invalidation conditions.
  • Expose total score, direction, component scores, indicators used/missing, freshness status, signal-engine version, score-model version, candle interval, source/generation timestamps, plain-language explanation.
  • Label as "Signal strength" everywhere in the UI/API, never probability/confidence/expected-return language.
  • Explanatory tooltip/details text per the mission's specified copy.

Non-goals

No claim of statistical calibration (score is agreement-based, not a calibrated probability) unless a future model proves otherwise; no per-user customizable weighting in this issue.

Dependencies

None strictly, but the score model's version needs to be stable before BACKTEST-001 references it.

Proposed implementation

A pure, DB-free scoring function (following the existing pattern of keeping computation testable without DB coupling, as used in analytics/metrics.ts) taking indicator outputs and freshness/availability flags, returning the full score contract as a Zod-validated shape shared client/server (mirroring the analytics.ts discriminated-union pattern from DATA-015).

Acceptance criteria

Score, direction, component breakdown, and versions are computed deterministically for a fixed indicator-input fixture; UI never uses banned probability/confidence language; explanation copy matches the mission's required tooltip text.

Definition of done

Unit tests cover deterministic scoring across representative indicator-agreement/disagreement fixtures; reviewer PASS; docs/product/signal-strength.md written.

Test plan

Fixed-fixture tests: full agreement (near-100), full disagreement (near-0), missing-indicator handling, stale-data handling, invalidation-condition triggering, version-stability across repeated runs with identical input.

Security review

No new external input surface -- purely a computation over already-validated internal data.

Accessibility review

Score display must not rely on color alone (mission-mandated for charts, applies here too).

Observability requirements

Log signal-generation duration and any indicator-computation failures with reason.

Performance considerations

Scoring must not materially slow the existing 30s signal-generation cycle.

Rollback plan

Revert PR; existing raw-indicator signal generation is unaffected as a fallback.

Documentation requirements

docs/product/signal-strength.md.

Completion evidence

(added on merge)

Reviewer verdict

(pending)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Valuable hardening, scalability, or developer-experience workepic:signalsSignal generation and scoring

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions