What Is an ARIMA Model?
An ARIMA model (AutoRegressive Integrated Moving Average) is a class of statistical models for forecasting time series data. It combines three components - autoregression, differencing, and moving average smoothing - into a single framework that can capture a wide range of temporal patterns. If a time series has trends, momentum, or short-term dependencies, an ARIMA model can describe that structure mathematically and project it forward.
The core idea is straightforward. Many time series aren't stationary - their mean or variance changes over time. Stock prices drift upward, GDP grows, inflation rises and falls in cycles. You can't model a non-stationary series directly with simple autoregressive or moving average models because those assume a stable mean. ARIMA solves this by differencing the series first (the "Integrated" part) to make it stationary, then fitting an ARMA model to the differenced data.
ARIMA models were formalised by George Box and Gwilym Jenkins in their 1970 book Time Series Analysis: Forecasting and Control, which laid out a systematic methodology for identifying, estimating, and checking these models. The Box-Jenkins approach remains the standard workflow for ARIMA modelling in 2026, even as machine learning methods have expanded the forecasting toolkit. For linear time series with well-behaved autocorrelation structures, ARIMA is still hard to beat.
In quantitative finance, ARIMA models appear in macroeconomic forecasting, yield curve modelling, spread analysis, and as benchmarks against which more complex models are measured. They're also a natural stepping stone to models like GARCH, which extends the framework to capture time-varying volatility.
The Three Components of ARIMA
ARIMA is built from three distinct pieces, each handling a different aspect of the time series. Understanding them individually makes the full model intuitive.
AR(p) - The Autoregressive Component
The autoregressive component models the relationship between an observation and its own past values. An AR(p) model says that today's value is a linear function of the previous p values plus a random shock:
[ X_t = c + \phi_1 X_{t-1} + \phi_2 X_{t-2} + \cdots + \phi_p X_{t-p} + \epsilon_t ]
where ( \phi_1, \ldots, \phi_p ) are the autoregressive coefficients, c is a constant, and ( \epsilon_t ) is white noise. The order p determines how many lags the model looks back. An AR(1) model uses only yesterday's value; an AR(2) uses the two most recent values.
Think of it like momentum. If ( \phi_1 = 0.8 ), a series above its mean today will likely be above its mean tomorrow too, because 80% of today's deviation carries over. The further back the significant lags extend, the higher the order p you need.
I(d) - The Integrated Component
The "I" in ARIMA stands for "integrated," which refers to differencing. A time series that needs to be differenced d times to become stationary is said to be integrated of order d, written I(d). Most financial and economic time series require either zero or one round of differencing.
First differencing transforms a series ( X_t ) into ( \Delta X_t = X_t - X_{t-1} ). For stock prices, first differencing gives you the change in price (or log returns if you difference the log prices). If first differencing produces a stationary series, then d = 1. If you need to difference again (rare in practice), d = 2.
A common mistake is over-differencing. If you difference a series that's already stationary, you introduce artificial negative autocorrelation at lag 1 and make the modelling harder, not easier. Always test for stationarity before choosing d.
MA(q) - The Moving Average Component
The moving average component models the relationship between an observation and past forecast errors. An MA(q) model says:
[ X_t = \mu + \epsilon_t + \theta_1 \epsilon_{t-1} + \theta_2 \epsilon_{t-2} + \cdots + \theta_q \epsilon_{t-q} ]
where ( \theta_1, \ldots, \theta_q ) are the moving average coefficients and ( \epsilon_t ) is white noise. The model depends not on past values of the series itself but on past unpredicted shocks.
The MA component captures short-lived effects that dissipate after a few periods. If an unexpected event pushes a series up today, an MA(1) model allows that shock to influence tomorrow's value too, but no further. After q periods, the effect vanishes entirely.
The ARIMA(p,d,q) Notation
An ARIMA model is specified by three integers: p, d, and q. Together they define the complete model.
- p - the number of autoregressive lags. Captures how the series depends on its own recent past.
- d - the number of differences needed to achieve stationarity. Usually 0 or 1.
- q - the number of moving average lags. Captures dependence on recent forecast errors.
Some common configurations:
| Model | Equivalent to | Description |
|---|---|---|
| ARIMA(0,0,0) | White noise | No structure at all |
| ARIMA(1,0,0) | AR(1) | Simple autoregressive model |
| ARIMA(0,0,1) | MA(1) | Simple moving average model |
| ARIMA(1,0,1) | ARMA(1,1) | One AR lag plus one MA lag, stationary data |
| ARIMA(0,1,0) | Random walk | Price follows a random walk |
| ARIMA(0,1,1) | Exponential smoothing (SES) | Random walk with MA correction |
| ARIMA(1,1,0) | Differenced AR(1) | AR(1) applied to first differences |
| ARIMA(1,1,1) | - | One of the most commonly used specifications |
The random walk model, ARIMA(0,1,0), deserves special attention in finance. It says that the best forecast of tomorrow's price is today's price - changes are unpredictable. This is the baseline that any forecasting model needs to beat.
The Box-Jenkins Methodology
Box and Jenkins proposed a three-stage iterative procedure for building ARIMA models. Despite being over fifty years old, it remains the standard approach.
Step 1: Identification
The goal is to determine appropriate values for p, d, and q by examining the data.
Check stationarity. Plot the series and run an augmented Dickey-Fuller (ADF) test. If the series is non-stationary (the ADF test fails to reject the null of a unit root), difference it and test again. The number of differences required gives you d.
Examine ACF and PACF. Once the series is stationary, plot the autocorrelation function (ACF) and partial autocorrelation function (PACF). The patterns in these plots guide the choice of p and q:
- If the PACF cuts off after lag p and the ACF decays gradually, the series suggests an AR(p) model.
- If the ACF cuts off after lag q and the PACF decays gradually, the series suggests an MA(q) model.
- If both decay gradually, an ARMA(p,q) model is appropriate, and you'll need information criteria to pin down the orders.
Step 2: Estimation
Fit the candidate ARIMA model(s) using maximum likelihood estimation. Modern software handles this automatically. If you identified several plausible specifications in step 1 - say ARIMA(1,1,1), ARIMA(2,1,0), and ARIMA(1,1,2) - fit all of them and compare using AIC (Akaike Information Criterion) or BIC (Bayesian Information Criterion). Lower values indicate a better trade-off between fit and complexity.
Step 3: Diagnostic Checking
After fitting, verify that the model adequately captures the data's structure.
- Residual ACF. Plot the ACF of the residuals. If the model is well specified, the residuals should be white noise - no significant autocorrelation at any lag.
- Ljung-Box test. Run a formal test for remaining autocorrelation in the residuals. A large p-value (above 0.05) means you can't reject the null of no autocorrelation, which is what you want.
- Residual distribution. Check that the residuals are approximately normally distributed (histogram, Q-Q plot). Heavy tails suggest you might need a different error distribution for reliable forecast intervals.
If diagnostics reveal problems, return to step 1 and try alternative specifications. The Box-Jenkins approach is explicitly iterative - you're expected to refine your model.
Choosing p, d, and q
Selecting the right parameters is the most important and often the trickiest part of ARIMA modelling.
Determining d with Unit Root Tests
The augmented Dickey-Fuller (ADF) test is the standard tool for deciding whether differencing is needed. The null hypothesis is that the series has a unit root (is non-stationary). If the p-value is below 0.05, you reject the null and conclude the series is stationary - no differencing needed (d = 0). If the p-value is above 0.05, difference once and test again.
For financial price data, you'll almost always find d = 1. Returns (first differences of log prices) are stationary, but prices themselves are not.
Using ACF and PACF for p and q
The ACF and PACF plots are your primary tools. The rules of thumb are:
- PACF cuts off at lag p, ACF tails off → choose AR(p), meaning q = 0
- ACF cuts off at lag q, PACF tails off → choose MA(q), meaning p = 0
- Both tail off → you need a mixed ARMA model; use AIC/BIC to compare candidates
In practice, clean cutoffs are rare with real data. You'll typically narrow it down to two or three plausible specifications and let information criteria decide.
Automated Selection with auto_arima
The pmdarima library provides auto_arima, which searches over a range of (p,d,q) combinations and selects the specification that minimises AIC or BIC. It handles the stationarity testing and parameter search automatically.
import pmdarima as pm import numpy as np np.random.seed(42) n = 500 # Simulate an ARIMA(1,1,1) process innovations = np.random.normal(0, 1, n) y = np.zeros(n) diff_y = np.zeros(n) for t in range(2, n): diff_y[t] = 0.6 * diff_y[t - 1] + innovations[t] + 0.4 * innovations[t - 1] y[t] = y[t - 1] + diff_y[t] model = pm.auto_arima( y, start_p=0, max_p=4, start_q=0, max_q=4, d=None, seasonal=False, stepwise=True, suppress_warnings=True, information_criterion="aic", ) print(f"Best model: ARIMA{model.order}") print(f"AIC: {model.aic():.2f}") print(model.summary())
The auto_arima function is convenient, but don't use it as a black box. Always check the diagnostics of the selected model. Automated selection occasionally picks a model that fits the in-sample data well but makes poor forecasts because of overfitting.
Fitting an ARIMA Model in Python
Here's a complete workflow using statsmodels: generate data, test for stationarity, fit an ARIMA model, run diagnostics, and produce forecasts.
import numpy as np import pandas as pd from statsmodels.tsa.arima.model import ARIMA from statsmodels.tsa.stattools import adfuller from statsmodels.stats.diagnostic import acorr_ljungbox np.random.seed(42) n = 600 # Simulate ARIMA(2,1,1): difference once, then AR(2) + MA(1) innovations = np.random.normal(0, 0.5, n) diff_series = np.zeros(n) for t in range(3, n): diff_series[t] = ( 0.5 * diff_series[t - 1] - 0.2 * diff_series[t - 2] + innovations[t] + 0.3 * innovations[t - 1] ) # Integrate once to get the price-like series price = np.cumsum(diff_series) + 100 series = pd.Series(price, name="price") # --- Step 1: Test stationarity --- adf_levels = adfuller(series, autolag="AIC") print("=== ADF Test on Levels ===") print(f"Test statistic: {adf_levels[0]:.4f}") print(f"p-value: {adf_levels[1]:.4f}") print(f"Stationary: {'Yes' if adf_levels[1] < 0.05 else 'No'}") print() # Difference once diff = series.diff().dropna() adf_diff = adfuller(diff, autolag="AIC") print("=== ADF Test on First Differences ===") print(f"Test statistic: {adf_diff[0]:.4f}") print(f"p-value: {adf_diff[1]:.6f}") print(f"Stationary: {'Yes' if adf_diff[1] < 0.05 else 'No'}") print() # --- Step 2: Fit ARIMA(2,1,1) --- model = ARIMA(series, order=(2, 1, 1)) result = model.fit() print("=== Model Summary ===") print(f"AR(1) coefficient: {result.params['ar.L1']:.4f}") print(f"AR(2) coefficient: {result.params['ar.L2']:.4f}") print(f"MA(1) coefficient: {result.params['ma.L1']:.4f}") print(f"AIC: {result.aic:.2f}") print(f"BIC: {result.bic:.2f}") print() # --- Step 3: Diagnostics --- residuals = result.resid lb_test = acorr_ljungbox(residuals, lags=[10, 20], return_df=True) print("=== Ljung-Box Test on Residuals ===") for lag in lb_test.index: pval = lb_test.loc[lag, "lb_pvalue"] status = "White noise" if pval > 0.05 else "Autocorrelation detected" print(f"Lag {lag}: p-value = {pval:.4f} -> {status}") print() # --- Step 4: Forecast --- forecast = result.get_forecast(steps=20) forecast_mean = forecast.predicted_mean conf_int = forecast.conf_int(alpha=0.05) print("=== 20-Step Forecast ===") for i in range(5): lo = conf_int.iloc[i, 0] hi = conf_int.iloc[i, 1] print(f"Step {i + 1}: {forecast_mean.iloc[i]:.2f} [{lo:.2f}, {hi:.2f}]") print(f" ... (15 more steps)")
The key outputs to examine are the Ljung-Box p-values (you want them above 0.05, indicating the residuals are white noise) and the AIC/BIC (for comparing alternative specifications). If the residuals still show autocorrelation, your model is mis-specified - try different orders for p and q.
SARIMA for Seasonal Data
Many real-world time series have seasonal patterns - monthly retail sales peak in December, electricity demand rises in summer and winter, and certain macroeconomic indicators follow quarterly cycles. Standard ARIMA can't capture these recurring patterns efficiently. SARIMA (Seasonal ARIMA) extends the framework by adding seasonal AR, differencing, and MA terms.
A SARIMA model is written as ARIMA(p,d,q)(P,D,Q)[s], where:
- (p,d,q) are the non-seasonal parameters, as before.
- (P,D,Q) are the seasonal autoregressive, differencing, and moving average orders.
- [s] is the seasonal period (12 for monthly data with annual seasonality, 4 for quarterly, etc.).
The seasonal differencing operator removes the seasonal pattern: ( \nabla_s X_t = X_t - X_{t-s} ). If monthly data has an annual seasonal pattern, seasonal differencing subtracts last year's January from this year's January, last year's February from this year's February, and so on.
from statsmodels.tsa.statespace.sarimax import SARIMAX np.random.seed(42) n = 360 # 30 years of monthly data # Simulate monthly data with trend and annual seasonality t = np.arange(n) seasonal = 5 * np.sin(2 * np.pi * t / 12) trend = 0.05 * t noise = np.cumsum(np.random.normal(0, 0.3, n)) y = 50 + trend + seasonal + noise monthly_series = pd.Series(y, name="monthly_value") # Fit SARIMA(1,1,1)(1,1,1)[12] sarima_model = SARIMAX( monthly_series, order=(1, 1, 1), seasonal_order=(1, 1, 1, 12), enforce_stationarity=False, enforce_invertibility=False, ) sarima_result = sarima_model.fit(disp=False) print("=== SARIMA(1,1,1)(1,1,1)[12] ===") print(f"AIC: {sarima_result.aic:.2f}") print(f"BIC: {sarima_result.bic:.2f}") print() print("Parameters:") for param, value in sarima_result.params.items(): print(f" {param}: {value:.4f}") # Forecast 24 months ahead sarima_forecast = sarima_result.get_forecast(steps=24) print() print("=== 24-Month Forecast (first 6 months) ===") for i in range(6): print(f"Month {i + 1}: {sarima_forecast.predicted_mean.iloc[i]:.2f}")
SARIMA is particularly useful for macroeconomic variables and economic indicators where seasonal patterns are strong and predictable. For financial asset prices, seasonality is generally weak (markets are efficient enough to arbitrage predictable seasonal moves), but SARIMA can be relevant for commodities with genuine seasonal supply and demand cycles.
ARIMA for Financial Data
Can you forecast stock prices with an ARIMA model? The honest answer is: not really, and anyone claiming otherwise is overselling the method.
Why ARIMA Struggles with Asset Prices
Stock prices are well approximated by a random walk - ARIMA(0,1,0). Returns (the first differences of log prices) are approximately white noise with very little exploitable autocorrelation. If daily returns had significant AR or MA structure, traders would exploit the pattern until it vanished. This is the efficient market hypothesis in action, and it applies with reasonable force to liquid equities, major FX pairs, and government bond futures.
When you fit an ARIMA model to daily stock returns, the estimated AR and MA coefficients are typically tiny and statistically insignificant. The Ljung-Box test on raw returns of the FTSE 100 or S&P 500 generally fails to reject white noise at daily frequency. The model reverts to saying "my best forecast of tomorrow's return is approximately zero," which isn't useful for trading.
Where ARIMA Is Useful in Finance
That said, ARIMA models do have legitimate applications in quantitative finance:
- Macroeconomic forecasting. GDP growth, inflation, industrial production, and employment figures have genuine autocorrelation structure. Central bank economists and macro strategy desks use ARIMA and SARIMA models routinely for these variables.
- Spread and basis modelling. The spread between cointegrated assets or the basis between a futures contract and its underlying can show exploitable time series structure. ARIMA models can capture mean-reverting dynamics in these series.
- Volatility modelling. Realised volatility is strongly autocorrelated. While GARCH models are the standard tool for conditional volatility, ARIMA models applied to log realised volatility (the HAR-RV approach uses a related idea) can produce competitive forecasts.
- Interest rate modelling. Short-term interest rates and yield curve factors show persistent, slowly mean-reverting dynamics that ARIMA models capture well.
- Benchmarking. Even when you're using a more sophisticated model, ARIMA provides a useful benchmark. If your neural network or gradient-boosted model can't beat ARIMA out of sample, the complexity isn't justified.
ARIMA vs Other Forecasting Models
ARIMA sits in a crowded landscape of time series forecasting methods. Here's how it compares to the main alternatives.
| Feature | ARIMA | Exponential Smoothing | GARCH | Prophet | LSTM |
|---|---|---|---|---|---|
| Type | Parametric, linear | Parametric, linear | Parametric, variance model | Additive, decomposition | Neural network, nonlinear |
| Captures trend | Yes (via differencing) | Yes (Holt's method) | No (models variance, not level) | Yes (piecewise linear) | Yes |
| Captures seasonality | SARIMA variant | Holt-Winters variant | No | Yes (Fourier terms) | Yes (with architecture design) |
| Captures volatility clustering | No | No | Yes (primary purpose) | No | Potentially |
| Handles nonlinearity | No | No | Limited | No | Yes |
| Parameters | p, d, q (manual or auto) | Alpha, beta, gamma | p, q (ARCH/GARCH lags) | Automatic | Architecture choices, many weights |
| Interpretability | High | High | High | Medium | Low |
| Data requirements | Moderate (50+ observations) | Small (can work with 20+) | Moderate (500+ for reliability) | Moderate | Large (thousands+) |
| Best for | Linear, autocorrelated series | Trend and seasonal extrapolation | Volatility forecasting | Business forecasting with events | Complex nonlinear patterns |
| Typical use in 2026 | Macro forecasting, benchmarks | Demand forecasting | Risk management, options | Business analytics | Research, high-dimensional data |
The choice depends on the problem:
- If your data is linear and autocorrelated with no volatility clustering, ARIMA is a strong choice and often the best one.
- If volatility matters more than the level, use GARCH (or fit ARIMA for the mean equation and GARCH for the variance).
- If you need quick, automated forecasts for business data with holidays and events, Prophet is convenient.
- If you have large datasets and suspect nonlinear patterns, LSTMs and other deep learning models are worth exploring, but they need far more data and tuning.
For many practical problems in 2026, ARIMA remains competitive. It's fast, interpretable, has well-understood statistical properties, and requires no GPU.
Limitations of ARIMA Models
ARIMA is a powerful and well-tested framework, but it has clear boundaries.
Linearity
ARIMA models are fundamentally linear. They assume the future value is a linear combination of past values and past errors. Real-world relationships - particularly in financial markets - often involve nonlinear dynamics: threshold effects, regime changes, and asymmetric responses to positive versus negative shocks. ARIMA can't capture these patterns. If the data-generating process is nonlinear, ARIMA will underperform models that can handle nonlinearity, such as regime-switching models, threshold AR models, or neural networks.
Stationarity Assumption
After d rounds of differencing, ARIMA assumes the resulting series is stationary - constant mean, constant variance. If the variance itself changes over time (as it does for virtually all financial returns), ARIMA's constant-variance assumption is violated. The point forecasts may still be reasonable, but the forecast intervals will be wrong - too narrow during volatile periods and too wide during calm ones. This is precisely why GARCH models were developed: to handle the time-varying variance that ARIMA ignores.
Sensitivity to Outliers
Large outliers can distort ARIMA parameter estimates significantly. A single extreme return - a flash crash, a surprise central bank decision - can inflate the MA coefficient or bias the AR coefficients. Robust estimation methods exist but aren't the default in most software. When working with financial data that includes crisis periods, it's worth checking how sensitive your estimates are to removing a handful of extreme observations.
Poor Long-Horizon Forecasts
ARIMA forecasts converge to the unconditional mean of the (differenced) series as the forecast horizon increases. The forecast intervals widen rapidly, and after 10-20 steps the model is essentially saying "I don't know." This is honest - linear models genuinely lose predictive power at longer horizons - but it means ARIMA is a short-term forecasting tool. For horizons beyond a few dozen periods, structural models or scenario analysis are more appropriate.
No Exogenous Variables (Without Extension)
Standard ARIMA uses only the history of the series itself. If external factors drive the variable you're forecasting, ARIMA can't incorporate them. The ARIMAX (or SARIMAX) extension adds exogenous regressors, but at that point you're combining regression with ARIMA errors, which introduces its own complexities around variable selection and overfitting.
Frequently Asked Questions
What does ARIMA stand for?
ARIMA stands for AutoRegressive Integrated Moving Average. "AutoRegressive" means the model uses past values of the series to predict the current value. "Integrated" refers to differencing - making a non-stationary series stationary by subtracting consecutive observations. "Moving Average" means the model also uses past forecast errors (residuals) as predictors. The three components work together: differencing handles trends and non-stationarity, autoregression captures momentum and persistence, and the moving average component captures short-lived shock effects. Box and Jenkins popularised the framework in 1970, and it remains one of the most widely used time series models in 2026.
How do I choose the values of p, d, and q?
Start with d. Run an augmented Dickey-Fuller test on the raw series. If the p-value exceeds 0.05, difference once and test again. Most series need d = 0 or d = 1. For p and q, examine the ACF and PACF plots of the stationary (possibly differenced) series. If the PACF cuts off at lag p while the ACF tails off, set that p and q = 0. If the ACF cuts off at lag q while the PACF tails off, set that q and p = 0. If both tail off, try a few combinations and compare AIC values. Alternatively, use auto_arima from the pmdarima library for automated selection. Whichever method you use, always validate with residual diagnostics - the Ljung-Box test should confirm the residuals are white noise.
Can ARIMA predict stock prices?
In practice, no - not with any useful accuracy. Daily returns of liquid stocks are very close to white noise, meaning there's virtually no autocorrelation for ARIMA to exploit. An ARIMA model fitted to stock returns will typically produce coefficients that are tiny and statistically insignificant, and the forecast will be "approximately zero return tomorrow." This is consistent with the efficient market hypothesis. ARIMA is far more useful for macroeconomic variables, interest rates, volatility measures, and mean-reverting spreads where genuine time series structure exists. If someone offers you an ARIMA model that "predicts stock prices," treat the claim with scepticism.
What is the difference between ARIMA and SARIMA?
SARIMA (Seasonal ARIMA) extends the standard ARIMA model by adding seasonal components. While ARIMA(p,d,q) captures non-seasonal patterns, SARIMA adds a second set of parameters (P,D,Q)[s] for seasonal autoregression, seasonal differencing, and seasonal moving average at a seasonal period s. For example, SARIMA(1,1,1)(1,1,1)[12] applied to monthly data would capture both month-to-month dynamics (through the non-seasonal terms) and year-over-year seasonal patterns (through the seasonal terms with period 12). Use SARIMA when your data has clear, repeating seasonal cycles - monthly sales data, quarterly economic indicators, or any series where the pattern at month t is related to the pattern at month t - 12.
How does ARIMA compare to GARCH?
They model different things. ARIMA models the conditional mean of a time series - it forecasts where the level of the series is heading. GARCH models the conditional variance - it forecasts how volatile the series will be. In many financial applications, the two are complementary: you fit an ARIMA (or ARMA) model for the mean equation and a GARCH model for the variance of the residuals. This combination captures both the predictable part of the level and the predictable part of the volatility. If you only care about the direction or level of a variable, ARIMA alone may suffice. If you care about risk, uncertainty, or the width of your forecast intervals, you need GARCH as well.
Is ARIMA still relevant in 2026 with machine learning available?
Yes. ARIMA remains a first-line tool for several reasons. It's interpretable - you can explain exactly what the model is doing and why. It has well-understood statistical properties - you get proper confidence intervals, hypothesis tests, and information criteria. It requires far less data than deep learning models. And for linear, autocorrelated time series, ARIMA is genuinely difficult to beat. Multiple forecasting competitions have shown that simple statistical models like ARIMA and exponential smoothing outperform complex machine learning models on many benchmark datasets, particularly when data is limited. The practical approach in 2026 is to use ARIMA as a baseline and only move to more complex models when you have evidence they add value.
Want to go deeper on ARIMA Model: Time Series Forecasting Explained 2026?
This article covers the essentials, but there's a lot more to learn. Inside Quantt, you'll find hands-on coding exercises, interactive quizzes, and structured lessons that take you from fundamentals to production-ready skills — across 50+ courses in technology, finance, and mathematics.
Free to get started · No credit card required