Choose one language
The three independent implementations share inputs, parameter conventions, target dates, and numerical checks. You can study in one language and inspect another when a result is unclear. You need only one of the three runtimes to work through the course.
Download the complete laboratory bundle, extract it, and open a terminal in its code directory. Keep the relative directory structure: entry points load the corresponding course implementation, and those implementations read fixed files in data.
The tested environment is Python 3.14.7 with NumPy 2.4.3, SciPy 1.17.1, and Matplotlib 3.10.8; R 4.6.1; and Julia 1.12.7. The core R and Julia examples use standard libraries only. Python requirements and their resolution are recorded in pyproject.toml and uv.lock. No provider API credential is needed to run the examples.
Python
Install Python and uv if they are not available. In the extracted code directory:
uv sync --locked
uv run python ch01.py
uv run python projects.py
The first command prepares the project environment. A chapter entry point runs its exact experiment. projects.py runs the complete public project case. Core computation uses NumPy; the pinned scientific environment also supports supplementary calculation and figure generation.
R
Use an installed R runtime and run:
Rscript ch01.R
Rscript projects.R
The reference implementations require base R. They do not install packages or change global settings. Read course.R for every calculation, including least-squares conventions, residual recursion, filtering, covariance factors, and variance updates.
Julia
Use an installed Julia runtime and run:
julia --startup-file=no ch01.jl
julia --startup-file=no projects.jl
The implementations use LinearAlgebra, Statistics, and DelimitedFiles. They require no external Julia packages. The verification runner can use a local writable depot for precompilation where the home depot is unavailable. Read course.jl for the full implementation.
Verify all three concurrently
With all three runtimes available:
uv run python verify.py
The runner executes the full lecture implementations concurrently, then executes the three project implementations concurrently. It checks input hashes, finite outputs, analytic identities, future-mutation invariants, parameter-domain failures, metric coverage, cross-language agreement, and every retained project forecast’s dates and value.
The current verification report records 152 lecture quantities, 13 project quantities, and 276 matched project forecast rows. Lecture numerical tolerance is absolute and relative; project tolerance is . The observed discrepancies are much smaller. Agreement is evidence of consistent implementation, not proof of a shared economic assumption.
The tests include deliberately failing cases: an inadmissible centered feature responds to future changes; a smoother intentionally uses later information; a covariance rotation changes shock interpretation without changing covariance; a rank-deficient design is rejected; a finite-variance GARCH routine rejects inadmissible parameters. The resulting repair or narrowed interpretation belongs to the lesson.
Run uv run python verify-boundaries.py for seven additional state-space checks in each language. They compare filtering and smoothing with exact single-observation Gaussian calculations, check zero process variance and missing observations, and reject empty inputs or nonfinite parameters. The boundary report records the results.
Lecture 2’s changing-risk example has independent Python, R, and Julia sources. Run uv run python verify-risk.py to check 42 matched quantities, nine analytic targets, and fifteen finite-sum identities. The risk verification report records exact enumeration of the two risk states, including conditional variances 1.25 and 11.25 and their unconditional average 6.25. The calculation uses no random draws.
Lecture entry points
Each row runs a complete case and writes its metrics. The chapter describes the economic argument, exact conventions, and the relevant functions in the full source. Entry points are intentionally short so the common algorithms remain in one inspectable file per language. For that reason an entry point runs only inside the extracted code folder, where it can load the course file and data beside it.
| Lecture | Main executable concepts | Python | R | Julia |
|---|---|---|---|---|
| 1 | Release clock, availability audit, geography, naive benchmark | ch01.py | ch01.R | ch01.jl |
| 2 | AR recursion, moments, iterated and closed-form forecasts, aggregation | ch02.py | ch02.R | ch02.jl |
| 3 | ARMA residuals, full objective grid, ACF/PACF, invertibility, forecasts | ch03.py | ch03.R | ch03.jl |
| 4 | Rolling origins, loss, coverage, Ljung–Box on one- and four-step errors, paired-loss statistic | ch04.py | ch04.R | ch04.jl |
| 5 | Noisy signals, trailing/centered filters, mutation | ch05.py | ch05.R | ch05.jl |
| 6 | Trends, DF/ADF, single-stream Monte Carlo, spurious regression | ch06.py | ch06.R | ch06.jl |
| 7 | Fourier terms, temperature proxies, feasible GLS | ch07.py | ch07.R | ch07.jl |
| 8 | Filter, smoother, missing update, Gaussian likelihood | ch08.py | ch08.R | ch08.jl |
| 9 | VAR fit, eigenvalues, Granger Wald tests, networks, forecast covariance | ch09.py | ch09.R | ch09.jl |
| 10 | Cholesky ordering, rotation, VAR and local-projection responses | ch10.py | ch10.R | ch10.jl |
| 11 | Common trend, spread, ECM estimation and forecast | ch11.py | ch11.R | ch11.jl |
| 12 | GARCH recursion/grid, risk quantile, scale invariance | ch12.py | ch12.R | ch12.jl |
| 13 | Breaks, windows, paired loss, block/HAC uncertainty | ch13.py | ch13.R | ch13.jl |
| 14 | Validation choice, frozen update, continuation | ch14.py | ch14.R | ch14.jl |
| 15 | Unit/future invariants, boundaries, rank failure | ch15.py | ch15.R | ch15.jl |
Project sources and results
projects.py, projects.R, and projects.jl implement the complete Build/Audit/Revise case. Read the specifications and actual results before interpreting its files.
Download the forecast table, freeze record, and project comparison quantities. Equivalent R and Julia outputs are included in the bundle and verified row by row. The public example’s final benchmark advantage is retained as a substantive result.
Fixed input files
The synthetic innovations have a generator and hash record. All languages read the same 2,048-by-6 file. Monte Carlo paths use the explicitly implemented Park–Miller/Box–Muller algorithm, not three unrelated language-default generators. Lecture 6 draws 2,000 replications per design from one stream with seed 2026, split into consecutive blocks. Reseeding each replication with consecutive seeds would give the first Box–Muller pair of every replication nearly the same radius, because the generator is multiplicative. The former seeds did this: across 200 replications the first two innovations each had a standard deviation of 2.07. monte-carlo-reference.py repeats the designs with 200,000 replications from NumPy’s generator, and its report records the reference rates.
The Texas electricity and temperature extract has a provider and units manifest. The extraction source checks the provider’s geographic label, workbook units, unique state-month rows, and month matches. Rebuilding the provider extract needs openpyxl==3.1.5; running the course does not.
The provider endpoints can change their latest values. Rebuilding a later extract is a new vintage and should receive a new hash. Do not overwrite the fixed course input and still claim exact reproduction of this edition’s reported quantities.
Source and publication formats
Read the editable chapter source, print the lecture text, or download the PDF book, which also includes projects, assignments, and references. The public source archive contains Markdown, code, data, figures, and editable print source. Live assessments, grading keys, private instructor scripts, and graded holdouts are kept in the separate instructor package.
© 2026 Ian Helfrich. All rights reserved. The public availability of the authored book does not grant a blanket redistribution or adaptation license. EIA and NOAA data and third-party sources retain their original terms and attribution.