Skip to content

sharpe/sortino return 0.0 on degenerate input while cagr returns NaN — inconsistent and dangerous #9

Description

@algotester123

Problem

The metrics module disagrees with itself about how to signal "undefined":

function degenerate input returns
cagr (metrics.py:12) empty series NaN
sharpe (metrics.py:21) zero/NaN volatility 0.0
sortino (metrics.py:29) no downside 0.0
calmar (metrics.py:41) no drawdown NaN

Why it matters

0.0 is a plausible real value. A Sharpe of exactly zero means "this strategy earned nothing per unit of risk" — a genuine, interpretable result. Returning it for "I could not compute this" makes the two indistinguishable downstream.

This is the same class of bug the project already fixed once in significance.py, where a NaN-poisoned bootstrap was fabricating p_delta_gt_0 = 0.0 and a confident verdict. The fix there was to return an explicit UNDEFINED rather than a number that looks real. metrics.py still has the original pattern, and deflated_sharpe.py consumes these values.

A flat cash-only sleeve (zero variance) is not a hypothetical input here — the demo strategy can go fully to cash.

Proposed fix

Return float("nan") from sharpe and sortino for undefined cases, matching cagr/calmar. Update summarize() and table() to render NaN distinctly (e.g. n/a) instead of printing 0.00.

This is a behaviour change, so it needs a note in the changelog and a check of anything comparing metrics with >/< (NaN comparisons are always False — that's the safe direction, but it should be deliberate).

Acceptance criteria

  • Zero-variance input yields NaN, not 0.0, from sharpe/sortino
  • A genuine zero-Sharpe strategy still returns exactly 0.0 and is distinguishable from undefined
  • table() renders undefined cells as n/a
  • Existing callers audited for NaN-comparison assumptions

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

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions