From 33da518dfabdae00c682306048b8f99f2e26b1ee Mon Sep 17 00:00:00 2001 From: DidierRLopes Date: Wed, 10 May 2023 07:22:56 -0700 Subject: [PATCH 1/2] Create KEYBOARD_HOTKEY_MACROS.md (#4986) * Create KEYCHRON_MACROS.md * Update KEYCHRON_MACROS.md * Update KEYCHRON_MACROS.md * Update KEYCHRON_MACROS.md * Update KEYCHRON_MACROS.md * Update KEYCHRON_MACROS.md * Update and rename KEYCHRON_MACROS.md to KEYBOARD_HOTKEY_MACROS.md * Update KEYBOARD_HOTKEY_MACROS.md * Update KEYBOARD_HOTKEY_MACROS.md --------- Co-authored-by: James Maslek Co-authored-by: Henrique Joaquim --- KEYBOARD_HOTKEY_MACROS.md | 76 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 KEYBOARD_HOTKEY_MACROS.md diff --git a/KEYBOARD_HOTKEY_MACROS.md b/KEYBOARD_HOTKEY_MACROS.md new file mode 100644 index 00000000000..b863effaa2d --- /dev/null +++ b/KEYBOARD_HOTKEY_MACROS.md @@ -0,0 +1,76 @@ +# Keyboard Hotkey Macros + +This document will explain how you can set hotkeys macros on your customizable keyboard which allow you to perform investment research in a few seconds. + +## Introduction to Routines + +The OpenBB Terminal is a powerful open source investment research platform. + +The more proefficient you get on the platform, the faster and more efficiently you are able to do investment research. + +One of the concepts that OpenBB introduced early on was the concept of script routines. Read more [here](https://docs.openbb.co/terminal/usage/guides/scripts-and-routines). + +**TL;DR: You can create MACROS like in Excel to run a sequence of commands.** + +E.g. by running `exe script.openbb` the following sequence could be executed + +```shell +stocks/load AAPL/candle --ma 20/fa/epsfc/pt/est +``` + +which would lead to: + +![image](https://user-images.githubusercontent.com/25267873/236659876-e119c820-b9ed-40e7-bb8d-5510fe862149.png) + +This allows to automate the process of investment research, and can improve user's experience by a significant margin. + +## Supported Configurators + +1. [VIA](#via) + +## VIA + +This document will explain how you can set hotkeys on your customizable keyboard using [VIA](https://www.caniusevia.com/). + +Here is a list of VIA's supported keyboards: [https://www.caniusevia.com/docs/supported_keyboards](https://www.caniusevia.com/docs/supported_keyboards) + +Note: We were in the market looking for a keyboard that could be highliy customizable for the needs of OpenBB power users. This is when we stumbled upon Keychron and the VIA configurator which allows users to intuitively remap any key on the keyboard, and create numerous macro commands, shortcuts, or key combinations. +Here's a post from Keychron on VIA: [Why VIA is one of the most essential features for a custom keyboard?](https://www.keychron.com/blogs/news/why-qmk-via-is-one-of-the-most-essential-features-for-a-custom-keyboard) + +For the purpose of this example, the command pipeline we are creating has the following sequence of commands: `dps/psi/../fa/pt/income/..` + +1. Try VIA [here](https://usevia.app/). The following screen should popup + + Screenshot 2023-05-06 at 11 10 51 PM + +2. Select the Layer you are interested in altering. As we're not looking forward to remap any of the existing main keys, we need to go to layer 2, 3 or 4. In my case, with a Keychron Q2, I know that Layer 4 can be accessed by pressing on "Fn2". Thus, I select that layer. + + Screenshot 2023-05-06 at 11 10 06 PM + +3. Most keys should have a triangle upside down which simbolizes that they don't have any functionality. You want to select one of those keys to contain your hotkey routine. After that selection you want to remap the key functionality, hence in the **KEYMAP settings** below you click on MACROS tab and select "MO". Now the screen should look like this: + + Screenshot 2023-05-06 at 11 13 43 PM + +4. Now we want to change what "MO" does and for that we select the **MACROS settings** below. Then we can select "M0" and insert `dps/psi/../fa/pt/income/..{KC_ENT}`. The screen should look like this: + + Screenshot 2023-05-06 at 11 17 52 PM + + Note that the `{KC_ENT}` will ensure that the command is run on the terminal. + +5. Save. To ensure that everything is correct you can go into the **KEYMAP settings** and click on the hotkey that you just created to see if it contains the sequence of commands, the following sequence should appear: + + Screenshot 2023-05-06 at 11 20 24 PM + +6. Finally, we are ready to test it on the [OpenBB Terminal](https://my.openbb.co/app/terminal). After going into `stocks` and doing `load AAPL`, I pressed "Fn2'+Z which lead to: + + Screenshot 2023-05-06 at 10 53 49 PM + +PS: If you prefer to see this in video format, you can do so by checking the following video. + +

+ + Didier demonstrating Keychron x OpenBB + +

+ +Hope you enjoy this tutorial, and please let us know what type of MACROS are you setting up. From bde21f033e5dcc3871d7c332577477bf1e03fc5c Mon Sep 17 00:00:00 2001 From: northern-64bit <75195383+northern-64bit@users.noreply.github.com> Date: Wed, 10 May 2023 16:30:36 +0200 Subject: [PATCH 2/2] Adding GARCH (#4815) * Add GARCH * Linting * Rearrange the econometrics menu * Add integration test * Add ret command + fixes * Fix linting * Fix linting * Fix pylint * Add logger to functions * bump pywry * fix rm command (#4890) Co-authored-by: Henrique Joaquim * Fix `crypto/defi/anchor` (#4892) * handle defi anchor exceptions * reason * mypy --------- Co-authored-by: Henrique Joaquim * fix windows pyinstaller subprocess fail if space in path * remove API_IEX_TOKEN * remove API_SENTIMENTINVESTOR_TOKEN * Convert to latex + requested changes * Fix linting * Remove unnecessary logger * Add example * SDK updated * fix syntax on elite level math that I def know * Fix docstring * Fix example * Fix * Linting --------- Co-authored-by: James Maslek Co-authored-by: teh_coderer Co-authored-by: montezdesousa <79287829+montezdesousa@users.noreply.github.com> Co-authored-by: Henrique Joaquim Co-authored-by: andrewkenreich --- .../core/sdk/models/econometrics_sdk_model.py | 4 + openbb_terminal/core/sdk/trail_map.csv | 1 + .../econometrics/econometrics_controller.py | 180 +++++++++++++++++- .../econometrics/econometrics_model.py | 99 +++++++++- .../econometrics/econometrics_view.py | 77 +++++++- openbb_terminal/miscellaneous/i18n/en.yml | 8 +- .../econometrics/test_econometrics.openbb | 2 + openbb_terminal/sdk.py | 2 + requirements.txt | 1 + 9 files changed, 354 insertions(+), 20 deletions(-) diff --git a/openbb_terminal/core/sdk/models/econometrics_sdk_model.py b/openbb_terminal/core/sdk/models/econometrics_sdk_model.py index a532ac86145..2bd9a60a11d 100644 --- a/openbb_terminal/core/sdk/models/econometrics_sdk_model.py +++ b/openbb_terminal/core/sdk/models/econometrics_sdk_model.py @@ -22,6 +22,8 @@ class EconometricsRoot(Category): `dwat_chart`: Show Durbin-Watson autocorrelation tests\n `fdols`: First differencing is an alternative to using fixed effects when there might be correlation.\n `fe`: When effects are correlated with the regressors the RE and BE estimators are not consistent.\n + `garch`: Calculates annualized volatility forecasts based on GARCH.\n + `garch_chart`: Plots the annualized volatility forecasts based on GARCH\n `get_regression_data`: This function creates a DataFrame with the required regression data as\n `granger`: Calculate granger tests\n `granger_chart`: Show granger tests\n @@ -56,6 +58,8 @@ class EconometricsRoot(Category): self.dwat_chart = lib.econometrics_regression_view.display_dwat self.fdols = lib.econometrics_regression_model.get_fdols self.fe = lib.econometrics_regression_model.get_fe + self.garch = lib.econometrics_model.get_garch + self.garch_chart = lib.econometrics_view.display_garch self.get_regression_data = lib.econometrics_regression_model.get_regression_data self.granger = lib.econometrics_model.get_granger_causality self.granger_chart = lib.econometrics_view.display_granger diff --git a/openbb_terminal/core/sdk/trail_map.csv b/openbb_terminal/core/sdk/trail_map.csv index 04218807364..5809887f91f 100644 --- a/openbb_terminal/core/sdk/trail_map.csv +++ b/openbb_terminal/core/sdk/trail_map.csv @@ -183,6 +183,7 @@ econometrics.panel,econometrics_regression_model.get_regressions_results,econome econometrics.pols,econometrics_regression_model.get_pols, econometrics.re,econometrics_regression_model.get_re, econometrics.root,econometrics_model.get_root,econometrics_view.display_root +econometrics.garch,econometrics_model.get_garch,econometrics_view.display_garch economy.available_indices,economy_yfinance_model.get_available_indices, economy.balance,economy_oecd_model.get_balance,economy_oecd_view.plot_balance economy.bigmac,economy_nasdaq_model.get_big_mac_indices,economy_nasdaq_view.display_big_mac_index diff --git a/openbb_terminal/econometrics/econometrics_controller.py b/openbb_terminal/econometrics/econometrics_controller.py index a88fa67be37..8602eeabec2 100644 --- a/openbb_terminal/econometrics/econometrics_controller.py +++ b/openbb_terminal/econometrics/econometrics_controller.py @@ -65,6 +65,7 @@ class EconometricsController(BaseController): "combine", "rename", "lag", + "ret", "ols", "norm", "root", @@ -73,6 +74,7 @@ class EconometricsController(BaseController): "dwat", "bgod", "bpag", + "garch", "granger", "coint", ] @@ -181,6 +183,7 @@ class EconometricsController(BaseController): "plot", "norm", "root", + "garch", "granger", "coint", "corr", @@ -217,6 +220,7 @@ class EconometricsController(BaseController): "ols", "panel", "delete", + "garch", ]: self.choices[feature] = dataset_columns for feature in [ @@ -280,17 +284,19 @@ class EconometricsController(BaseController): mt.add_cmd("combine", self.files) mt.add_cmd("rename", self.files) mt.add_cmd("lag", self.files) + mt.add_cmd("ret", self.files) mt.add_cmd("export", self.files) - mt.add_info("_tests_") + mt.add_info("time_series_") mt.add_cmd("norm", self.files) - mt.add_cmd("root", self.files) - mt.add_cmd("granger", self.files) - mt.add_cmd("coint", self.files) - mt.add_info("_regression_") mt.add_cmd("ols", self.files) + mt.add_cmd("granger", self.files) + mt.add_cmd("root", self.files) + mt.add_cmd("coint", self.files) + mt.add_cmd("garch", self.files) + mt.add_info("_panel_") mt.add_cmd("panel", self.files) mt.add_cmd("compare", self.files) - mt.add_info("_regression_tests_") + mt.add_info("_residuals_") mt.add_cmd("dwat", self.files and self.regression["OLS"]["model"]) mt.add_cmd("bgod", self.files and self.regression["OLS"]["model"]) mt.add_cmd("bpag", self.files and self.regression["OLS"]["model"]) @@ -1224,6 +1230,50 @@ class EconometricsController(BaseController): self.update_runtime_choices() + @log_start_end(log=logger) + def call_ret(self, other_args: List[str]): + """Process ret command""" + parser = argparse.ArgumentParser( + add_help=False, + formatter_class=argparse.ArgumentDefaultsHelpFormatter, + prog="ret", + description="Calculate returns for the given column.", + ) + parser.add_argument( + "-v", + "--values", + help="Dataset.column values to calculate returns.", + dest="values", + choices={ + f"{dataset}.{column}": {column: None, dataset: None} + for dataset, dataframe in self.datasets.items() + for column in dataframe.columns + }, + type=str, + required="-h" not in other_args, + ) + + if other_args and "-" not in other_args[0][0]: + other_args.insert(0, "-v") + ns_parser = self.parse_known_args_and_warn( + parser, other_args, export_allowed=NO_EXPORT + ) + + if not ns_parser: + return + + try: + dataset, col = ns_parser.values.split(".") + data = self.datasets[dataset] + except ValueError: + console.print("[red]Please enter 'dataset'.'column'.[/red]\n") + return + + data[col + "_returns"] = econometrics_model.get_returns(data[col]) + self.datasets[dataset] = data + + self.update_runtime_choices() + @log_start_end(log=logger) def call_eval(self, other_args): """Process eval command""" @@ -1890,6 +1940,124 @@ class EconometricsController(BaseController): self.regression["OLS"]["model"], ns_parser.export ) + @log_start_end(log=logger) + def call_garch(self, other_args: List[str]): + """Process garch command""" + parser = argparse.ArgumentParser( + add_help=False, + formatter_class=argparse.ArgumentDefaultsHelpFormatter, + prog="garch", + description=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. + + $\text{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$ . + + Another method used for estimation is "variance targeting", where one first sets $\omega$ + equal to the variance of the time series. This method nearly as effective as the previously mentioned and + is less computationally effective. + + One can measure the fit of the time series to the GARCH method by using the Ljung-Box statistic. [3] + + See the sources below for reference and for greater detail. + + Sources: + [1] Generalized Autoregressive Conditional Heteroskedasticity, by Tim Bollerslev + [2] Finance Compact Plus Band 1, by Yvonne Seler Zimmerman and Heinz Zimmerman; ISBN: 978-3-907291-31-1 + [3] Options, Futures & other Derivates, by John C. Hull; ISBN: 0-13-022444-8""", + ) + parser.add_argument( + "-v", + "--value", + type=str, + choices=self.choices["garch"], + dest="column", + help="The column and name of the database you want to estimate volatility for", + required="-h" not in other_args, + ) + parser.add_argument( + "-p", + help="The lag order of the symmetric innovation", + dest="p", + type=int, + default=1, + ) + parser.add_argument( + "-o", + help="The lag order of the asymmetric innovation", + dest="o", + type=int, + default=0, + ) + parser.add_argument( + "-q", + help="The lag order of lagged volatility or equivalent", + dest="q", + type=int, + default=1, + ) + parser.add_argument( + "-m", + "--mean", + help="Choose mean model", + choices=["LS", "AR", "ARX", "HAR", "HARX", "constant", "zero"], + default="constant", + type=str, + dest="mean", + ) + parser.add_argument( + "-l", + "--length", + help="The length of the estimate", + dest="horizon", + type=int, + default=100, + ) + parser.add_argument( + "-d", + "--detailed", + help="Display the details about the parameter fit, for instance the confidence interval", + dest="detailed", + action="store_true", + default=False, + ) + if other_args and "-" not in other_args[0][0]: + other_args.insert(0, "-v") + ns_parser = self.parse_known_args_and_warn( + parser, other_args, EXPORT_BOTH_RAW_DATA_AND_FIGURES + ) + if ns_parser: + dataset, column = ns_parser.column.split(".") + econometrics_view.display_garch( + self.datasets[dataset], + column, + ns_parser.p, + ns_parser.o, + ns_parser.q, + ns_parser.mean, + ns_parser.horizon, + ns_parser.detailed, + ) + @log_start_end(log=logger) def call_granger(self, other_args: List[str]): """Process granger command""" diff --git a/openbb_terminal/econometrics/econometrics_model.py b/openbb_terminal/econometrics/econometrics_model.py index 60809a343dc..fdcabb4c68e 100644 --- a/openbb_terminal/econometrics/econometrics_model.py +++ b/openbb_terminal/econometrics/econometrics_model.py @@ -8,18 +8,18 @@ import warnings from itertools import combinations from typing import Any, Dict, Optional, Tuple, Union +import numpy as np import pandas as pd import statsmodels.api as sm +from arch import arch_model from scipy import stats from statsmodels.tsa.stattools import adfuller, grangercausalitytests, kpss -from openbb_terminal.decorators import log_start_end from openbb_terminal.rich_config import console logger = logging.getLogger(__name__) -@log_start_end(log=logger) def get_options( datasets: Dict[str, pd.DataFrame], dataset_name: str = "" ) -> Dict[Union[str, Any], pd.DataFrame]: @@ -61,7 +61,6 @@ def get_options( return option_tables -@log_start_end(log=logger) def get_corr_df(data: pd.DataFrame) -> pd.DataFrame: """Returns correlation for a given df @@ -79,7 +78,6 @@ def get_corr_df(data: pd.DataFrame) -> pd.DataFrame: return corr -@log_start_end(log=logger) def clean( dataset: pd.DataFrame, fill: str = "", @@ -127,7 +125,6 @@ def clean( return dataset -@log_start_end(log=logger) def get_normality(data: pd.Series) -> pd.DataFrame: """ The distribution of returns and generate statistics on the relation to the normal curve. @@ -182,7 +179,6 @@ def get_normality(data: pd.Series) -> pd.DataFrame: ) -@log_start_end(log=logger) def get_root( data: pd.Series, fuller_reg: str = "c", kpss_reg: str = "c" ) -> pd.DataFrame: @@ -224,10 +220,9 @@ def get_root( return data -@log_start_end(log=logger) def get_granger_causality( dependent_series: pd.Series, independent_series: pd.Series, lags: int = 3 -) -> dict: +) -> pd.DataFrame: """Calculate granger tests Parameters @@ -241,8 +236,8 @@ def get_granger_causality( Returns ------- - dict - Dictionary containing results of Granger test + pd.DataFrame + Dataframe containing results of Granger test """ granger_set = pd.concat([dependent_series, independent_series], axis=1) @@ -326,6 +321,90 @@ def get_coint_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 $. + + Another method used for estimation is "variance targeting", where one first sets $ \omega $ + equal to the variance of the time series. This method nearly as effective as the previously mentioned and + is less computationally effective. + + One can measure the fit of the time series to the GARCH method by using the Ljung-Box statistic. [3] + + See the sources below for reference and for greater detail. + + Sources: + [1] Generalized Autoregressive Conditional Heteroskedasticity, by Tim Bollerslev + [2] Finance Compact Plus Band 1, by Yvonne Seler Zimmerman and Heinz Zimmerman; ISBN: 978-3-907291-31-1 + [3] Options, Futures & other Derivates, by John C. Hull; ISBN: 0-13-022444-8 + + Parameters + ---------- + data: pd.Series + The time series (often returns) to estimate volatility from + p: int + Lag order of the symmetric innovation + o: int + Lag order of the asymmetric innovation + q: int + Lag order of lagged volatility or equivalent + mean: str + The name of the mean model + horizon: int + The horizon of the forecast + Examples + -------- + >>> from openbb_terminal.sdk import openbb + >>> openbb.econometrics.garch(openbb.stocks.load("AAPL").iloc[:, 0].pct_change()*100) + """ + model = arch_model(data.dropna(), vol="GARCH", p=p, o=o, q=q, mean=mean) + model_fit = model.fit(disp="off") + pred = model_fit.forecast(horizon=horizon, reindex=False) + + return np.sqrt(pred.variance.values[-1, :]), model_fit + + def get_engle_granger_two_step_cointegration_test( dependent_series: pd.Series, independent_series: pd.Series ) -> Tuple[float, float, float, pd.Series, float, float]: diff --git a/openbb_terminal/econometrics/econometrics_view.py b/openbb_terminal/econometrics/econometrics_view.py index 2f80a9f0f54..c13342c8944 100644 --- a/openbb_terminal/econometrics/econometrics_view.py +++ b/openbb_terminal/econometrics/econometrics_view.py @@ -1,6 +1,8 @@ """Econometrics View""" __docformat__ = "numpy" +# pylint: disable=too-many-arguments + import logging import os from typing import Dict, Optional, Union @@ -43,7 +45,9 @@ def show_options( "Please load in a dataset by using the 'load' command before using this feature." ) else: - option_tables = econometrics_model.get_options(datasets, dataset_name) + option_tables = econometrics_model.get_options( + datasets, dataset_name if dataset_name is not None else "" + ) for dataset, data_values in option_tables.items(): print_rich_table( @@ -386,6 +390,77 @@ def display_root( ) +@log_start_end(log=logger) +def display_garch( + dataset: pd.DataFrame, + column: str, + p: int = 1, + o: int = 0, + q: int = 1, + mean: str = "constant", + horizon: int = 1, + detailed: bool = False, + export: str = "", + external_axes: bool = False, +) -> Union[OpenBBFigure, None]: + """Plots the volatility forecasts based on GARCH + + Parameters + ---------- + dataset: pd.DataFrame + The dataframe to use + column: str + The column of the dataframe to use + p: int + Lag order of the symmetric innovation + o: int + Lag order of the asymmetric innovation + q: int + Lag order of lagged volatility or equivalent + mean: str + The name of the mean model + horizon: int + The horizon of the forecast + detailed: bool + Whether to display the details about the parameter fit, for instance the confidence interval + export: str + Format to export data + external_axes: bool + Whether to return the figure object or not, by default False + """ + data = dataset[column] + result, garch_fit = econometrics_model.get_garch(data, p, o, q, mean, horizon) + + fig = OpenBBFigure() + + fig.add_scatter(x=list(range(1, horizon + 1)), y=result) + fig.set_title( + f"{f'GARCH({p}, {o}, {q})' if o != 0 else f'GARCH({p}, {q})'} volatility forecast" + ) + + if fig.is_image_export(export): + export_data( + export, + os.path.dirname(os.path.abspath(__file__)), + f"{column}_{dataset}_GARCH({p},{q})", + result, + figure=fig, + ) + + if not detailed: + print_rich_table( + garch_fit.params.to_frame(), + headers=["Values"], + show_index=True, + index_name="Parameters", + title=f"GARCH({p}, {o}, {q})" if o != 0 else f"GARCH({p}, {q})", + export=bool(export), + ) + else: + console.print(garch_fit) + return fig.show(external=external_axes) + + @log_start_end(log=logger) def display_granger( dependent_series: pd.Series, diff --git a/openbb_terminal/miscellaneous/i18n/en.yml b/openbb_terminal/miscellaneous/i18n/en.yml index 6cabec05ece..f06570a2d4f 100644 --- a/openbb_terminal/miscellaneous/i18n/en.yml +++ b/openbb_terminal/miscellaneous/i18n/en.yml @@ -966,19 +966,21 @@ en: econometrics/combine: Combine columns from different datasets econometrics/rename: Rename column from dataset econometrics/lag: Add lag to a variable by shifting a column - econometrics/_regression_: Regression - econometrics/_regression_tests_: Regression Tests + econometrics/_panel_: Panel + econometrics/_residuals_: Residuals econometrics/ols: fit a (multi) linear regression model econometrics/norm: perform normality tests on a column of a dataset econometrics/root: perform unitroot tests (ADF & KPSS) on a column of a dataset econometrics/panel: estimate model based on various regression techniques econometrics/compare: compare results of all estimated models - econometrics/_tests_: Tests + econometrics/_time_series_: Time Series econometrics/dwat: Durbin-Watson autocorrelation test on the residuals of the regression econometrics/bgod: Breusch-Godfrey autocorrelation tests with lags on the residuals of the regression econometrics/bpag: Breusch-Pagan heteroscedasticity test on the residuals of the regression econometrics/granger: Granger causality tests on two columns econometrics/coint: co-integration test on a multitude of columns + econometrics/garch: estimate future volatility with GARCH + econometrics/ret: calculate returns for the given time series portfolio/bro: brokers holdings supports robinhood, ally, degiro, coinbase portfolio/po: portfolio optimization optimize your portfolio weights efficiently portfolio/load: load transactions into the portfolio (use load --example for an example) diff --git a/openbb_terminal/miscellaneous/integration_tests_scripts/econometrics/test_econometrics.openbb b/openbb_terminal/miscellaneous/integration_tests_scripts/econometrics/test_econometrics.openbb index 1f805c28572..2e0ae729b31 100644 --- a/openbb_terminal/miscellaneous/integration_tests_scripts/econometrics/test_econometrics.openbb +++ b/openbb_terminal/miscellaneous/integration_tests_scripts/econometrics/test_econometrics.openbb @@ -3,6 +3,8 @@ econometrics ## Exploration load nile +ret -v nile.volume +garch -v nile.volume_returns desc nile load nile -a nile_2 eval double_volume = volume * 2 diff --git a/openbb_terminal/sdk.py b/openbb_terminal/sdk.py index 772854ee362..3dc04b8727f 100644 --- a/openbb_terminal/sdk.py +++ b/openbb_terminal/sdk.py @@ -123,6 +123,8 @@ class OpenBBSDK: `dwat_chart`: Show Durbin-Watson autocorrelation tests\n `fdols`: First differencing is an alternative to using fixed effects when there might be correlation.\n `fe`: When effects are correlated with the regressors the RE and BE estimators are not consistent.\n + `garch`: Calculates annualized volatility forecasts based on GARCH.\n + `garch_chart`: Plots the annualized volatility forecasts based on GARCH\n `get_regression_data`: This function creates a DataFrame with the required regression data as\n `granger`: Calculate granger tests\n `granger_chart`: Show granger tests\n diff --git a/requirements.txt b/requirements.txt index 01110416d23..ead630034e4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,6 +6,7 @@ altair==4.2.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and p ansiwrap==0.8.4 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11" anyio==3.6.2 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11" appdirs==1.4.4 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11" +arch==5.3.1 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11" appnope==0.1.3 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11" and sys_platform == "darwin" or python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11" and platform_system == "Darwin" argon2-cffi-bindings==21.2.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11" argon2-cffi==21.3.0 ; python_version >= "3.8" and python_full_version != "3.9.7" and python_version < "3.11"