Method specifications (tsbootstrap.methods)

Typed method specifications: the single public configuration surface.

Each bootstrap method is a frozen, validated specification object. The entry point is bootstrap(X, *, method=MovingBlock(block_length="auto"), ...): the configuration (these dataclasses) is separated from the execution (pure engine functions), which gives static typing, IDE autocomplete, and JSON-serialisable provenance via spec.model_dump().

extra="forbid" means an unknown or misspelled parameter fails immediately with a structured error instead of being silently ignored. frozen=True makes specs immutable and hashable.

Composition:

  • Observation-resampling specs (IID, the *Block family) double as the innovation resampler for residual/sieve bootstraps.

  • Wild and BlockWild are innovation-only specs (multiplier resamplers); they are valid as innovation but not as a top-level method.

  • ResidualBootstrap pairs a model (AR/ARIMA/ VAR) with an innovation resampler.

class tsbootstrap.methods.BaseMethodSpec[source]

Bases: BaseModel

Open base for every method spec: immutable, hashable, strict about parameters.

Third-party methods subclass this (directly, or via the model bases below), declare a unique kind Literal, and register an executor with tsbootstrap.register_chunk_executor(); bootstrap then dispatches to them exactly like a built-in. The base is intentionally open so out-of-tree methods can participate without editing this module (runtime safety comes from the executor registry, which raises for an unregistered spec).

model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'frozen': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class tsbootstrap.methods.IID(*, kind: Literal['iid'] = 'iid')[source]

Bases: BaseMethodSpec

Plain i.i.d. resampling. A baseline; not valid under serial dependence.

model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'frozen': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class tsbootstrap.methods.MovingBlock(*, kind: Literal['moving_block'] = 'moving_block', block_length: int | Literal['auto'] = 'auto')[source]

Bases: BaseMethodSpec

Moving block bootstrap (Kunsch 1989): overlapping fixed-length blocks.

model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'frozen': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class tsbootstrap.methods.CircularBlock(*, kind: Literal['circular_block'] = 'circular_block', block_length: int | Literal['auto'] = 'auto')[source]

Bases: BaseMethodSpec

Circular block bootstrap (Politis-Romano 1992): wrap-around blocks.

model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'frozen': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class tsbootstrap.methods.StationaryBlock(*, kind: Literal['stationary_block'] = 'stationary_block', avg_block_length: int | Literal['auto'] = 'auto')[source]

Bases: BaseMethodSpec

Stationary bootstrap (Politis-Romano 1994): geometric block lengths.

model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'frozen': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class tsbootstrap.methods.NonOverlappingBlock(*, kind: Literal['non_overlapping_block'] = 'non_overlapping_block', block_length: int | Literal['auto'] = 'auto')[source]

Bases: BaseMethodSpec

Non-overlapping block bootstrap (Carlstein 1986).

model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'frozen': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class tsbootstrap.methods.TaperedBlock(*, kind: Literal['tapered_block'] = 'tapered_block', window: Literal['bartlett', 'blackman', 'hamming', 'hann', 'tukey'] = 'bartlett', block_length: int | Literal['auto'] = 'auto', alpha: Annotated[float, Gt(gt=0.0), Le(le=1.0)] = 0.5)[source]

Bases: BaseMethodSpec

Tapered block bootstrap (Paparoditis-Politis 2001): window-weighted blocks.

model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'frozen': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class tsbootstrap.methods.Wild(*, kind: Literal['wild'] = 'wild', distribution: Literal['rademacher', 'gaussian', 'mammen'] = 'rademacher')[source]

Bases: BaseMethodSpec

Wild bootstrap innovations (Wu 1986; Liu 1988): e*_t = v_t * e_hat_t.

Each centered residual keeps its time position and magnitude; an i.i.d. external multiplier v_t (mean 0, variance 1) randomizes its sign/scale. Valid under conditional heteroskedasticity of unknown form, where index resampling would average the variance profile away. The default Rademacher multiplier follows Davidson and Flachaire (2008); "mammen" is the two-point distribution of Mammen (1993) matching the third moment; "gaussian" is the standard normal multiplier.

Requires burn_in=0 and initial="fixed" on the host model spec: the multiplier stream is aligned one-to-one with the residuals, conditional on the observed initial values.

model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'frozen': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class tsbootstrap.methods.BlockWild(*, kind: Literal['block_wild'] = 'block_wild', distribution: Literal['rademacher', 'gaussian', 'mammen'] = 'rademacher', block_length: int | Literal['auto'] = 'auto')[source]

Bases: BaseMethodSpec

