Files
OpenBB/openbb_platform/extensions/econometrics/tests/test_diagnostics.py
Danglewood 35aacde541 refactor econometrics for v5 (#7505)
Co-authored-by: deeleeramone <>
2026-06-01 19:12:06 +03:00

117 lines
4.1 KiB
Python

"""Tests for ``openbb_econometrics.diagnostics`` - regression diagnostics."""
from openbb_econometrics import diagnostics
X_COLUMNS = ["open", "high", "low"]
def test_autocorrelation(timeseries_data):
"""The Durbin-Watson statistic lies in the [0, 4] range."""
out = diagnostics.autocorrelation(
diagnostics.AutocorrelationQueryParams(
data=timeseries_data, y_column="close", x_columns=X_COLUMNS
)
)
result = out.results
dumped = result.model_dump()
assert 0.0 <= dumped["durbin_watson"] <= 4.0
def test_residual_autocorrelation(timeseries_data):
"""The Breusch-Godfrey test returns LM and F statistics with p-values."""
out = diagnostics.residual_autocorrelation(
diagnostics.ResidualAutocorrelationQueryParams(
data=timeseries_data,
y_column="close",
x_columns=X_COLUMNS,
lags=2,
)
)
dumped = out.results.model_dump()
assert 0.0 <= dumped["lm_p_value"] <= 1.0
assert 0.0 <= dumped["f_p_value"] <= 1.0
assert isinstance(dumped["lm_statistic"], float)
assert isinstance(dumped["f_statistic"], float)
def test_residual_autocorrelation_default_lags(timeseries_data):
"""The ``lags`` parameter defaults to 1."""
params = diagnostics.ResidualAutocorrelationQueryParams(
data=timeseries_data, y_column="close", x_columns=X_COLUMNS
)
assert params.lags == 1
out = diagnostics.residual_autocorrelation(params)
assert out.results.lm_statistic is not None
def test_heteroskedasticity(timeseries_data):
"""The heteroskedasticity command returns Breusch-Pagan and White results."""
params = diagnostics.HeteroskedasticityQueryParams(
data=timeseries_data, y_column="close", x_columns=X_COLUMNS
)
assert params.robust is True
out = diagnostics.heteroskedasticity(params)
dumped = out.results.model_dump()
for prefix in ("breusch_pagan", "white"):
assert 0.0 <= dumped[f"{prefix}_lm_p_value"] <= 1.0
assert 0.0 <= dumped[f"{prefix}_f_p_value"] <= 1.0
assert isinstance(dumped[f"{prefix}_lm_statistic"], float)
assert isinstance(dumped[f"{prefix}_f_statistic"], float)
def test_heteroskedasticity_non_robust(timeseries_data):
"""The heteroskedasticity command accepts the non-robust Breusch-Pagan variant."""
out = diagnostics.heteroskedasticity(
diagnostics.HeteroskedasticityQueryParams(
data=timeseries_data,
y_column="close",
x_columns=X_COLUMNS,
robust=False,
)
)
dumped = out.results.model_dump()
assert 0.0 <= dumped["breusch_pagan_lm_p_value"] <= 1.0
def test_normality(timeseries_data):
"""The Jarque-Bera normality test returns a statistic and p-value."""
out = diagnostics.normality(
diagnostics.NormalityQueryParams(
data=timeseries_data, y_column="close", x_columns=X_COLUMNS
)
)
dumped = out.results.model_dump()
assert dumped["jarque_bera"] >= 0.0
assert 0.0 <= dumped["p_value"] <= 1.0
assert isinstance(dumped["skew"], float)
assert isinstance(dumped["kurtosis"], float)
def test_variance_inflation_factor_with_columns(timeseries_data):
"""VIF with an explicit ``columns`` list returns one row per requested column."""
out = diagnostics.variance_inflation_factor(
diagnostics.VarianceInflationFactorQueryParams(
data=timeseries_data, columns=X_COLUMNS
)
)
results = out.results
assert {row.variable for row in results} == set(X_COLUMNS)
for row in results:
assert row.model_dump()["vif"] > 0.0
def test_variance_inflation_factor_without_columns(timeseries_data):
"""Without ``columns`` VIF uses every numeric column in the dataset."""
params = diagnostics.VarianceInflationFactorQueryParams(data=timeseries_data)
assert params.columns is None
out = diagnostics.variance_inflation_factor(params)
# open/high/low/close/volume.
assert len(out.results) == 5
assert {row.variable for row in out.results} == {
"open",
"high",
"low",
"close",
"volume",
}