Rust-implemented time-series utilities exposed to Python via PyO3.
Project description
rust_timeseries — Python bindings for duration models and tests
rust_timeseries is a Python-first library that wraps high-performance Rust code for:
- modelling event-time durations with ACD-type models,
- calling a Rust-implemented maximum-likelihood optimizer,
- extracting fitted parameters and optimizer diagnostics, and
- running the Escanciano–Lobato (2009) portmanteau test, which is robust to conditional heteroskedasticity.
All heavy computation lives in Rust; the public surface is a small, typed Python API exposed via the compiled _rust_timeseries extension and the stub files:
duration_models.pyistatistical_tests.pyi
This README documents only what is actually exposed through those bindings.
1. Installation
1.1 From PyPI (recommended)
Version 1.0.0 is available on PyPI:
pip install rust_timeseries
The project currently ships wheels for Python 3.11–3.13 on common Linux, macOS, and Windows targets.
For unsupported platforms/versions, you can build from source (see below).
1.2 From source (development / contributing)
You’ll need a recent Rust stable toolchain and Python ≥ 3.11.
Clone the repo and create a virtual environment:
git clone https://github.com/mickwise/rust_timeseries.git
cd rust_timeseries
python -m venv .venv
source .venv/bin/activate # on Windows: .venv\Scripts\activate
pip install -U pip maturin
maturin develop --release
This builds the extension in place and installs it into your current environment. The Python usage is identical to the PyPI installation.
2. Python modules
The compiled extension _rust_timeseries.* is not imported directly; instead, use the public modules:
rust_timeseries/
duration_models.py # ACD models and related utilities
statistical_tests.py # Escanciano–Lobato test
_rust_timeseries.* # compiled extension (internal)
Use:
import rust_timeseries
from rust_timeseries import duration_models, statistical_tests
# or
from rust_timeseries.duration_models import ACD
from rust_timeseries.statistical_tests import EscancianoLobato
Do not import from internal Rust modules (duration, optimization, etc.). Always go through the public Python modules above.
3. Duration models (rust_timeseries.duration_models)
The duration_models module exposes ACD-type processes via the ACD class.
Note: Only the main surface API is documented here.
For full signatures, see the Python type stubs (duration_models.pyi) and the docstrings.
3.1 Minimal example
import numpy as np
from rust_timeseries.duration_models import ACD
# synthetic durations (strictly positive floats)
durations = 1.0 + np.abs(np.random.randn(200))
# unconstrained parameter guess (length 1 + p + q)
theta0 = np.zeros(3, dtype=np.float64) # (ω, α₁, β₁)
# configure ACD(1,1); see docstring for all options
model = ACD(data_length=len(durations), p=1, q=1)
# fit model in unconstrained parameter space
model.fit(durations=durations, theta0=theta0)
# short-horizon forecast of conditional duration
psi_hat = model.forecast(durations=durations, horizon=5)
print("ψ(5) =", psi_hat)
# classical vs. HAC-robust covariance matrices for θ
cov_classical = model.covariance_matrix(durations, robust=False)
cov_hac = model.covariance_matrix(durations, robust=True)
print("classical cov shape:", np.asarray(cov_classical).shape)
print("HAC cov shape :", np.asarray(cov_hac).shape)
Key methods (high level):
-
ACD(data_length: int, p: int, q: int, **options)
Construct an ACD(p, q) model for a given sample length. Extra options (e.g., stationarity margins, backcasting choices) are documented in the class docstring. -
fit(durations: np.ndarray, theta0: np.ndarray, ...) -> None
Estimate parameters in an unconstrained space (internally mapped to a stationary region). -
forecast(durations: np.ndarray, horizon: int, ...) -> float
Run an out-of-sample forecast and return the final ψ at the requested horizon. -
covariance_matrix(durations: np.ndarray, robust: bool = False, ...) -> list[list[float]]
Return model-based (robust=False) or HAC-robust (robust=True) covariance matrices for the unconstrained parameter vector. -
standard_errors(...) -> list[float]
Convenience wrapper that returns just the standard errors (diagonal of the chosen covariance matrix). -
results -> ACDOptimOutcome
Optimizer diagnostics (status, iterations, gradient norm, evaluation counts, etc.). -
fitted_params -> ACDFittedParams
Fitted model-space parameters (ω, slack, α, β, ψ-lags) that satisfy the stationarity and positivity constraints enforced in Rust.
3.2 Constructors and variants
The main constructor:
ACD(
data_length: int,
p: int,
q: int,
*,
init=None,
init_fixed=None,
init_psi_lags=None,
init_durations_lags=None,
tol_grad=None,
tol_cost=None,
max_iter=None,
line_searcher=None,
lbfgs_mem=None,
psi_guards=None,
)
An exponential innovation distribution is used by default. Two alternative constructors are available:
ACD.wacd(...)– Weibull-innovation ACD(p, q) with shape parameterk.ACD.gacd(...)– generalized-gamma-innovation ACD(p, q) with shape parametersp_shapeandd_shape.
Both accept the same core configuration arguments as ACD (data_length, p, q, optimizer settings), plus their respective shape parameters.
3.3 Standard errors (ACD.covariance_matrix)
covariance_matrix computes parameter covariance matrix for a given duration series, optionally with HAC corrections:
se = model.covariance_matrix(
durations=durations,
unit="seconds",
t0=None,
diurnal_adjusted=False,
robust=True,
kernel="bartlett",
bandwidth=None,
center=False,
small_sample_correction=True,
)
- When
robust=False, covariance matrix is based on the model-based information matrix. - When
robust=True, a HAC estimator is used (kernel and bandwidth options are forwarded to the Rust implementation).
3.4 Optimization diagnostics (ACDOptimOutcome)
The results property returns an ACDOptimOutcome object, wrapping the Rust OptimOutcome type.
Attributes:
theta_hat: list[float]– unconstrained parameter vector at the solution.value: float– objective value at the solution.converged: bool– whether the optimizer terminated successfully.status: str– human-readable termination reason.iterations: int– number of iterations taken.grad_norm: float | None– norm of the gradient at the solution, when available.fn_evals: list[tuple[str, int]]– evaluation counters keyed by function name.
Typical usage:
outcome = model.results
print("Converged:", outcome.converged, "-", outcome.status)
print("Objective value:", outcome.value)
print("Iterations:", outcome.iterations)
print("Gradient norm:", outcome.grad_norm)
print("Function evals:", outcome.fn_evals)
3.5 Fitted parameters (ACDFittedParams)
The fitted_params property returns an ACDFittedParams instance that mirrors the Rust ACDParams struct:
omega: float– baseline level parameter.slack: float– positive slack term used to enforce strict stationarity.alpha: list[float]– ARCH-type coefficients (sizep).beta: list[float]– GARCH-type coefficients (sizeq).psi_lags: list[float]– initialization lags for ψₜ.
Example:
params = model.fitted_params
print("omega:", params.omega)
print("slack:", params.slack)
print("alpha:", params.alpha)
print("beta:", params.beta)
print("psi_lags:", params.psi_lags)
All invariants (positivity, stationarity, shape constraints) are enforced on the Rust side; Python sees only valid parameter configurations.
4. Escanciano–Lobato test (rust_timeseries.statistical_tests)
The statistical_tests module currently exposes a single class, EscancianoLobato, implementing the Escanciano–Lobato heteroskedasticity proxy test.
4.1 Constructing EscancianoLobato
import numpy as np
from rust_timeseries.statistical_tests import EscancianoLobato
residuals = np.asarray(residuals, dtype=float)
el = EscancianoLobato(
residuals, # 1-D array-like of float64, no NaNs, length >= 1
q=2.4, # positive float proxy order (optional)
d=None, # positive integer max lag; default floor(n**0.2)
)
Signature (from statistical_tests.pyi):
class EscancianoLobato:
def __init__(
self,
data,
q: float | None = 2.4,
d: int | None = None,
) -> None: ...
Validation rules enforced in the bindings:
datamust be non-empty and contain no NaNs;qmust be positive when provided;dmust be positive when provided.
Invalid inputs raise a ValueError from the PyO3 binding.
4.2 Accessing test results
EscancianoLobato wraps a Rust ELOutcome and exposes three read-only properties:
statistic: float– the test statistic;pvalue: float– asymptotic p-value under the null;p_tilde: int– data-driven lag choice that maximizes the penalized statistic.
Example:
print("EL statistic:", el.statistic)
print("EL p-value :", el.pvalue)
print("Selected lag p~:", el.p_tilde)
5. Design notes
- Python-first. The core lives in Rust, but the bindings are designed so that quantitative researchers can stay in Python. Inputs are standard array-like objects (
numpy.ndarray,pandas.Series, lists); outputs are plain Python scalars and lists. - Tight coupling to Rust invariants. The PyO3 layer performs shape checks, basic validation, and error mapping. All model invariants (positivity, stationarity, etc.) are enforced in the Rust types (
ACDModel,ACDParams,ELOutcome). - Explicit error reporting. Rust errors (through the
ACDErrortype) are surfaced as Python exceptions with clear messages. Fitted-state-dependent getters (results,fitted_params) fail loudly if you call them beforefit. - Minimal, inspectable objects. The Python wrappers (
ACD,ACDOptimOutcome,ACDFittedParams,EscancianoLobato) are intentionally small and read-only. They are easy to log, serialize, or convert to dictionaries for downstream analysis.
6. Status and extension points
The current Python API is intentionally narrow and corresponds exactly to the bindings implemented in lib.rs and documented in duration_models.pyi and statistical_tests.pyi.
Natural extensions (planned to be added in Rust and then surfaced via the same binding pattern) include:
- simulation module for the ACD family.
- further goodness-of-fit and residual tests under
statistical_tests, - exposing of covariance estimation through python as a standalone module.
When extending the library, keep the following steps:
- Add functionality in the Rust core.
- Expose it through a PyO3 wrapper (
#[pyclass]/#[pymethods]). - Update the
.pyistubs to match. - Update this README to document the new public surface.
This keeps the README, stubs, and compiled extension in sync.
7. License
rust_timeseries is released under the MIT license. See LICENSE for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file rust_timeseries-1.1.0.tar.gz.
File metadata
- Download URL: rust_timeseries-1.1.0.tar.gz
- Upload date:
- Size: 1.2 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
25dfd40c117c77d753354918bc67ba822671cb2bb58bf8d32bd44fd190d5ed67
|
|
| MD5 |
62e3f77e440b3ec6b0327883996bf092
|
|
| BLAKE2b-256 |
7f8aa3eea5219d8d13a8e8001d510b3fb1ba2abcc1f8812953a8f59ada1d85a3
|
File details
Details for the file rust_timeseries-1.1.0-cp313-cp313-win_amd64.whl.
File metadata
- Download URL: rust_timeseries-1.1.0-cp313-cp313-win_amd64.whl
- Upload date:
- Size: 438.7 kB
- Tags: CPython 3.13, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8c60849f87c8bd19d47729c0b73509edbb071724088ab7f1260fb592a99bb9ad
|
|
| MD5 |
61b8524c63e63e87eb7f557107ca8d8c
|
|
| BLAKE2b-256 |
a7696e657b0fb0812add91dd00fdd7ecf7df0b4eba43f2977c1f2aabd58de9f0
|
File details
Details for the file rust_timeseries-1.1.0-cp313-cp313-manylinux_2_34_x86_64.whl.
File metadata
- Download URL: rust_timeseries-1.1.0-cp313-cp313-manylinux_2_34_x86_64.whl
- Upload date:
- Size: 612.6 kB
- Tags: CPython 3.13, manylinux: glibc 2.34+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
02fe42719b674181a60198d1fa105c405d4ea7976d78b79ca9b5c205c77e6409
|
|
| MD5 |
7573af68b0d1cf7008148f90e706ca2a
|
|
| BLAKE2b-256 |
054610f38f868900228bd36b5cc43737e198d5fbc8546e5331e13575e1d8a05a
|
File details
Details for the file rust_timeseries-1.1.0-cp313-cp313-macosx_11_0_arm64.whl.
File metadata
- Download URL: rust_timeseries-1.1.0-cp313-cp313-macosx_11_0_arm64.whl
- Upload date:
- Size: 529.8 kB
- Tags: CPython 3.13, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
42f9b0e085a9b26841e7d0fa000fd4501d0389c21d28d1a82426d762d8b0f1af
|
|
| MD5 |
87fc5ce43663d673fe4f5f1252631e0d
|
|
| BLAKE2b-256 |
1425f213bf317b3e9530aaf324dfd36a55cf8153cc83b8b1dfea5c6dc7c9e550
|
File details
Details for the file rust_timeseries-1.1.0-cp312-cp312-win_amd64.whl.
File metadata
- Download URL: rust_timeseries-1.1.0-cp312-cp312-win_amd64.whl
- Upload date:
- Size: 439.0 kB
- Tags: CPython 3.12, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
91768b55805713949068c21abab08d3220d83d3eaed24d9b27953b395b48949e
|
|
| MD5 |
1ec90cda1d382dfbf589f3d4fa9c3bbf
|
|
| BLAKE2b-256 |
c64bfdcdc56f46387a96cb68ed87cc5d2b6d062995986b7ca06db2a989149314
|
File details
Details for the file rust_timeseries-1.1.0-cp312-cp312-manylinux_2_34_x86_64.whl.
File metadata
- Download URL: rust_timeseries-1.1.0-cp312-cp312-manylinux_2_34_x86_64.whl
- Upload date:
- Size: 612.9 kB
- Tags: CPython 3.12, manylinux: glibc 2.34+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e20b18b7cd5f2ee5ae1f6603ad7a81f6c1a4c999ccf65531b3babdc2140a27da
|
|
| MD5 |
bd2a008b3e3214d2b44bcaac8be69e73
|
|
| BLAKE2b-256 |
36ce7f7a67e3dc8465589abdf9fc108cc2b684e759d50086643e939d2e2c42a1
|
File details
Details for the file rust_timeseries-1.1.0-cp312-cp312-macosx_11_0_arm64.whl.
File metadata
- Download URL: rust_timeseries-1.1.0-cp312-cp312-macosx_11_0_arm64.whl
- Upload date:
- Size: 530.0 kB
- Tags: CPython 3.12, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7e026b126e46050fe2a54b0dbb1b4f46c8f77bf4723341c1d0322b3d187dfdaa
|
|
| MD5 |
ef999872b48ff10618a3785f8b4f32c4
|
|
| BLAKE2b-256 |
97a8673174733ba7502f26393e946de24ca1205af4e4cb0a51bc532d81e06a47
|
File details
Details for the file rust_timeseries-1.1.0-cp311-cp311-win_amd64.whl.
File metadata
- Download URL: rust_timeseries-1.1.0-cp311-cp311-win_amd64.whl
- Upload date:
- Size: 438.4 kB
- Tags: CPython 3.11, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3fe45c2c2dcb945b59817c65e5583afd2f8f0e2e3f15f3415f86818701193d31
|
|
| MD5 |
e18b61d94d9fda26ef82c7b175ec340f
|
|
| BLAKE2b-256 |
390b2a1045482dd166e684f0013ea1bfac3740626813525e65a31602b2ec72bc
|
File details
Details for the file rust_timeseries-1.1.0-cp311-cp311-manylinux_2_34_x86_64.whl.
File metadata
- Download URL: rust_timeseries-1.1.0-cp311-cp311-manylinux_2_34_x86_64.whl
- Upload date:
- Size: 612.5 kB
- Tags: CPython 3.11, manylinux: glibc 2.34+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
acc046ee5b8c2dcad32220278fe2a302c62310383184aea15993c64fdb6d95e5
|
|
| MD5 |
baec035ad9d249ee0bcd42d3d22845d7
|
|
| BLAKE2b-256 |
660cf0b10e38ef5b50287daaf12c0db211a237b2b6a44911842889d713c05b65
|
File details
Details for the file rust_timeseries-1.1.0-cp311-cp311-macosx_11_0_arm64.whl.
File metadata
- Download URL: rust_timeseries-1.1.0-cp311-cp311-macosx_11_0_arm64.whl
- Upload date:
- Size: 535.7 kB
- Tags: CPython 3.11, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e2a5062b621a525dc6164c0e5d606f0cf8a37d1207613f49cc7f34048f86f4dd
|
|
| MD5 |
2a281bbb01ea38b932882c668321406c
|
|
| BLAKE2b-256 |
0d1a09dd6664254f10d61a7826e7b94b865cc1365421914702773bee705e3879
|