Block-wild bootstrap innovations: multipliers constant on time blocks.

One multiplier is drawn per contiguous non-overlapping block of the residual sequence and repeated across that block, so within-block residual dependence survives the resampling (a piecewise-constant special case of the dependent wild bootstrap of Shao 2010; the block-constant construction mirrors the wild cluster bootstrap of Cameron, Gelbach, and Miller 2008 with time blocks as clusters). block_length=1 degenerates to Wild. "auto" resolves the block length from the centered residuals via the Politis-White rule at fit time.

Same host-model constraints as Wild (burn_in=0, initial="fixed").

model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'frozen': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class tsbootstrap.methods.AR(*, stability_policy: Literal['raise', 'skip'] = 'raise', burn_in: Annotated[int, Ge(ge=0)] = 0, initial: Literal['fixed', 'random_block'] = 'fixed', kind: Literal['ar'] = 'ar', order: Annotated[int, Ge(ge=1)])[source]

Bases: _RecursiveInitSpec

Autoregressive model of fixed order.

model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'frozen': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class tsbootstrap.methods.ARIMA(*, stability_policy: Literal['raise', 'skip'] = 'raise', kind: Literal['arima'] = 'arima', order: tuple[int, int, int])[source]

Bases: _ModelSpec

Integrated ARMA model. SARIMA (seasonal) is not yet supported.

Unlike AR/VAR/SieveAR, ARIMA exposes no burn_in or initial: it conditions on the observed initial differenced state, and integration would turn any burn-in transient into a permanent level shift, so neither field is meaningful here (see _RecursiveInitSpec).

model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'frozen': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class tsbootstrap.methods.VAR(*, stability_policy: Literal['raise', 'skip'] = 'raise', burn_in: Annotated[int, Ge(ge=0)] = 0, initial: Literal['fixed', 'random_block'] = 'fixed', kind: Literal['var'] = 'var', order: Annotated[int, Ge(ge=1)])[source]

Bases: _RecursiveInitSpec

Vector autoregression (multivariate).

model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'frozen': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class tsbootstrap.methods.ResidualBootstrap(*, kind: ~typing.Literal['residual'] = 'residual', model: ~tsbootstrap.methods.AR | ~tsbootstrap.methods.ARIMA | ~tsbootstrap.methods.VAR, innovation: ~tsbootstrap.methods.IID | ~tsbootstrap.methods.MovingBlock | ~tsbootstrap.methods.CircularBlock | ~tsbootstrap.methods.StationaryBlock | ~tsbootstrap.methods.NonOverlappingBlock | ~tsbootstrap.methods.Wild | ~tsbootstrap.methods.BlockWild = <factory>)[source]

Bases: BaseMethodSpec

Recursive residual bootstrap with resampled, centered innovations.

model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'frozen': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class tsbootstrap.methods.SieveAR(*, stability_policy: ~typing.Literal['raise', 'skip'] = 'raise', burn_in: ~typing.Annotated[int, ~annotated_types.Ge(ge=0)] = 0, initial: ~typing.Literal['fixed', 'random_block'] = 'fixed', kind: ~typing.Literal['sieve_ar'] = 'sieve_ar', min_lag: ~typing.Annotated[int, ~annotated_types.Ge(ge=1)] = 1, max_lag: ~types.Annotated[int | None, ~annotated_types.Ge(ge=1)] = None, criterion: ~typing.Literal['aic', 'bic', 'hqic'] = 'bic', innovation: ~tsbootstrap.methods.IID | ~tsbootstrap.methods.MovingBlock | ~tsbootstrap.methods.CircularBlock | ~tsbootstrap.methods.StationaryBlock | ~tsbootstrap.methods.NonOverlappingBlock | ~tsbootstrap.methods.Wild | ~tsbootstrap.methods.BlockWild = <factory>)[source]

Bases: _RecursiveInitSpec

Sieve bootstrap: select the AR order once, then recursive AR residual bootstrap.

model_config: ClassVar[ConfigDict] = {'extra': 'forbid', 'frozen': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

tsbootstrap.methods.OBSERVATION_RESAMPLING = (<class 'tsbootstrap.methods.IID'>, <class 'tsbootstrap.methods.MovingBlock'>, <class 'tsbootstrap.methods.CircularBlock'>, <class 'tsbootstrap.methods.StationaryBlock'>, <class 'tsbootstrap.methods.NonOverlappingBlock'>, <class 'tsbootstrap.methods.TaperedBlock'>)

Specs that resample observation indices (so OOB/in-bag masks are defined).