CHAPTER 19/ 45
State-Space Models and the Kalman Filter
Core idea: First use the state transition to form a prior, then use the innovation from a new observation to update the hidden state. The timestamp determines whether that update can inform a trade. Prerequisites: Chapter 5, linear algebra; Chapter 6, conditional Gaussian distributions; Chapter 8, regression; Chapter 16, monthly time indexing. By the end of this chapter, you will be able to derive the scalar-observation Kalman update from a conditional Gaussian distribution, calculate a one-dimensional dynamic beta by hand, explain a two-dimensional alpha/beta state and its hedge ratio, distinguish filtering from smoothing, and build a research workflow that keeps future information out of historical signals.
1. Learning objectives
After reading, you should be able to write a state-space representation and state the units and dimensions of its states, observations, and noise; derive the prediction, innovation, innovation variance, Kalman gain, and posterior covariance from a joint Gaussian distribution; calculate a beta update by hand; distinguish the information used by a filtered state from that used by a smoothed state; and run the core function, fixed-seed simulation, and frozen-data example while explaining which investment claims they do not validate.
You have completed this chapter when your hand calculations match the code, every state and observation has a clear timestamp, and you can find complete answers to the original 13 questions and the 3 added teaching questions in Section 18.
2. Why Quant practitioners use state-space models
A historical regression beta is the average market exposure over a particular sample window. If exposure changes over time, a fixed beta averages away those changes. Rolling ordinary least squares (OLS) repeatedly changes the sample window, so both the window length and the re-estimation point affect the result.
A state-space model separates the problem into two processes: how latent exposure changes and how current returns vary around that exposure. A dynamic beta is an estimate of market exposure that changes over time. Each month, as new returns arrive, you compare them with the model’s prior expectation and update the beta estimate. The process-noise variance specifies how much state change the model allows; the observation-noise variance describes how much returns deviate from the relationship with the state.
This decomposition gives risk estimation a recursive update rule. It does not determine whether beta is stable, how large process noise should be, whether a hedge can be executed, or whether dynamic beta outperforms rolling OLS. You still need training-period and out-of-sample evidence to answer those questions.
3. Intuition: the state changes behind the scenes while returns mix signal and noise
You can observe monthly asset and market returns, but not the asset’s true sensitivity to the market. That sensitivity is a latent state. Monthly residuals can also reflect industry shocks, portfolio changes, and measurement error.
The filter processes each month in sequence:
| Timing | Information available | Action | Output |
|---|---|---|---|
| Before the month begins | Observations through the prior month | Project forward with the state-transition model | Prior mean and variance for the month |
| After this month’s returns arrive | This month’s asset and market returns | Subtract the prior expectation from the realized value | Innovation and its variance |
| Month-end update | The prior, innovation, and variance above | Adjust the state based on uncertainty | Filtered state incorporating this month’s observation |
The prior distribution is the state distribution before the observation month begins; the posterior distribution is the state distribution conditional on this month’s observation. The predicted state can inform risk controls during the month, but the filtered state does not exist until this month’s returns arrive. They refer to different information sets.
4. Mathematical setup and notation
Suppose the state has
In this chapter, let
where
The implementation starts from
Which object does each of the three uncertainties belong to?
| Quantity | Random object | Role in the recursion |
|---|---|---|
| New state shock |
State-change uncertainty added after the transition | |
| Observation error |
Noise that remains in the observation given the state | |
| (P_{t | t-1}), (P_{t | t}) |
Notation note: the scalar observation_design is the design, process_covariance corresponds to observation_variance corresponds to
5. Formal definitions: hidden states, observations, and model assumptions
A latent state is a variable the model describes but cannot directly observe. Dynamic beta is one example. The observation equation links it to visible returns, while the state equation describes how it changes from one period to the next.
Filtering computes, in time order,
The subscript
Smoothing computes
A smoothed state includes observations after the target month, so it is useful for explaining the full history after the fact. This chapter does not implement a smoother; do not describe smoothing as a code output or a real-time signal.
The conditional Gaussian posterior in this chapter requires the following assumptions:
- The initial state
has a Gaussian distribution with known mean and covariance. - State noise and observation noise are zero-mean Gaussian in each period; noise is independent across periods.
- State noise, observation noise, and the initial state are mutually independent.
, , , and the design are known at the relevant time. With a random design, the stated independence assumptions must continue to hold conditional on that design. If a market input is correlated with a state shock, the current recursion does not automatically correct for that endogeneity. - The observation variance is positive, the covariance is positive semidefinite, and the innovation variance is invertible. With one scalar observation, the innovation variance is a positive scalar.
The conditional expectations below also assume that the model matrices and an appropriate exogenous observation design are given. In the dynamic-beta example, the current month’s market return
The Gaussian assumption ensures that each conditional distribution remains Gaussian, so the mean and covariance describe the full posterior. If the distribution is non-Gaussian, linear projection can still give a linear minimum mean-square-error estimate; the recursive quantities alone do not establish that the full posterior is Gaussian. The assumptions determine the scope of the conclusions.
6. Deriving one update from a conditional Gaussian distribution
First, let the state estimate through
6.1 Predict with the state equation
Substitute the state transition into the conditional mean:
Zero-mean, independent state noise does not change the predicted mean. Apply the linear-transformation rule to the covariance, then add the covariance of the independent noise:
This variance describes the model’s uncertainty about the state before this period’s return arrives.
6.2 Calculate the prior observation and innovation
The observation equation gives the prior observation mean
The conditional covariance between the state and observation, and the innovation variance, are
See the update weight through scalar precision
For a scalar prior with
The two information precisions add. Let
The convex weight is
Hold
| 0.01 | 0.0001 | 0.05 | 0.00012 | 8.333333 | 0.166667 | 1.083333 |
| 0.06 | 0.0001 | 0.10 | 0.00014 | 14.285714 | 0.285714 | 1.142857 |
| 0.01 | 0.0004 | 0.05 | 0.00042 | 2.380952 | 0.047619 | 1.023810 |
For this fixed positive design, increasing
6.3 Obtain the posterior from the conditional formula for a joint Gaussian
Conditional on the historical observations, the state and new observation have a joint Gaussian distribution:
Apply the conditional-mean and Schur-complement formulas for a partitioned Gaussian distribution to obtain
Define the Kalman gain
The mean can then be written as
The implementation uses the Joseph covariance update:
Under the model assumptions, this equals the conditional-covariance formula above; under finite-precision rounding, it better preserves symmetry and positive semidefiniteness. With one scalar observation,
7. Financial interpretation: two-dimensional alpha, beta, and a dynamic hedge ratio
Write the asset and market monthly excess simple returns as
Thus, the observation equation is
| Parameter | Value | Meaning |
|---|---|---|
| Initial mean |
Initial alpha is 0 and beta is 1 | |
| Initial covariance |
Initial state variances for alpha and beta | |
| Transition |
Alpha and beta means continue as random walks | |
| Process covariance |
Monthly state-change variance | |
| Observation variance |
Residual variance of monthly decimal returns |
These are teaching values specified in advance; the program does not estimate them from the full sample.
When
The state components have different units: alpha is a monthly decimal return, and beta is a dimensionless exposure. Alpha variance is measured in return squared, beta variance in beta squared, and their covariance in return times beta. Estimating the alpha state is not a test of whether a strategy’s alpha is statistically significant.
8. Calculating dynamic beta by hand: how one return updates the state
State prediction and return prediction use different clocks
| Timing | Quantity that can be computed | Quantity still unknown or unavailable for backfilling |
|---|---|---|
| Before the month | The current state shock and the full monthly asset and market returns | |
| When the month-end market factor |
This is not an asset-return forecast made before the month | |
| When the month-end asset return arrives | The innovation, filtered state, and next-month plan | The filtered state cannot change the position already held this month |
| After the sample ends | A smoothed historical estimate using future observations | It cannot be a real-time signal for the target month; smoothing is not implemented here |
To forecast an asset return before the month begins, you need to specify a conditional distribution for future
Return beta, price-regression coefficients, and share counts also need separate interpretations. If another model uses
9. Python implementation and execution
Default standalone entry point
From the root of the bundled reader package, create a separate environment using its environment instructions, then run:
.venv/bin/python run_notebook.py notebooks/ch19_state_space.ipynb
First check the prior, innovation, gain, and posterior for one scalar update. Then compare the two-dimensional alpha/beta conditional Gaussian formula with the core implementation term by term. The two-dimensional example specifies the prior covariance directly, uses an identity transition, and sets Q to 0; do not confuse it with the dynamic process parameters in Section 7.
Next, use seed 20261019 to construct a sample starting in 1980-01 and spanning 480 months. Draw the initial state from a Gaussian distribution with mean [0.001,0.9] and covariance diag(0.0001,0.04); set Q=diag(0.000004,0.00004) and R=0.0004; draw market returns from a Gaussian distribution with mean 0 and standard deviation 0.04. Each period, transition the latent state first and then generate the observation. Comparing the true Q filter with a filter whose beta process variance is zero gives one constructed path; retain the result in Section 18 where the misspecified filter has lower RMSE, and do not use it to recommend a model.
By default, the Notebook writes constructed_latent.csv and constructed_filter.csv to runs/ch19_state_space_<uuid>/. It displays the two simulated PNGs already included in fixtures/figures/a4/ and does not generate new images. The other two French figures and historical numbers in Sections 10–11 are frozen chapter reading material, not default-run outputs.
RUN_FRENCH=False; French data are not read or downloaded by default. Importing the chapter workflow does not run its historical market analysis. The chapter run directory is separate from the runner’s runs/execution_<uuid>/, which stores an execution copy and status. Assertions included in the package let readers check the constructed calculations; the production tests not included in the package do not need to be restored. Constructed results do not establish market predictability or a trading advantage after costs.
The CLI below follows the historical course-work root path and requires suitable, authorized data inputs and an environment; it does not replace the default command above.
Shared implementation and historical course-work path
The recursion is implemented by kalman_filter in the state-space core. The chapter script code/ch19_state_space.py reuses that function; it validates the frozen French data, runs a fixed-parameter analysis, and outputs tables and figures. The default Notebook above reuses the shared core and constructed-simulation branch, including the conditional-Gaussian check and hand-calculation assertions. The historical French analysis is handled separately by the CLI below.
The code below reproduces the example in Section 8; its outputs remain in beta and monthly decimal-return units:
import numpy as np
from quant_course.state_space import kalman_filter
result = kalman_filter(
observations=np.array([0.03]),
observation_design=np.array([[0.02]]),
initial_state=np.array([1.0]),
initial_covariance=np.array([[0.04]]),
transition=np.array([[1.0]]),
process_covariance=np.array([[0.01]]),
observation_variance=0.0001,
)
assert np.isclose(result.predicted_covariances[0, 0, 0], 0.05)
assert np.isclose(result.innovations[0], 0.01)
assert np.isclose(result.innovation_variances[0], 0.00012)
assert np.isclose(result.gains[0, 0], 8.333333333333333)
assert np.isclose(result.filtered_states[0, 0], 1.0833333333333333)
assert np.isclose(result.filtered_covariances[0, 0, 0], 0.04166666666666667)
You can run the CLI from any directory by using an absolute path. Put outputs in a new directory to preserve existing data and figures. The script does not download French data and checks the SHA-256 hashes of the six raw, extracted, and processed files. Overwriting results with the same names requires the explicit --overwrite option.
python /path/to/quant_course/code/ch19_state_space.py \
--output-dir /tmp/ch19-output \
--figure-dir /tmp/ch19-figures
The core API in this chapter uses fixed
10. Figures: viewing the state, innovation, and uncertainty

