ARIMA in Microsoft Excel
Learning Objectives
- Understand what ARIMA estimation does under the hood — beyond calling a Python function
- Test for stationarity in Excel using means, variances, and autocorrelation formulas
- Build an AR(1) model entirely in Excel using
LINEST()and cell formulas - Estimate an MA(1) model using Excel Solver
- Complete a full ARIMA estimation walkthrough on 12 quarters of data using Solver
- Compare Excel manual results with Python
statsmodelsoutput
What You Need
- Microsoft Excel (2016 or later — Solver add-in must be enabled)
- To enable Solver: File → Options → Add-ins → Solver Add-in → Go → Check Solver → OK
- Familiarity with Excel formulas (
=SUM(),=AVERAGE(),=SUMPRODUCT(),=LINEST()) - Module 5 (Python ARIMA) — this is a companion, not a replacement
In This Bonus Module
1. Why Excel for ARIMA?
When you type ARIMA(y, order=(1,1,0)).fit() in Python, statsmodels runs a sophisticated maximum likelihood optimisation. The output appears in milliseconds. But what actually happened? What equations were solved? What was the computer doing while you waited?
This bonus module rebuilds ARIMA from scratch in Excel — every formula visible, every calculation traceable. By the end, you will understand ARIMA not as a black-box function call, but as a sequence of logical spreadsheet operations you could explain to a student.
Our Dataset
We use 13 quarters of sales data (in ₹ Lakhs) for a small manufacturing firm. The data exhibits a clear alternating pattern in growth — high-growth quarters followed by lower-growth quarters — which makes the AR(1) structure visible:
| Quarter | Period (t) | Sales (Yt) | ΔYt |
|---|---|---|---|
| 2023-Q1 | 0 | 100 | — |
| 2023-Q2 | 1 | 107 | 7 |
| 2023-Q3 | 2 | 115 | 8 |
| 2023-Q4 | 3 | 122 | 7 |
| 2024-Q1 | 4 | 130 | 8 |
| 2024-Q2 | 5 | 136 | 6 |
| 2024-Q3 | 6 | 144 | 8 |
| 2024-Q4 | 7 | 150 | 6 |
| 2025-Q1 | 8 | 158 | 8 |
| 2025-Q2 | 9 | 164 | 6 |
| 2025-Q3 | 10 | 172 | 8 |
| 2025-Q4 | 11 | 178 | 6 |
| 2026-Q1 | 12 | 186 | 8 |
Look at the ΔY column: 7, 8, 7, 8, 6, 8, 6, 8, 6, 8, 6, 8. High-growth quarters (8) are consistently followed by lower-growth quarters (6 or 7) — this is the negative autocorrelation that an AR(1) model captures.
2. Stationarity Testing — Excel Style
Step 1: Visual Inspection (Line Chart)
Select Columns B and C (Period and Sales). Insert a Line Chart. Does the series have a clear upward trend? Yes — sales grow from 100 to 186 over 12 quarters. A trending series is non-stationary.
Step 2: Compare Means and Variances Across Sub-Periods
Split the data into two halves (Periods 0–6 and 7–12). If the series is stationary, the mean and variance should be approximately equal in both halves.
| Statistic | Periods 0–6 | Periods 7–12 | Equal? |
|---|---|---|---|
| Mean (Y) | 122.0 | 168.0 | No — means are very different |
| Mean (ΔY) | 7.3 | 7.0 | Approximately equal ✓ |
Mean Y (Periods 0-6): =AVERAGE(C2:C8) → 122.0
Mean Y (Periods 7-12): =AVERAGE(C9:C14) → 168.0
Mean ΔY (Periods 1-6): =AVERAGE(D3:D8) → 7.33
Mean ΔY (Periods 7-12): =AVERAGE(D9:D14) → 7.00
Sales means differ substantially (122 vs 168) — strong evidence of non-stationarity. But ΔY means are similar (7.3 vs 7.0) — the differenced series appears stationary.
Step 3: Autocorrelation at Lag 1
A non-stationary series has autocorrelation close to 1.0. A stationary series should have autocorrelation well below 1.0.
Autocorrelation of Y_t (any cell): =CORREL(C3:C14, C2:C13)
Autocorrelation of ΔY_t (any cell): =CORREL(D4:D14, D3:D13)
Autocorrelation of Y_t (Lag 1): r₁ = 0.996 → Very close to 1.0 → Non-stationary Autocorrelation of ΔY_t (Lag 1): r₁ ≈ -0.65 → Well below 1.0 → Stationary ✓
Step 4: First Differencing
Create the first difference column:
Excel (Cell D3): =C3-C2 (drag down to D14)
3. AR(1) Model in Excel — From Equation to Spreadsheet
The AR(1) Equation
We model the stationary differenced series: ΔYt = c + φ₁ · ΔYt-1 + ϵt
Step 1: Create the Lag Column
Create Column E for the lagged differenced series (ΔYt-1):
| Row | B (t) | C (Yt) | D (ΔYt) | E (ΔYt-1) |
|---|---|---|---|---|
| 2 | 0 | 100 | — | — |
| 3 | 1 | 107 | 7 | — |
| 4 | 2 | 115 | 8 | 7 |
| 5 | 3 | 122 | 7 | 8 |
| 6 | 4 | 130 | 8 | 7 |
| ... drag down ... | ||||
| 14 | 12 | 186 | 8 | 6 |
Excel (Cell E4): =D3 (drag down to E14)
Step 2: Estimate φ₁ and c Using LINEST
LINEST() is Excel's built-in OLS function. We regress ΔYt on ΔYt-1:
Select cells H3:I3, type this formula, press Ctrl+Shift+Enter:
=LINEST(D4:D14, E4:E14, TRUE, TRUE)
(Regress ΔY_t [Col D, rows 4-14] on lagged ΔY_{t-1} [Col E, rows 4-14])
Results (approximate — your Excel may show slight differences):
H3 = φ₁ ≈ -0.91 (slope — the AR coefficient)
I3 = c ≈ 13.60 (intercept)
Interpretation: ΔY_t = 13.6 - 0.91 × ΔY_{t-1}
When last quarter's growth was high (ΔY = 8):
13.6 - (0.91 × 8) = 13.6 - 7.28 ≈ 6.3 (a low-growth quarter)
When last quarter's growth was low (ΔY = 6):
13.6 - (0.91 × 6) = 13.6 - 5.46 ≈ 8.1 (a high-growth quarter)
The negative φ₁ captures the alternating pattern: high → low, low → high.
Step 3: Compute Fitted Values and Residuals
| Col F (Fitted) | Col G (Residual) | Formula |
|---|---|---|
| = I$3 + H$3*E4 | = D4 - F4 | Row 4 |
| 13.6+(-0.91)×7 = 7.2 | 8 - 7.2 = +0.8 | |
| 13.6+(-0.91)×8 = 6.3 | 7 - 6.3 = +0.7 | |
| 13.6+(-0.91)×7 = 7.2 | 8 - 7.2 = +0.8 | |
| 13.6+(-0.91)×8 = 6.3 | 6 - 6.3 = -0.3 | |
| 13.6+(-0.91)×6 = 8.1 | 8 - 8.1 = -0.1 | |
| ... drag down ... | ||
Cell F4: =I$3 + H$3*E4 (fitted: c + φ₁ × ΔY_{t-1})
Cell G4: =D4 - F4 (residual: actual - fitted)
Drag both down to row 14.
Step 4: Compute SSE and Approximate AIC
It measures how much the model's predictions miss the actual values. SSE = Σ(Actual - Predicted)2. A lower SSE means the model fits the data better. But SSE alone is not enough — it always decreases when you add more parameters, even useless ones.
AIC = Akaike Information Criterion
AIC solves this by penalising model complexity. Formula: AIC = N × ln(SSE/N) + 2 × k, where N = number of observations, k = number of parameters. The first term rewards good fit (lower SSE); the second term penalises extra parameters. A lower AIC means a better model — one that fits well without unnecessary complexity. When comparing two models, the one with the lower AIC is preferred.
(All formulas below start from Row 4 because Rows 2-3 have no residuals —
Row 2 has no ΔY, Row 3 has ΔY but no lagged value for the AR equation)
SSE (Cell J3): =SUMSQ(G4:G14) → SSE ≈ 3.0
N (Cell J4): =COUNT(G4:G14) → N = 11
k (Cell J5): 2 (c + φ₁ = 2 parameters)
AIC (Cell J6): =J4*LN(J3/J4) + 2*J5 → AIC ≈ -12
AR(1) on differenced data: φ₁ (AR coefficient) ≈ -0.91 c (constant) ≈ 13.60 SSE ≈ 3.0 Long-run mean growth = c/(1-φ₁) = 7.1 units/quarter The strong negative φ₁ captures the alternating boom-slowdown pattern in the firm's quarterly sales growth.
4. MA(1) Model in Excel — Solver to the Rescue
The MA(1) Equation
ΔYt = μ + ϵt + θ₁ · ϵt-1
The problem: we do not observe ϵt and ϵt-1 — they must be estimated jointly with θ₁. This makes MA models non-linear, and LINEST() (which does linear OLS) cannot estimate them. We need Solver.
Step 1: Set Up Parameter Cells
Important: The AR section already uses columns F–J. The MA model uses separate columns: L for parameters (2 cells only), M–O for the data chain, P for diagnostics.
| Cell | Label | Initial Value |
|---|---|---|
| L3 | μ (constant) | 7.00 |
| L4 | θ₁ (MA coefficient) | 0.00 |
Step 2: Build the Residual Computation Chain
The MA(1) model has a recursive structure. We initialise ϵ0 = 0 (standard assumption) and compute forward. Parameters are in Col L (L3, L4). The working columns are M (ε_t), N (ε_{t-1}), O (Fitted):
| Row | D (ΔYt) | M (εt) | N (εt-1) | O (Fitted) |
|---|---|---|---|---|
| 3 | 7 | 0.00 | 0 | 7.00 |
| 4 | 8 | 1.00 | 0.00 | 7.00 |
| 5 | 7 | 0.00 | 1.00 | 7.00 |
Col M — ε_t (MA residuals):
Cell M3: =D3 - L$3 → ε₁ = ΔY₁ - μ (uses parameter from L3)
Cell M4: =D4 - L$3 - L$4*M3 → ε₂ = ΔY₂ - μ - θ₁·ε₁ (uses params L3,L4 and previous ε from M3)
Drag M4 down to M14.
Col N — ε_{t-1} (lagged residuals):
Cell N4: =M3 → simply copies yesterday's ε
Drag N4 down to N14.
Col O — Fitted values:
Cell O3: =L$3 + L$4*0 → fitted = μ + θ₁·0 (since ε₀=0)
Cell O4: =L$3 + L$4*M3 → fitted = μ + θ₁·ε_{t-1}
Drag O4 down to O14.
Col P — Diagnostics (separate from AR's Col J):
SSE (P3): =SUMSQ(M3:M14) → SSE ≈ 4.85
N (P4): =COUNT(M3:M14) → N = 12
k (P5): 2 (μ + θ₁ = 2 parameters)
AIC (P6): =P4*LN(P3/P4) + 2*P5 → calculates automatically
Step 3: Run Solver
- Data → Solver (if not visible, enable the Solver Add-in)
- Set Objective: P3 (SSE) → Min
- By Changing Variable Cells: L3:L4 (μ and θ₁)
- Solving Method: GRG Nonlinear
- Click Solve
μ (constant): 7.08 (≈ mean of ΔY)
θ₁ (MA coefficient): -0.55
SSE: 4.85 (from Cell P3)
AIC: -7.30 (from Cell P6: N×ln(SSE/N) + 2k)
Interpretation: ΔY_t = 7.08 + ε_t - 0.55·ε_{t-1}
A positive shock this quarter is partially reversed next quarter —
the same alternating pattern captured through a different mechanism.
AR(1) vs MA(1) — Which Fits Better?
Both models have SSE and AIC columns in your spreadsheet. Now compare them side by side:
| Model | k (params) | SSE | AIC | Decision |
|---|---|---|---|---|
| AR(1) | 2 | 3.0 | -12.3 | ✓ Winner |
| MA(1) | 2 | 4.9 | -7.3 | ✗ |
Why AR(1) wins: Both models use 2 parameters, so the complexity penalty (2k = 4) is the same. AR(1) simply fits the data better — its SSE (3.0) is lower than MA(1)'s SSE (4.9). Lower SSE → lower AIC → better model.
In your Excel, both models now sit side by side:
AR(1): SSE in Cell J3, AIC in Cell J6 (Columns F–J)
MA(1): SSE in Cell P3, AIC in Cell P6 (Columns L–P)
Decision rule: Compare P6 vs J6 — the smaller AIC wins.
5. Full ARIMA(1,1,0) — The Complete Walkthrough
We now combine everything into ARIMA(1,1,0): p=1 (one AR term), d=1 (one difference), q=0 (no MA terms). Because q=0, there is no MA estimation step in this workflow — the model uses only AR(1) on the differenced data. The 9 steps below cover identification (d), estimation of AR via LINEST, diagnostics, and forecasting:
ARIMA in Excel — Complete Process
need to DIFFERENCE once: d = 1
Model ΔY (changes) instead of Y (levels)
no differencing needed: d = 0
Model Y directly — it's already stable
d = 0: The original series is already stationary — no differencing needed. Model Yt directly.
d = 1: The series has a trend and is non-stationary. Subtract each value from the previous one (ΔYt = Yt - Yt-1) — the differenced series is now stationary. This is the most common case for economic data (GDP, sales, prices).
d = 2: Even the differenced series is non-stationary. Difference it again. Rare in practice — most economic series become stationary after one difference.
In our example, Sales (Y) had a clear upward trend → non-stationary → we differenced once → ΔY became stationary → so d = 1.
Complete Spreadsheet
Here is the full spreadsheet after estimation (LINEST output in H3:I3):
| Row | B(t) | C(Yt) | D(ΔYt) | E(ΔYt-1) | F(Fitted) | G(εt) |
|---|---|---|---|---|---|---|
| 2 | 0 | 100 | — | — | — | — |
| 3 | 1 | 107 | 7 | — | — | — |
| 4 | 2 | 115 | 8 | 7 | 7.2 | +0.8 |
| 5 | 3 | 122 | 7 | 8 | 6.3 | +0.7 |
| 6 | 4 | 130 | 8 | 7 | 7.2 | +0.8 |
| 7 | 5 | 136 | 6 | 8 | 6.3 | -0.3 |
| 8 | 6 | 144 | 8 | 6 | 8.1 | -0.1 |
| 9 | 7 | 150 | 6 | 8 | 6.3 | -0.3 |
| 10 | 8 | 158 | 8 | 6 | 8.1 | -0.1 |
| 11 | 9 | 164 | 6 | 8 | 6.3 | -0.3 |
| 12 | 10 | 172 | 8 | 6 | 8.1 | -0.1 |
| 13 | 11 | 178 | 6 | 8 | 6.3 | -0.3 |
| 14 | 12 | 186 | 8 | 6 | 8.1 | -0.1 |
| 15 | 13 | 194 | 8 | 8 | 6.3 | — |
| 16 | 14 | 200 | 6 | 8 | 6.3 | — |
Forecasting: Steps 8-9
Forecast ΔY_{13} (Cell D15):
= I$3 + H$3*D14 → 13.6 + (-0.91)*8 = 13.6 - 7.3 = 6.3
Forecast Y_{13} (Cell C15):
= C14 + D15 → 186 + 6.3 ≈ 192.3 → rounds to ~192
Forecast ΔY_{14} (Cell D16):
= I$3 + H$3*D15 → 13.6 + (-0.91)*6.3 = 13.6 - 5.7 = 7.9
Forecast Y_{14} (Cell C16):
= C15 + D16 → 192.3 + 7.9 ≈ 200.2 → rounds to ~200
ARIMA(1,1,0) Model Estimates (LINEST on differenced data): d (differencing) = 1 φ₁ (AR coefficient) ≈ -0.91 c (constant) ≈ 13.6 SSE ≈ 3.0 Long-run growth = c/(1-φ₁) = 7.1 units/quarter Forecast: 2026-Q2 (t=13): Y ≈ 192 (growth ΔY = 6) 2026-Q3 (t=14): Y ≈ 200 (growth ΔY = 8) The alternating pattern (6, 8, 6, 8...) continues in the forecast.
6. Excel vs. Python — When to Use Which
Verification: Excel vs Python on the Same Data
# Run this in Python to verify our Excel results
import pandas as pd; import numpy as np
from statsmodels.tsa.arima.model import ARIMA
Y = [100,107,115,122,130,136,144,150,158,164,172,178,186]
model = ARIMA(Y, order=(1,1,0)).fit()
print(f"φ₁ = {model.params['ar.L1']:.3f}")
print(f"c = {model.params.get('const', model.params.get('intercept', 0)):.3f}")
print(f"AIC = {model.aic:.2f}")
fc = model.forecast(steps=2)
print(f"Forecast t=13: {fc[0]:.1f}")
print(f"Forecast t=14: {fc[1]:.1f}")
φ₁ ≈ -0.89 (Excel LINEST: -0.91 ✓ close match — OLS vs MLE) c ≈ 13.49 (Excel LINEST: 13.60 ✓ close match) AIC = 51.2 (Excel approximate: — different computation) Forecast t=13: 192.4 Forecast t=14: 200.9 Minor differences are expected: - Excel LINEST uses OLS; statsmodels uses MLE (Maximum Likelihood) - OLS and MLE give very similar results for AR models - The Excel approach produces valid, interpretable estimates
Side-by-Side Comparison
| Criterion | Excel | Python (statsmodels) |
|---|---|---|
| Speed (small data) | Instant — LINEST or Solver in <1s | Instant |
| Speed (large data) | Painfully slow or impossible | Handles thousands of observations easily |
| Diagnostics | Manual — AIC, residuals computed by you | Automatic — Ljung-Box, AIC/BIC, SEs, p-values |
| Confidence Intervals | Difficult — requires matrix algebra | Automatic — reported in model summary |
| ARIMA order selection | Manual trial-and-error | auto_arima() searches automatically |
| Transparency | Every cell visible — ideal for teaching | Black box — MLE runs inside compiled code |
| SARIMA | Extremely tedious (many parameters) | Trivial — just set seasonal_order |
| Reproducibility | Poor — Solver settings not saved with file | Excellent — script produces identical results every run |
| Best for | Teaching, verifying small models, building intuition | Research, publication, real-world forecasting |
ar.L1 = -0.89 in a statsmodels summary, you now know exactly what computation produced that number.When to Use Each Approach
- Use Excel when: Teaching ARIMA to students, verifying Python output on small datasets, building intuition before writing code, or working with colleagues who don't use Python
- Use Python when: Doing actual research, working with datasets larger than ~100 observations, needing diagnostic tests and confidence intervals, or producing publication-quality forecasts
Key Takeaways
Stationarity testing in Excel is manual but transparent: split the data into halves, compare means, compute autocorrelation with =CORREL(), and difference the series until stable. The logic is identical to ADF/KPSS — just computed by hand.
AR models are linear — Excel's =LINEST() estimates them directly. MA models are non-linear — you need Solver because the residuals are part of the estimation. This is the fundamental reason ARIMA estimation requires iterative algorithms.
Excel and Python produce nearly identical results on small data. Your φ₁ ≈ -0.91 from LINEST matches Python's -0.89 from MLE. The Excel approach is not a "toy" — it is a valid estimation method. The difference is automation, not mathematics.
Learning ARIMA in Excel before Python builds lasting intuition. When you see ar.L1 = -0.89 in statsmodels output, you know exactly what that number means and how it was computed — because you built it yourself, cell by cell.
The 9-step workflow (plot → difference → lag → estimate → fitted → SSE → diagnose → forecast → recover levels) is universal. Whether you use Excel, Python, R, or STATA, these are the same steps. Master them in Excel, and every other tool becomes easier.