BATS and TBATS time series forecasting
Package provides BATS and TBATS time series forecasting methods described in:
De Livera, A.M., Hyndman, R.J., & Snyder, R. D. (2011), Forecasting time series with complex seasonal patterns using exponential smoothing, Journal of the American Statistical Association, 106(496), 1513-1527.
Installation
From pypi:
python -m pip install tbats
Import via:
from tbats import BATS, TBATS
Minimal working example:
from tbats import TBATS
import numpy as np
# required on windows for multi-processing,
# see https://docs.python.org/2/library/multiprocessing.html#windows
if __name__ == '__main__':
np.random.seed(2342)
t = np.array(range(0, 160))
y = 5 * np.sin(t * 2 * np.pi / 7) + 2 * np.cos(t * 2 * np.pi / 30.5) + \
((t / 20) ** 1.5 + np.random.normal(size=160) * t / 50) + 10
# Create estimator
estimator = TBATS(seasonal_periods=[14, 30.5])
# Fit model
fitted_model = estimator.fit(y)
# Forecast 14 steps ahead
y_forecasted = fitted_model.forecast(steps=14)
# Summarize fitted model
print(fitted_model.summary())
Reading model details
# Time series analysis
print(fitted_model.y_hat) # in sample prediction
print(fitted_model.resid) # in sample residuals
print(fitted_model.aic)
# Reading model parameters
print(fitted_model.params.alpha)
print(fitted_model.params.beta)
print(fitted_model.params.x0)
print(fitted_model.params.components.use_box_cox)
print(fitted_model.params.components.seasonal_harmonics)
See examples directory for more details.
Troubleshooting
BATS and TBATS tries multitude of models under the hood and may appear slow when fitting to long time series. In order to speed it up you can start with constrained model search space. It is recommended to run it without Box-Cox transformation and ARMA errors modelling that are the slowest model elements:
# Create estimator
estimator = TBATS(
seasonal_periods=[14, 30.5],
use_arma_errors=False, # shall try only models without ARMA
use_box_cox=False # will not use Box-Cox
)
fitted_model = estimator.fit(y)
In some environment configurations parallel computation of models freezes. Reason for this is unclear yet. If the process appears to be stuck you can try running it on a single core:
estimator = TBATS(
seasonal_periods=[14, 30.5],
n_jobs=1
)
fitted_model = estimator.fit(y)
For Contributors
Setup and locked development environment
Install uv 0.12.3, then create the locked development environment:
uv sync --locked
The committed uv.lock is a universal development and CI lock for Python 3.10–3.13. It is not a consumer installation requirement; consumers install the package with pip or another standards-compliant installer. Update it deliberately after dependency changes:
uv lock
Testing
Run the non-R unit and integration suite:
uv run --locked python -m pytest test/
Run the bounded explicit-spawn smoke check for BATS and TBATS:
uv run --locked python scripts/spawn_smoke.py
R forecast package comparison tests are separate from normal development, CI, and release validation. They require R, the R forecast package, and the optional Python R extra:
uv sync --locked --extra r
uv run --locked --extra r python -m pytest test_R/
If R packages live in a custom user library, set R_LIBS_USER for that command (for example, R_LIBS_USER=/path/to/R/library uv run --locked --extra r python -m pytest test_R/).
Release checks
Run the reviewed snapshot validation and build checks before a release:
./prepare_package.sh
uv build --no-sources
uvx --from twine==7.0.0 twine check dist/*
prepare_package.sh runs the locked non-R suite, explicit-spawn smoke check, build, and metadata check. publish_package.sh is a local preflight only; it never uploads or creates tags.
To release a new version, bump tbats.__version__, commit it on master, ensure all CI jobs are green, and create and push the protected signed v<version> tag. Then publish a GitHub Release for that existing tag, for example:
gh release create v1.2.0 --verify-tag --generate-notes --title "tbats 1.2.0"
Publishing the GitHub Release makes it visible on the Releases page and triggers PyPI OIDC. The release workflow checks that the release tag starts with v, checks out that exact tag, and verifies its commit is on master. It then rebuilds a fresh dist/ and fails closed unless it contains exactly one matching wheel and sdist. It validates both embedded metadata files and records SHA-256 hashes before installing and smoking the exact wheel externally. The later upload is bound to those two validated paths; the publish job downloads that exact artifact, validates it again, recomputes and compares both hashes, and only then publishes through PyPI Trusted Publishing. Existing version 1.1.3 cannot be republished.
One-time release administration: configure the PyPI Trusted Publisher with owner intive-DataScience, repository tbats, workflow publish.yml, and environment pypi. Protect the GitHub pypi environment and v* tags. No PyPI token secret is used.
Comparison to R implementation
Python implementation is meant to be as much as possible equivalent to R implementation in forecast package.
Metadata
Release files for tbats 1.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| tbats-1.2.0.tar.gz | 34.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| tbats-1.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 79.7 kB
Release files / tbats-1.2.0.tar.gz
| Download URL | tbats-1.2.0.tar.gz |
|---|---|
| Size | 34.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
fc6002009fc74636109fd2bec308693ead566a84eb6631b67a9edf24b34ab5b0
|
|
BLAKE2b-256 checksum How to use checksums |
7f28d51e9813cb06aba55a212c4feae8ec370cc1178fbd379080f5798830ec7f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 16, 2026.
Transparency logRelease files / tbats-1.2.0-py3-none-any.whl
| Download URL | tbats-1.2.0-py3-none-any.whl |
|---|---|
| Size | 45.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b877fbffd46fb27c7bc6903dfdd42de6d80087f3bcd73381606c6c5af6c554d4
|
|
BLAKE2b-256 checksum How to use checksums |
fd2d1a195becb944ac8b9a38067a177dbfffd121a8b983df41e350cb2cbfadb6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 16, 2026.
Transparency log