Skip to content

v1.16.0 — feat: two-phase backtest API, standardised fit() return contract

Choose a tag to compare

@rpycgo rpycgo released this 16 Apr 05:08
· 74 commits to main since this release

What's changed

New features

  • BaseModel.wrap_fit_result(params) — static helper that wraps a
    plain params dict into the standard {'summary': DataFrame, 'estimates': dict} structure required by WalkForwardRunner.
    Non-MCMC adapters should call this in fit().
  • BaseModel.fit() docstring updated to document the standardised
    return contract.

Bug fixes

  • Fix _fit_window() treating all non-MCMC adapter fits as failures —
    'summary' key was absent from plain dict returns, causing every
    window to be skipped for GARCH, DL, HMM, Simple Breakout, MA, RSI.
  • Fix GARCH z_score unit mismatch: (Close−Open)/(Open×GARCH_Vol)
    replaced with log_return×100 / GARCH_Vol — both now in the same
    log_return×100 scale.
  • Fix GARCH NaN/inf errors: dropna() added before ARCH model fit.
  • Fix HMM convergence failures: log_return × 100 scaling applied
    in both fit() and predict().
  • Fix garch_btc.toml gamma_avg corrected from 2.70 → 2.0 to match
    revised z_score scale.
  • Remove stale SNR fallback keys (alpha_long, alpha_short,
    sigma_1) from HMMRegimeAdapter.fit() and DlRegimeAdapter.fit()
    left over from removed build_dynamic_params().
  • Fix _fit_window() empty-summary check: non-MCMC adapters using
    wrap_fit_result() produce an intentionally empty summary DataFrame.
    Previously this caused all non-MCMC windows to be skipped. Now only
    fails when both summary and estimates are empty.

Internal changes

  • GarchCryptoAdapter now merges model-level [filters] config on
    top of shared backtest_settings.toml filters, allowing per-model
    filter overrides (e.g. use_sticky = false for GARCH).