assert_causal¶
Defined in fynance.core
- assert_causal(func, *, T=256, t0=None, n_probes=3, seed=0, atol=0.0)[source]
Assert func never uses future information (no lookahead bias).
Executable form of the repository’s “no lookahead” house rule: generates a seeded synthetic price level series
x, computes the baseliney0 = func(x), then at one or more probe indicest0perturbs x strictly fromt0onward – once with additive noise, once with a1.5xrescale – and requiresfuncof the perturbed input to agree withy0everywhere beforet0. NaN is treated as equal to NaN (so a warmup region that is legitimatelyNaNdoes not trip the check).- Parameters:
- funccallable
Maps a 1-D array of length T to a 1-D or 2-D array aligned with it on axis 0 (e.g. a rolling feature). Extra keyword arguments should be bound with a
lambdaorfunctools.partialbefore passing func in.- Tint, optional
Length of the synthetic input series. Default is 256.
- t0int, optional
Single probe index to test. If
None(default), n_probes probe points spread over[T // 4, 3 * T // 4]are used instead.- n_probesint, optional
Number of default probe points when t0 is
None. Default is 3 (T // 4,T // 2,3 * T // 4).- seedint, optional
Seed of the synthetic input and perturbation noise. Default is 0.
- atolfloat, optional
Absolute tolerance for the pre-
t0comparison. Default is 0.0 (exact, NaN-safe equality).
- Returns:
- None
Nothing on success.
- Raises:
- ValueError
If T is too small to host a probe, or t0 does not lie strictly inside
(0, T - 1).- AssertionError
If perturbing the input from some probe t0 onward changes the output before t0. The message names func, the probe t0, the perturbation used, and the earliest leaking index.
Examples
A trailing (causal) rolling mean passes:
>>> import numpy as np >>> from fynance.core.checks import assert_causal >>> def trailing_mean(x, w=5): ... out = np.empty_like(x) ... for t in range(len(x)): ... lo = max(0, t - w + 1) ... out[t] = x[lo:t + 1].mean() ... return out >>> assert_causal(trailing_mean, T=64, seed=0)
A centered rolling mean (
mode='same'convolution) leaks future values into the past and raises, naming the earliest leaking index:>>> def centered_mean(x, w=9): ... return np.convolve(x, np.ones(w) / w, mode='same') >>> try: ... assert_causal(centered_mean, T=64, seed=0) ... except AssertionError as e: ... print(str(e)[:40]) assert_causal: lookahead detected in cen