makystats GitHub PyPI FR · EN

ARMA / ARIMA / SARIMA

MLE for ARMA, ARIMA or SARIMA without GARCH: a single variance parameter σ².

The time index of y (DatetimeIndex, PeriodIndex, …) is preserved on residuals, fitted values and forecasts. If d or D > 0, leading NaNs appear (alignment on the full sample).

Source README: makystats/arma/README.md

Import

from makystats import arma, arima, sarima, select_arma_order
# or: from makystats.arma import ARMA, arma, ...

ARMA (stationary, d=0)

res = arma(y, mean="ARMA", ar=1, ma=1, trend="c").fit()
print(res.coef_table)
print(res.params["AR(1)"])       # named Series
print(res.bse, res.pvalues)
print(res.cov_params())
print(res.forecast(steps=5, conf_int=True))

ARIMA (levels, often I(1))

The user does not need to difference by hand:

res = arma(prices, mean="ARMA", ar=1, ma=1, d=1, trend="c").fit()
res = arima(prices, order=(1, 1, 1), trend="c").fit()

res.forecast(steps=10)                # levels (default if d>0)
res.forecast(steps=10, levels=False)  # on Δy
res.fitted_values_level()             # fitted in levels
dRole
0ARMA on y
1ARIMA on non-stationary levels
2Double differencing (rare)

On Δy, trend='c' is a drift in levels (constant on differences).

SARIMA

# Multiplicative form via SARIMAX (dense orders)
res = arma(ylog, mean="ARMA", ar=0, ma=1, d=1,
           seasonal_order=(0, 1, 1, 12), trend="n").fit()

res = sarima(ylog, order=(0, 1, 1), seasonal_order=(0, 1, 1, 12), trend="n").fit()

# Sparse (“gapped”) lags + season → native engine (additive seasonal lags)
res = arma(ylog, mean="ARMA", ar=[4], ma=1, d=1,
           seasonal_order=(1, 1, 1, 12), trend="c").fit()
seasonal_order(P, D, Q, s)
P, QSeasonal AR / MA
DSeasonal differences (1−Ls)D
sPeriod (12 = monthly, 4 = quarterly)

Results (after fit)

Attribute / methodContent
params, coef, coefficientsNamed coefficient Series
bse, se, pvalues, tvaluesInference Series
coef_tableCoeff / SE / z / Prob. / CI
cov_params()k×k covariance matrix
conf_int(alpha=0.05)Coefficient CIs
aic, bic, hqic, llf, loglikICs and log-likelihood
nobs, df_model, df_residSample sizes
residuals, resid, fitted_valuesIndexed series
arparams, maparamsAR/SAR and MA/SMA subsets
arroots, marootsPolynomial roots; |r| > 1 desired
sigma2Innovation variance

Diagnostics

res.test_serial_correlation(lags=10)   # Ljung-Box
res.test_heteroskedasticity(lags=5)    # ARCH-LM
res.test_normality()                   # Jarque-Bera
res.plot_diagnostics()

Order selection

tab = select_arma_order(y, p_range=range(0, 4), q_range=range(0, 3), criterion="bic")
tab = select_arma_order(prices, d=1, p_range=range(0, 3), q_range=range(0, 2))
tab = select_arma_order(
    ylog, d=1, seasonal_order=(0, 1, 1, 12),
    p_range=range(0, 3), q_range=range(0, 2), criterion="aic",
)
tab, best = select_arma_order(..., return_best=True)

d and seasonal_order are fixed for the whole grid; only p and q vary.

arma vs arma_garch

NeedFunction
Mean only, possibly integrated / seasonalarma / arima / sarima
Conditional volatility / VaRarma_garch
Forecast CIs in levels for d>0 are indicative (not exact state-space variance). Coefficients are on the working scale (after d/D); forecast and fitted_values_level rebuild levels. Dense SARIMA → multiplicative SARIMAX; sparse ARMA + season → additive seasonal lags.