polars_online.sim¶
A seeded simulator for correlation regimes (docs/ENHANCEMENTS.md E64).
The detectors in this library — deco, hmm, corrchange, bocpd — are claims about streams whose correlation structure changes. A claim like that can only be measured against data whose truth is known, and the truth has to include the awkward parts: series that report at their own times, levels observed with additive noise, autocorrelated increments, a scale that moves with the regime, a periodic pattern, and an activity clock.
regimes() produces all of it from one seed, and hands back the truth
beside the data:
rowswhat a consumer sees: levels
x_1 .. x_m(sopolars_online.prep.refresh_time()and then.diff()apply), a clock, a cycle index and an optional activity count.truth_rowsper row: the block, the state, the scale multiplier and the interpolation fraction.
truth_blocksper block: the state, the row count, and the block’s true correlation matrix as
vech.
Everything is drawn from numpy.random.default_rng(seed) in one order, so
two calls with the same seed give byte-identical frames. numpy only; no
scipy.
- polars_online.sim.regimes(m: int, *, states: Sequence[Any], transition: Any, n_blocks: int, rows_per_block: int, durations: Sequence[int] | None = None, design: str = 'step', smooth_rows: int = 0, phi: float | Sequence[float] = 0.0, scale_state: float | Sequence[float] = 0.0, async_rates: Sequence[float] | None = None, noise: float = 0.0, cycle_profile: Sequence[float] | None = None, cycle_rows: int | None = None, activity: tuple[float, float] | None = None, seed: int = 0) dict[str, DataFrame][source]¶
A simulated stream of
mseries whose correlation changes by regime.statesis a list ofKcorrelation matrices (m x m, unit diagonal, PSD) orKfloats, each an equicorrelation.transitionis theK x Krow-stochastic matrix that drives one state per block, and there aren_blocksblocks ofrows_per_blockrows.durations(one positive block count per state) makes the sojourn deterministic instead and draws the next state fromtransitionwith its diagonal removed — the recurring-state design, where each state lasts exactly as long as it says.design="step"switches at the block boundary.design="smooth"interpolates the correlation matrix linearly oversmooth_rowsrows around it; a convex combination of two correlation matrices is one, so every matrix along the way is valid.The latent returns are
eps_t ~ N(0, R_t), filtered toy_it = phi_i y_i,t-1 + eps_itand scaled byexp(scale_state * s_t). The documented truth is the innovation correlation: an AR filter moves the return correlation of a pair with unequalphi, which is exactly whatpolars_online.corr.fisher_se()’s inflation is about.scale_stateas a scalar makes the noise scale rise with the state index; as a list it gives one multiplier exponent per state.cycle_profileiscycle_rowsmultipliers in(0, 1]applied to the off-diagonal ofR_tat rowt mod cycle_rows— a mix towards the identity, so the matrix stays PSD.cycle_rowsdefaults torows_per_block, andsession = t // cycle_rows.activityis(mean, shape)for a Gamma count per row, with the mean scaled by the same scale multiplier;clockis then the cumulative activity, and the row index otherwise.x_1 .. x_mare levels: the cumulative sum of the latent returns plusnoise * N(0, 1)per observed row. Noise on the level is what the literature models, and it makes the observed return an MA(1) with a negative first autocorrelation — the microstructure effect rcov exists to undo. Withasync_rates(expected observations per row, per series) a row where seriesireported nothing carriesnullforx_i: last-observation sampling is oneforward_fillaway, andunpivotover the non-null rows ispolars_online.prep.refresh_time()’s long input.Returns
{"rows", "truth_rows", "truth_blocks"}. Two calls with the sameseedgive byte-identical frames.