mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-11-08 18:32:21 +00:00
158 lines
5.2 KiB
Python
158 lines
5.2 KiB
Python
"""Econometrics data tools - correlation matrix and descriptive statistics."""
|
|
|
|
from typing import Literal
|
|
|
|
from openbb_core.app.model.example import APIEx, PythonEx
|
|
from openbb_core.app.model.obbject import OBBject
|
|
from openbb_core.app.router import Router
|
|
from openbb_core.provider.abstract.data import Data
|
|
from openbb_core.provider.abstract.query_params import QueryParams
|
|
from pydantic import Field, PositiveInt
|
|
|
|
router = Router(
|
|
prefix="", description="Econometrics correlation and descriptive tools."
|
|
)
|
|
|
|
|
|
class CorrelationMatrixQueryParams(QueryParams):
|
|
"""Query parameters for the correlation matrix endpoint."""
|
|
|
|
__category__ = "tools"
|
|
__output_columns__ = ("comp_to",)
|
|
|
|
data: list[Data] = Field(description="Input dataset.")
|
|
method: Literal["pearson", "kendall", "spearman"] = Field(
|
|
default="pearson",
|
|
description="Correlation method: 'pearson' (standard), 'kendall' (Kendall Tau),"
|
|
+ " or 'spearman' (rank correlation).",
|
|
)
|
|
min_periods: PositiveInt = Field(
|
|
default=1,
|
|
description="Minimum number of observations required per pair of columns"
|
|
+ " to compute a correlation.",
|
|
)
|
|
|
|
|
|
class CorrelationMatrixData(Data):
|
|
"""One row of the correlation matrix."""
|
|
|
|
comp_to: str = Field(
|
|
description="The variable each correlation in the row is measured against."
|
|
)
|
|
|
|
|
|
class SummaryStatisticsQueryParams(QueryParams):
|
|
"""Query parameters for the summary statistics endpoint."""
|
|
|
|
__category__ = "tools"
|
|
__output_columns__ = (
|
|
"column",
|
|
"count",
|
|
"mean",
|
|
"std",
|
|
"min",
|
|
"p25",
|
|
"median",
|
|
"p75",
|
|
"max",
|
|
"skew",
|
|
"kurtosis",
|
|
)
|
|
|
|
data: list[Data] = Field(description="Input dataset.")
|
|
|
|
|
|
class SummaryStatisticsData(Data):
|
|
"""Descriptive statistics for a single numeric column."""
|
|
|
|
column: str = Field(description="Name of the column.")
|
|
count: int = Field(description="Number of non-null observations.")
|
|
mean: float = Field(description="Arithmetic mean.")
|
|
std: float = Field(description="Sample standard deviation.")
|
|
min: float = Field(description="Minimum value.")
|
|
p25: float = Field(description="25th percentile.")
|
|
median: float = Field(description="Median (50th percentile).")
|
|
p75: float = Field(description="75th percentile.")
|
|
max: float = Field(description="Maximum value.")
|
|
skew: float = Field(description="Skewness of the distribution.")
|
|
kurtosis: float = Field(description="Excess kurtosis of the distribution.")
|
|
|
|
|
|
@router.command(
|
|
methods=["POST"],
|
|
examples=[
|
|
PythonEx(
|
|
description="Get the correlation matrix of a dataset.",
|
|
code=[
|
|
"stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp').to_df()", # noqa: E501
|
|
"obb.econometrics.correlation_matrix(data=stock_data)",
|
|
],
|
|
),
|
|
APIEx(parameters={"data": APIEx.mock_data("timeseries")}),
|
|
],
|
|
)
|
|
def correlation_matrix(
|
|
params: CorrelationMatrixQueryParams,
|
|
) -> OBBject[list[CorrelationMatrixData]]:
|
|
"""Get the correlation matrix of an input dataset.
|
|
|
|
The correlation matrix shows how strongly the variables in the dataset move in
|
|
relation to one another. Scores range from -1 (perfect negative correlation) through
|
|
0 (no correlation) to 1 (perfect positive correlation).
|
|
"""
|
|
import numpy as np
|
|
from openbb_core.app.utils import basemodel_to_df
|
|
|
|
df = basemodel_to_df(params.data)
|
|
|
|
if "symbol" in df.columns and len(df.symbol.unique()) > 1 and "close" in df.columns:
|
|
df = df.pivot(columns="symbol", values="close")
|
|
|
|
corr = df.corr(
|
|
method=params.method, min_periods=params.min_periods, numeric_only=True
|
|
).replace(np.nan, None)
|
|
|
|
results = []
|
|
for key, series in corr.items():
|
|
row = series.to_dict()
|
|
row["comp_to"] = str(key)
|
|
results.append(CorrelationMatrixData.model_validate(row))
|
|
|
|
return OBBject(results=results)
|
|
|
|
|
|
@router.command(
|
|
methods=["POST"],
|
|
examples=[APIEx(parameters={"data": APIEx.mock_data("timeseries")})],
|
|
)
|
|
def summary_statistics(
|
|
params: SummaryStatisticsQueryParams,
|
|
) -> OBBject[list[SummaryStatisticsData]]:
|
|
"""Compute descriptive summary statistics for each numeric column.
|
|
|
|
Returns per-column count, mean, standard deviation, minimum, quartiles, maximum,
|
|
skewness, and excess kurtosis - a quick overview of each variable's distribution.
|
|
"""
|
|
from openbb_core.app.utils import basemodel_to_df
|
|
|
|
df = basemodel_to_df(params.data).select_dtypes(include="number")
|
|
|
|
results = [
|
|
SummaryStatisticsData(
|
|
column=str(column),
|
|
count=int(df[column].count()),
|
|
mean=float(df[column].mean()),
|
|
std=float(df[column].std()),
|
|
min=float(df[column].min()),
|
|
p25=float(df[column].quantile(0.25)),
|
|
median=float(df[column].median()),
|
|
p75=float(df[column].quantile(0.75)),
|
|
max=float(df[column].max()),
|
|
skew=float(df[column].skew()),
|
|
kurtosis=float(df[column].kurtosis()),
|
|
)
|
|
for column in df.columns
|
|
]
|
|
|
|
return OBBject(results=results)
|