stats.py threads a risk-free rate through four functions — _stats, metrics, summary,
summary_markdown — and into Data.from_prices(..., rf=rf). Nothing sets it:
$ grep -rn '\brf\b' src/ tests/
src/jointview/stats.py:36: def _stats(..., rf: float = 0.0)
src/jointview/stats.py:48: return Data.from_prices(levels, date_col=date_col, rf=rf).stats
src/jointview/stats.py:100: def metrics(..., rf: float = 0.0)
src/jointview/stats.py:118: stats = _stats(frame, column, date_col=date_col, rf=rf)
src/jointview/stats.py:174: def summary(..., rf: float = 0.0)
src/jointview/stats.py:185: numbers = metrics(frame, column, date_col=date_col, rf=rf)
src/jointview/stats.py:200: rf: float = 0.0,
src/jointview/stats.py:209: table = summary(frame, column, date_col=date_col, rf=rf)
Every hit is the parameter passing itself along. Neither cli.py nor app.py mentions it,
so every Sharpe, Sortino and Calmar the app displays is excess-of-zero — and the table
labels them "Sharpe ratio", not "Sharpe ratio (rf = 0%)". For a tool whose whole subject is
comparing NAV series, those three rows are the ones most sensitive to the assumption, and
it is the one assumption the page does not state.
Two honest ways out, and the issue is to pick one rather than leave it half-plumbed:
Plumb it. --rf on cli._parser, through _app_args into mo.cli_args(), and a
mo.ui.number beside the rebase switch so it can be moved without a restart. That gives
the parameter a caller and makes the ratios answerable. FUNDS in data.py already carries
a cash line at 1.0, which makes the demo frame a usable check that a non-zero rate moves
the numbers the right way.
Or delete it. Drop the four parameters, let jQuantStats default, and put one line under
the table saying the ratios are excess-of-zero. Smaller diff, and it stops advertising
configurability the app does not have.
Leaning toward plumbing it — the parameter is already correct at every layer but the two
that face a user, so the work is a flag and a widget rather than a redesign. Either way the
README's options table and the summary table's labels should end up saying which rate the
ratios are against.
stats.pythreads a risk-free rate through four functions —_stats,metrics,summary,summary_markdown— and intoData.from_prices(..., rf=rf). Nothing sets it:Every hit is the parameter passing itself along. Neither
cli.pynorapp.pymentions it,so every Sharpe, Sortino and Calmar the app displays is excess-of-zero — and the table
labels them "Sharpe ratio", not "Sharpe ratio (rf = 0%)". For a tool whose whole subject is
comparing NAV series, those three rows are the ones most sensitive to the assumption, and
it is the one assumption the page does not state.
Two honest ways out, and the issue is to pick one rather than leave it half-plumbed:
Plumb it.
--rfoncli._parser, through_app_argsintomo.cli_args(), and amo.ui.numberbeside the rebase switch so it can be moved without a restart. That givesthe parameter a caller and makes the ratios answerable.
FUNDSindata.pyalready carriesa
cashline at 1.0, which makes the demo frame a usable check that a non-zero rate movesthe numbers the right way.
Or delete it. Drop the four parameters, let jQuantStats default, and put one line under
the table saying the ratios are excess-of-zero. Smaller diff, and it stops advertising
configurability the app does not have.
Leaning toward plumbing it — the parameter is already correct at every layer but the two
that face a user, so the work is a flag and a widget rather than a redesign. Either way the
README's options table and the summary table's labels should end up saying which rate the
ratios are against.