In Figure 1, the horizontal axis is the simulated month generated with fixed seed 20261019, and the vertical axis is dimensionless beta. The black line is the known latent beta; the blue line is filtered beta using the true

Figure 2 uses simulated months on the horizontal axis. The top panel’s vertical axis is monthly alpha in percent; the middle panel shows

Figure 3 uses target month on the horizontal axis and dimensionless beta on the vertical axis. Before each month begins, the blue line uses only earlier observations to obtain the Kalman prior; the red line is the OLS slope over the 60 months through the prior month. Both lines come from the same currently revised history. Their difference shows how parameters and windows change the estimate; it does not show that one method makes more money.

Figure 4 covers months from 2010-01 through 2026-08. The top panel’s vertical axis shows filtered alpha (monthly percent) and its conditional marginal
11. Real-market example: the French NoDur industry portfolio
The example uses monthly returns for the 10 industry portfolios and the three-factor file from the Kenneth R. French Data Library. NoDur is an industry portfolio, not an individual stock. The asset input is the NoDur monthly total return minus RF; the market input is Mkt-RF, which already subtracts RF, so the code does not subtract RF again. Returns are in decimals over calendar months.
The frozen download date is 2026-10-05, and the sample runs from 1926-07 through 2026-08, for 1,202 months. The analysis checks monthly continuity with the monthly-series reader and verifies six hashes in the local manifests for the raw ZIPs, extracted CSVs, and processed CSVs. See the French factor manifest and industry-data manifest. The processed industry CSV has SHA-256 3b097d810c295d64eedfa1ece7067ff2a0707f5ca90e33935df9949251f70950; the FF3 CSV has SHA-256 c19770a19a0ac47ad1c29074f57234570aeaa9725212cb4fa8146a2846c52814.
All initial states and
| Month | Kalman prior beta | Month-end filtered beta | Prior 60-month OLS beta |
|---|---|---|---|
| 2010-01 | 0.672096 | 0.672764 | 0.661122 |
| 2020-03 | 0.675173 | 0.683395 | 0.670480 |
| 2026-08 | 0.597956 | 0.596971 | 0.434646 |
By 2026-08, the month-end filtered beta is 0.596971, with a model-conditional standard deviation of about 0.03788. The prior beta for that month is 0.597956, and the rolling OLS beta is 0.434646. The filtered value and rolling slope use different state noise, windows, and shrinkage; this difference alone cannot tell us which estimate is closer to future exposure.
The data come from one currently revised version, without public timestamps or historical versions for each period. The analysis therefore makes no claim of point-in-time availability, a no-look-ahead strategy return, alpha outperformance, or actual hedge performance. The French Library page provides downloadable data; the local manifests do not record blanket permission for external redistribution. This chapter retains the source and hashes and does not repackage this snapshot.
12. Common mistakes
| Mistake | Problem | Correction |
|---|---|---|
| Treating |
The gain is measured in beta per return, not probability; the conversion ratio changes when the market return is small | Check the state units of |
| Using filtered beta to place an order at the start of the same month | Filtered beta uses that month’s asset and market returns | Use predicted beta before the month starts; update the next-period state after month-end |
| Treating a full-sample smoother as a historical signal | A smoothed state is conditional on observations after the target time | Use only filtered or predicted states for real-time signals |
| Subtracting RF a second time from Mkt-RF | The factor file already provides excess market returns | Subtract RF once from the NoDur total return only |
| Fitting |
The parameters absorb future sample information, creating leakage even if the recursion itself is causal row by row | Estimate parameters in a training window and freeze them out of sample or update them by a prespecified rule |
| Dropping a missing month and continuing the recursion | The number of state transitions becomes misaligned | Preserve the monthly index and specify a missing-data policy; this chapter’s function raises an error for a missing month or NaN |
| Treating a state interval as a test of alpha significance | The conditional variance includes only state uncertainty under the specified model | For an alpha test, handle parameter uncertainty, identification, and multiple selection separately |
13. Quant research application: testing whether a dynamic hedge ratio improves risk control
A narrow hypothesis to test is whether, with a tradable market proxy and a prespecified month-end timestamp, a market-neutral portfolio formed using the beta prior available before the month begins reduces out-of-sample risk or tracking error. This is a risk hypothesis, not a claim that beta filtering predicts market direction.
- Record the data source, release date, receipt time, return interval, and units. Confirm that the industry portfolio and market proxy can be traded at the specified weights.
- Choose a training window. Use only training data to estimate or specify the initial alpha and beta mean and covariance
, along with . Record the parameter choices, window, and selection rules, then freeze them for the test period. - At the end of period
, after receiving complete returns, save and use the state equation to generate the next period’s beta prior. Under the random-walk model, the mean satisfies . - Establish the hedge at an executable time and hold it through the month. At month-end, calculate the realized hedged-portfolio return from actual asset and market returns. Do not backfill the month-end filtered beta to the start of the month.
- Using the same training information, compare static OLS beta with rolling OLS beta over the prior 60 months. Report unhedged and hedged volatility, tail loss, turnover, transaction costs, and execution constraints.
- Repeat the process in later months. Check the mean, serial correlation, and tails of standardized innovations; test sensitivity to
; and explain how conclusions change under model misspecification.
Specify in advance what evidence would reject the hypothesis. For example, reject the claim that “this dynamic hedging approach reduces achievable risk” if out-of-sample risk does not improve or if the improvement disappears after turnover and costs. If PIT data, a historical market proxy, or a cost model is missing, report descriptive risk paths at most.
14. How the pieces fit together
The state transition carries the prior-period posterior into the current-period prior; the observation design maps the state to visible returns; the innovation measures the gap between the current observation and its prior; the innovation variance measures uncertainty in that gap; the gain adjusts the state based on its covariance with the observation; and the updated covariance carries post-observation uncertainty into the next period. The Gaussian and independent-noise assumptions let these means and variances describe the full conditional posterior.
In finance, the beta state provides a dynamic estimate for current-period risk. Whether an estimate can inform an order depends on whether it was available before the order. Conditional variance, parameter estimation, and strategy risk represent different sources of uncertainty and should be reported separately.
15. Exercises
Complete answers to every question appear in Section 18.
19-E01 (Concept) In the two-dimensional alpha/beta model, identify the state, observation, design vector, state noise, and observation noise. Which item can only be observed after month-end?
19-E02 (Dimensions and units) State the dimensions and units of
19-E03 (By hand) Let the previous-period posterior have
19-E04 (Interpretation) The Kalman gain in Section 8 is greater than 1. Explain its units and identify the error in interpreting it as a probability.
19-E05 (Information timing) Let
19-E06 (Assumptions) Market return
19-E07 (Distribution) If state and observation noise still have zero means and known covariances but are heavy-tailed, which conclusions remain valid as linear-projection recursions, and which claims about a “full Gaussian posterior” must be withdrawn?
19-E08 (Parameter leakage) A researcher uses all observations from 1926–2026 to choose
Added teaching questions (separately numbered)
19-R01 Precision derivation and boundary cases. Complete the square in a scalar Gaussian prior and observation density to write the posterior precision and mean. Why is the weight KH? What happens when H=0?
19-R02 Hand calculation comparing Q and R. Use the three rows in the Section 6 table to calculate each posterior variance. Explain why the same innovation produces different adjustments.
19-R03 Position and timing check. Hold 10 shares of an asset priced at 50, with the proxy priced at 100 and log-price coefficient b=1.2. How many shares are needed for the local hedge? If b is a filtered state at the end of the current month, can it determine the position for that month?
16. Programming exercises
19-P01 (Hand-calculation regression check) Use the core function to reproduce the Section 8 example. Assert the prior variance, innovation, innovation variance, gain, posterior beta, and posterior variance individually, with tolerance no greater than
19-P02 (Prefix causality) Construct 8 months of single-state data and save the filtered states for the first 5 months. Change only observations from month 6 onward and run the same filter with the same parameters. Assert that the first 5 filtered states are identical and that the final state in the changed segment differs.
19-P03 (Time boundaries) Give the dynamic-beta function a pair of continuous indexes with one month missing and a pair of monthly series containing NaN. Confirm that the function raises an error in both cases; do not drop the missing month and continue fitting.
17. Challenge questions
19-C01 (Unexpected ranking in a simulation) With fixed seed 20261019, use the accompanying script to generate 480 periods of latent alpha and beta. Compare the beta root-mean-square error (RMSE) and marginal model-interval coverage for a correctly specified filter using the true
19-C02 (Research design) Design a point-in-time dynamic-beta hedging evaluation for a real asset. Specify data versions, timestamps, parameter estimation, static and rolling benchmarks, return accounting, costs, and failure conditions. Explain how to avoid using the same month’s month-end filtered beta to backfill its position.
18. Exercise answers and derivations
19-E01
Let
19-E02
19-E03
Apply the first transition:
The expected observation is
The posterior mean is
The first prior mean is 2; skipping the transition would incorrectly give 1. This is why the first-step timing check uses
19-E04
The numerator
19-E05
19-E06
You cannot directly call this update the correct conditional posterior. Given the design, the derivation assumes that the state shock, observation error, and initial state are independent. If
19-E07
With linearity, finite second moments, and correct covariances, the mean and covariance recursions can still be interpreted as linear projections and error-covariance calculations. Heavy tails do not ensure that the conditional distribution remains Gaussian, so these values cannot be claimed to describe the full posterior density; an interval of
19-E08
Leakage occurs in the model selection for
19-P01 through 19-P03
Run the following Python program from the repository root with PYTHONPATH=src python -. The first block checks the hand calculation, the second changes only the future suffix, and the third checks missing-month and NaN boundaries.
import numpy as np
import pandas as pd
from quant_course.state_space import kalman_filter, dynamic_beta_filter
# 19-P01: Hand-check the scalar beta update.
manual = kalman_filter(
[0.03], [[0.02]], initial_state=[1.0],
initial_covariance=[[0.04]], transition=[[1.0]],
process_covariance=[[0.01]], observation_variance=0.0001,
)
actual = [
manual.predicted_covariances[0, 0, 0],
manual.innovations[0],
manual.innovation_variances[0],
manual.gains[0, 0],
manual.filtered_states[0, 0],
manual.filtered_covariances[0, 0, 0],
]
expected = [0.05, 0.01, 0.00012, 8.333333333333333,
1.0833333333333333, 0.04166666666666667]
np.testing.assert_allclose(actual, expected, rtol=0, atol=1e-12)
# 19-P02: Changes to future observations must not rewrite past filtered states.
y = np.arange(8, dtype=float) / 10
h = np.ones((8, 1))
kwargs = dict(
initial_state=[0.0], initial_covariance=[[1.0]],
transition=[[1.0]], process_covariance=[[0.02]],
observation_variance=0.3,
)
original = kalman_filter(y, h, **kwargs)
changed_y = y.copy()
changed_y[5:] += 100
changed = kalman_filter(changed_y, h, **kwargs)
np.testing.assert_allclose(original.filtered_states[:5],
changed.filtered_states[:5], rtol=0, atol=0)
assert not np.allclose(original.filtered_states[5:],
changed.filtered_states[5:])
# 19-P03: Do not compress missing months or silently accept NaN.
months = pd.period_range("2025-01", periods=3, freq="M")
market = pd.Series([0.01, 0.02, -0.01], index=months)
asset = pd.Series([0.02, 0.01, 0.00], index=months)
parameters = dict(
initial_beta=1.0, initial_variance=0.04,
process_variance=0.01, observation_variance=0.0001,
)
for bad_asset, bad_market in [
(asset.drop(months[1]), market.drop(months[1])),
(asset.copy().where(pd.Series([True, False, True], index=months)), market),
]:
try:
dynamic_beta_filter(bad_asset, bad_market, **parameters)
except (TypeError, ValueError):
pass
else:
raise AssertionError("expected invalid monthly input to be rejected")
19-C01
The script uses a fixed seed to generate 480 periods, known latent states, and two sets of filtered results. The historical constructed run produced beta RMSE
You cannot use this to recommend
19-C02
An acceptable research plan should provide a checkable record for every timestamp:
- Record the data source, release version, availability time for each row, sample period, currency, return definition, missing-data treatment, and hash. Use price series that represent a tradable market; French factors can serve as a statistical benchmark but do not guarantee that a corresponding tradable product exists.
- Estimate or select
in the training window and freeze them together with the window and hyperparameter grid. Also specify a static training-period OLS benchmark and a rolling OLS benchmark over the prior 60 months. During testing, read only versions available at the time. - At the end of period
, calculate and record . Hold the hedge at this weight from the next month’s first executable time. Record actual asset returns, market returns, and costs for month t in month t’s P&L. The computed only at month-end can affect positions in t+1 or later. - Report unhedged and hedged returns, volatility, tail risk, beta residuals, turnover, stock-borrowing/financing/market-impact costs, and data and execution limits for each weighting rule. Tune parameters only within rolling training windows.
- Without PIT history, do not describe a currently revised history as a genuine historical backtest. If the market proxy cannot be traded at the target weight, or risk does not fall after costs, reject the claim of achievable risk improvement.
A suitable conclusion could be “This parameterization has better risk metrics than the benchmark in the available sample, but the difference is sensitive to
Full answers to the added teaching questions
19-R01. Given a scalar Gaussian prior with
The exponent of the prior density times the observation density is
The linear coefficient in the quadratic is
The first hand example gives
19-R02. Calculate
19-R03. The local share count is -1.2×10×50/100=-6 shares; writing -12 shares confuses notional with share count. Local log-price sensitivity is not automatically return beta. A month-end filtered state can be used at a later executable time after the next state transition; it cannot be backfilled into the current month.
19. Further reading
- Must Know: Kalman (1960), read pp. 35–45 of the original paper for the problem statement, state recursion, and Theorem 3. The paper uses early notation and a specific measurement setup; the scalar observation-error formula in this chapter is derived from the conditional distribution of a joint Gaussian and does not attribute every modern implementation to that paper.
- Must Know: statsmodels 0.15.0, Time Series Analysis by State Space Methods. Read the matrix names and dimensions in the general state-space form, the lower-order state-space models, and the distinction between KalmanFilter and KalmanSmoother.
- Should Know: the local state-space core and chapter Notebook. Recalculate this chapter’s examples in prior, innovation, and update order, then inspect the time-index validation.
- Advanced: the official statsmodels state-space chapters on custom models, initialization, likelihood, and result objects. This chapter does not include parameter-estimation or smoother code; as you read further, watch for differences between software conventions and this chapter’s notation.
20. References and source scope
- CH19_KALMAN1960: R. E. Kalman, “A New Approach to Linear Filtering and Prediction Problems,” Journal of Basic Engineering, 82(1), 35–45, 1960. DOI: 10.1115/1.3662552. See source_notes.md for the reading scope, mirror notes, and claims supported by this source.
- CH19_STATSMODELS: statsmodels 0.15.0, Time Series Analysis by State Space Methods. This chapter follows its model overview and maps the differing notation in the text.
- FRENCH: Kenneth R. French Data Library, 10 Industry Portfolios and Fama/French Factors. The actual snapshots and input hashes are recorded in two local manifests; see source_notes.md for the reading scope.