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.

  • 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_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.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 = <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 = <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).