Repository: OpenBB-finance/OpenBBTerminal
File: openbb_terminal/econometrics/econometrics_model.py (Python)

Code before:
        result[f"{x.name}/{y.name}"] = [c, gamma, alpha, adfstat, pvalue]
        z_values[f"{x.name}/{y.name}"] = z

    if result and z_values:
        if return_z:
            return z_values
        df = pd.DataFrame.from_dict(
            result,
            orient="index",
            columns=["Constant", "Gamma", "Alpha", "Dickey-Fuller", "P Value"],
        )
        return df
    return pd.DataFrame()


@log_start_end(log=logger)
def get_returns(data: pd.Series):
    """Calculate returns for the given time series

    Parameters
    ----------
    data: pd.Series
        The data series to calculate returns for
    """
    return 100 * data.pct_change().dropna()


@log_start_end(log=logger)
def get_garch(
    data: pd.Series,
    p: int = 1,
    o: int = 0,
    q: int = 1,
    mean: str = "constant",
    horizon: int = 100,
):
    r"""Calculates annualized volatility forecasts based on GARCH.

    GARCH (Generalized autoregressive conditional heteroskedasticity) is stochastic model for time series,
    which is for instance used to model volatility clusters, stock return and inflation. It is a
    generalisation of the ARCH models.

    $ GARCH(p, q)  = (1 - \alpha - \beta) \sigma_l + \sum_{i=1}^q \alpha u_{t-i}^2 + \sum_{i=1}^p \beta \sigma_{t-i}^2
    $ [1]

    The GARCH-model assumes that the variance estimate consists of 3 components:
    - $ \sigma_l $; the long term component, which is unrelated to the current market conditions
    - $ u_t $; the innovation/discovery through current market price changes
    - $ \sigma_t $; the last estimate

    GARCH can be understood as a model, which allows to optimize these 3 variance components to the time series.

Review comment (suggestion):
This should include an example of how to use in the sdk.

Also technically not annualized since we get rid of the sqrt

Code after:
            orient="index",
            columns=["Constant", "Gamma", "Alpha", "Dickey-Fuller", "P Value"],
        )
        return df
    return pd.DataFrame()


def get_returns(data: pd.Series):
    """Calculate returns for the given time series

    Parameters
    ----------
    data: pd.Series
        The data series to calculate returns for
    """
    return 100 * data.pct_change().dropna()


def get_garch(
    data: pd.Series,
    p: int = 1,
    o: int = 0,
    q: int = 1,
    mean: str = "constant",
    horizon: int = 100,
):
    r"""Calculates volatility forecasts based on GARCH.

    GARCH (Generalized autoregressive conditional heteroskedasticity) is stochastic model for time series,
    which is for instance used to model volatility clusters, stock return and inflation. It is a
    generalisation of the ARCH models.

    $ GARCH(p, q)  = (1 - \alpha - \beta) \sigma_l + \sum_{i=1}^q \alpha u_{t-i}^2 + \sum_{i=1}^p \beta \sigma_{t-i}^2
    $ [1]

    The GARCH-model assumes that the variance estimate consists of 3 components:
    - $ \sigma_l $; the long term component, which is unrelated to the current market conditions
    - $ u_t $; the innovation/discovery through current market price changes
    - $ \sigma_t $; the last estimate

    GARCH can be understood as a model, which allows to optimize these 3 variance components to the time series.
    This is done assigning weights to variance components: $ (1 - \alpha - \beta) $ for $ \sigma_l $, $ \alpha $ for
    $ u_t $ and $ \beta $ for $ \sigma_t $. [2]

    The weights can be estimated by iterating over different values of $ (1 - \alpha - \beta) \sigma_l $ which we
    will call $ \omega $, $ \alpha $ and $ \beta $, while maximizing: $ \sum_{i} -ln(v_i) - (u_i ^ 2) / v_i $.
    With the constraints:
    - $ \alpha > 0 $
    - $ \beta > 0 $
    - $ \alpha + \beta < 1 $
    Note that there is no restriction on $ \omega $.