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
d | Role |
|---|---|
0 | ARMA on y |
1 | ARIMA on non-stationary levels |
2 | Double 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, Q | Seasonal AR / MA |
D | Seasonal differences (1−Ls)D |
s | Period (12 = monthly, 4 = quarterly) |
Results (after fit)
| Attribute / method | Content |
|---|---|
params, coef, coefficients | Named coefficient Series |
bse, se, pvalues, tvalues | Inference Series |
coef_table | Coeff / SE / z / Prob. / CI |
cov_params() | k×k covariance matrix |
conf_int(alpha=0.05) | Coefficient CIs |
aic, bic, hqic, llf, loglik | ICs and log-likelihood |
nobs, df_model, df_resid | Sample sizes |
residuals, resid, fitted_values | Indexed series |
arparams, maparams | AR/SAR and MA/SMA subsets |
arroots, maroots | Polynomial roots; |r| > 1 desired |
sigma2 | Innovation 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
| Need | Function |
|---|---|
| Mean only, possibly integrated / seasonal | arma / arima / sarima |
| Conditional volatility / VaR | arma_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.