Generalised Least Squares (GLS)
Fit a Generalized Least Squares (GLS) regression of dependent_ticker on independent_tickers, given a known error covariance structure omega.
GLS generalises WLS to an arbitrary error covariance matrix Var(e) = sigma^2 * Omega. Where WLS only corrects for heteroskedasticity (a diagonal Omega), GLS also corrects for correlation between the errors of different observations, such as the autocorrelation that is common in financial time series (a non-diagonal Omega).
The formula is as follows:
\[\text{betâ} = (\text{X'Ω⁻¹X}) \text{⁻¹X'Ω⁻¹y}\] \[\operatorname{Cov}(\text{betâ}) = \text{sigmâ} ^{2} \cdot (\text{X'Ω⁻¹X}) \text{⁻¹},\;\; \text{with}\; \text{sigmâ} ^{2} = \text{e'Ω⁻¹e} / (n - k)\]- y is the dependent ticker’s
column(Return by default) and X the independent tickers’columnplus a constant (add_constant=True)
Under a correctly specified Omega this is the most efficient linear unbiased estimator. By default (omega=”ar1”) Omega is estimated from the regression itself as an AR(1) error structure, eₜ = ρ·eₜ₋₁ + uₜ: ρ is the slope of the OLS residuals on their own lag and Ωᵢⱼ = ρ^|i - j|, which makes this the Prais-Winsten estimator. Any other structure can be supplied as omega. get_durbin_watson_test helps establish whether the residuals are autocorrelated in the first place.
For more information about the method, see the following paper:
- Aitken, A.C. (1935). “On Least Squares and Linear Combinations of Observations.” Proceedings of the Royal Society of Edinburgh, 55, 42-48.
- Prais, S.J. and Winsten, C.B. (1954). “Trend Estimators and Serial Correlation.” Cowles Commission Discussion Paper No. 383.
Also known as: GLS, Prais-Winsten.
Generalised Least Squares (GLS) in Python or via the MCP
Install the Finance Toolkit with:
pip install financetoolkit -U
Then call get_gls as shown below.
from financetoolkit import Toolkit
toolkit = Toolkit(
["AAPL", "MSFT"],
api_key="FINANCIAL_MODELING_PREP_KEY",
start_date="2021-01-01",
end_date="2025-12-31",
)
# AAPL (the first ticker) is dependent, MSFT is independent; Omega is estimated (AR(1))
toolkit.econometrics.get_gls(period="weekly")
Or, after setting up the Finance Toolkit MCP, ask:
How sensitive were Apple's weekly returns to Microsoft's from 2021 to 2025, according to a generalized least squares regression?
Which returns:
| Coefficient | Std. Error | t-Statistic | P-Value | |
|---|---|---|---|---|
| Intercept | 0.0012 | 0.0017 | 0.7282 | 0.4671 |
| MSFT | 0.6312 | 0.0576 | 10.9557 | 0 |
Using Your Own Data
get_gls runs on any data, not only prices: ratios, economic indicators, yield curves or your own dataset. Pass a DataFrame, a Series or a dictionary of them to Econometrics as data, with the dates in the rows or the columns, and set changes to how its changes are calculated: "percentage", "log", "difference" for rates and ratios, or None when the data are changes already. For example, for the monthly unemployment rates of the United States and Germany:
from financetoolkit import Economics, Econometrics
economics = Economics(start_date="2000-01-01")
unemployment = economics.get_unemployment_rate(
countries=["United States", "Germany"], period="monthly"
)
econometrics = Econometrics(data=unemployment, changes="difference")
econometrics.get_gls()
Parameters
get_gls accepts the following parameters.
| Parameter | Type | Description | Example |
|---|---|---|---|
omega | pd.DataFrame | str | The (symmetric, positive-definite) error covariance structure, up to a scalar, shape (n, n), or “ar1” to estimate an AR(1) structure from the regression’s own residuals (Prais-Winsten). Defaults to “ar1”. | "ar1" |
dependent_ticker | str | None | The dependent (predicted) asset. Defaults to None, meaning the Toolkit instance’s first ticker. | "AAPL" |
independent_tickers | str | list[str] | None | The independent (predictor) asset(s). Defaults to None, meaning every other ticker in the Toolkit instance besides dependent_ticker. | ["MSFT", "Benchmark"] |
include_benchmark | bool | Whether to include “Benchmark” in the default independent ticker(s) (has no effect when independent_tickers is given explicitly). Defaults to False. | True |
period | str | The data frequency (daily, weekly, monthly, quarterly, or yearly). Defaults to “daily”. | "weekly" |
column | str | The historical data column to regress on. Defaults to “Return”. | "Return" |
add_constant | bool | Whether to include an intercept. Defaults to True. | False |
rounding | int | None | The number of decimals to round the results to. Defaults to None. | 2 |