- The Granger Causality test asks a precise, falsifiable question: does knowing the history of series X improve your ability to predict series Y, bey...
- **Similar:** [Cointegration](../cointegration/Cointegration.md), [Correlation](../correlation/Correlation.md) | **Trading note:** Granger causality test; determines if one time series can forecast another. Lead-lag detection.
The Granger Causality test asks a precise, falsifiable question: does knowing the history of series X improve your ability to predict series Y, beyond what Y's own history already provides? The answer arrives as an F-statistic from comparing two OLS regression models. Higher F means X contains predictive information about Y that Y itself does not. This implementation uses lag-1, runs in O(1) streaming mode via running sums, and handles bar corrections for live trading.
## Historical Context
Clive Granger introduced this test in 1969, later refined in Granger (1980). The key insight: "causality" here means temporal predictive precedence, not physical causation. The test became a workhorse in econometrics for testing lead-lag relationships between economic variables, exchange rates, and commodity prices. In trading, it identifies which instruments lead others, informing pairs trading, cross-asset signals, and regime detection.
Standard implementations require batch matrix operations. This implementation maintains running statistics for O(1) per-bar updates, matching the batch result exactly while supporting streaming and bar correction.
## Architecture and Physics
### 1. Dual-Input Streaming Design
The indicator takes two series: Y (dependent, the series you want to predict) and X (independent, the hypothesized cause). At each bar, it maintains three parallel ring buffers storing the lagged triplet (y_t, y_{t-1}, x_{t-1}) over a rolling window of size `period`.
### 2. Running Sum Statistics
Nine running sums track means, variances, and cross-covariances:
-`sumY`, `sumYLag`, `sumXLag` for means
-`sumYY`, `sumYLagYLag`, `sumXLagXLag` for variances
-`sumYYLag`, `sumYXLag`, `sumYLagXLag` for covariances
These enable O(1) updates: subtract the oldest triplet, add the newest. Periodic resync every 1000 bars corrects floating-point drift.
### 3. Bar Correction via isNew
When `isNew=false`, the indicator restores the previous state snapshot and replaces the newest triplet in all buffers and running sums. This handles tick updates within the same bar without re-processing the entire window.
where $q = 1$ (one restriction: $d_2 = 0$) and $k = 3$ (unrestricted model parameters). The F-statistic follows an $F(1, N-3)$ distribution under the null hypothesis that X does not Granger-cause Y.
O(L·N) per update where L = number of lags, N = period. Heavy enough that batch mode (pre-computing all bars at once) is preferred for historical analysis.
| SIMD potential | Low (recursive lag dependency) |
| Warmup period | period + 1 |
### Quality Metrics
| Metric | Score (1-10) |
| :--- | :--- |
| Responsiveness | 7 |
| Smoothness | 5 |
| Lag | 3 (inherent from windowed regression) |
| Noise rejection | 6 |
| Interpretability | 8 (F-statistic, compare to critical values) |
## Validation
This indicator validates against statistical properties rather than external TA libraries, as Granger causality is not commonly found in standard TA packages.
| Test | Description | Result |
| :--- | :--- | :--- |
| Causal relationship | Y = f(Y_lag, X_lag) + noise | F > 0, high |
| Independent series | Two independent GBMs | F finite, generally low |
| Asymmetric detection | X causes Y but Y does not cause X | F(Y,X) > F(X,Y) |
| Batch vs streaming | TSeries batch matches streaming | Exact match |
| Span vs streaming | Span API matches streaming | Exact match |
| Bar correction | isNew=false restores state | Values match |
## Common Pitfalls
1.**Not true causation.** Granger causality tests temporal precedence in prediction, not physical causation. A spurious correlation with a lagged third variable can produce high F.
2.**Period too small.** Period must exceed 3 for the F-statistic to have positive degrees of freedom. Small periods amplify noise. Use 20+ for meaningful results.
3.**Constant or near-constant series.** Zero variance in the lag produces NaN (division by zero in OLS). This is mathematically correct behavior.
4.**Multicollinearity.** If y_lag and x_lag are nearly perfectly correlated, the denominator D approaches zero, producing NaN. This indicates the two predictors carry redundant information.
5.**Confusing direction.** F(Y,X) tests whether X helps predict Y. F(X,Y) tests the reverse. Always verify which direction matters for your trading thesis.
6.**Critical values depend on sample size.** For F(1, N-3): at 5% significance, critical value is approximately 4.0 for N=20, declining toward 3.84 for large N.
7.**Floating-point drift.** Running sums accumulate rounding errors over thousands of bars. The built-in resync every 1000 bars limits this to negligible levels.
## References
- Granger, C.W.J. (1969). "Investigating Causal Relations by Econometric Models and Cross-spectral Methods." Econometrica, 37(3), 424-438.
- Granger, C.W.J. (1980). "Testing for Causality: A Personal Viewpoint." Journal of Economic Dynamics and Control, 2, 329-352.
- Hamilton, J.D. (1994). Time Series Analysis. Princeton University Press. Chapter 11.