Skip to content

kelly_criterion is off by a factor of the average loss, and rf is routed by inspecting the call stack #537

Description

@lenamonj

Both findings are backed by closed-form identities, so the expected values are checkable independently of my code.

1. kelly_criterion returns the growth-optimal fraction multiplied by the average loss. On a two-outcome series with p = 0.60, win +2%, loss -1%, the closed-form Kelly fraction is 39.9985 and the function returns 0.399985 - exactly 1/l smaller. The function is also scale-invariant, returning the same 0.03554685 for a series scaled by 1.0, 0.5 and 0.1, where true Kelly moves 2.86, 5.72 and 28.62. Issue #535 frames this as discrete versus continuous Kelly, which I think is not quite the sharpest statement of it.

2. The risk-free rate is selected by caller name. _prepare_returns inspects inspect.stack(), with the effect that cagr(r, rf=0.00) and cagr(r, rf=0.50) both return 0.2163540607973844. The separate if rf > 0 guard also discards negative rates everywhere. That the intent differs is visible inside reports.py, which passes rf at line 1314 and 0.0 at lines 1550-1563; at present all five paths return the same number.

Two further items worth a look: aggregate_returns silently no-ops on its documented 'M', 'Q' and 'Y' arguments, so best(aggregate='Y') returns the best single day, and raises AttributeError on 'W' since .week was removed in pandas 2.0; and information_ratio is not annualized while sharpe is, a gap of exactly sqrt(252).

For balance, I looked at issue #514 (arithmetic versus geometric active return) and think it should be declined - arithmetic active return is the Grinold-Kahn convention and matches your docstring. Issue #518 did not reproduce for me, and #493 looks like correct period statistics rather than a defect.

I have a patch: repro goes 26 failing to 33/33, and your suite stays at 125 passing with nothing weakened. Glad to open a PR.

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