diff --git a/openbb_terminal/common/technical_analysis/volatility_model.py b/openbb_terminal/common/technical_analysis/volatility_model.py index c152c98174b..0df3a948723 100644 --- a/openbb_terminal/common/technical_analysis/volatility_model.py +++ b/openbb_terminal/common/technical_analysis/volatility_model.py @@ -170,8 +170,11 @@ def atr( @log_start_end(log=logger) -def rvol( - data: pd.DataFrame, lower_q: float = 0.25, upper_q: float = 0.75 +def cones( + data: pd.DataFrame, + lower_q: float = 0.25, + upper_q: float = 0.75, + is_crypto: bool = False, ) -> pd.DataFrame: """Returns a DataFrame of realized volatility quantiles. @@ -183,22 +186,25 @@ def rvol( The lower quantile to calculate the realized volatility over time for. upper_q: float (default = 0.75) The upper quantile to calculate the realized volatility over time for. + is_crypto: bool (default = False) + If true, volatility is calculated for 365 days instead of 252. Returns ------- - pd.DataFrame: rvol + pd.DataFrame: cones DataFrame of realized volatility quantiles. - Examples - -------- - df = rvol(symbol = "AAPL") - - df = rvol(symbol = "AAPL", lower_q = 0.10, upper_q = 0.90) + Example + ------- + df = openbb.stocks.load("AAPL") + cones_df = openbb.ta.cones(data = df, lower_q = 0.10, upper_q = 0.90) """ + + n_days: int = 365 if is_crypto else 252 + try: lower_q_label = str(int(lower_q * 100)) upper_q_label = str(int(upper_q * 100)) - rvol: pd.DataFrame = pd.DataFrame() quantiles = [lower_q, upper_q] windows = [3, 10, 30, 60, 90, 120, 150, 180, 210, 240, 300, 360] min_ = [] @@ -214,7 +220,9 @@ def rvol( log_return = (data["Close"] / data["Close"].shift(1)).apply(np.log) - return log_return.rolling(window=window, center=False).std() * np.sqrt(252) + return log_return.rolling(window=window, center=False).std() * np.sqrt( + n_days + ) for window in windows: # Looping to build a dataframe with realized volatility over each window. @@ -241,11 +249,12 @@ def rvol( 5: "Max", } ) - rvol = df.copy() - return rvol.transpose() - - except Exception as e: - rvol = pd.DataFrame() - print('There was an error with the selected quantile value. Values must be between 0 and 1.') - return rvol + cones_df = df.copy() + return cones_df.transpose() + except Exception: + cones_df = pd.DataFrame() + print( + "There was an error with the selected quantile value. Values must be between 0 and 1." + ) + return cones_df diff --git a/openbb_terminal/common/technical_analysis/volatility_view.py b/openbb_terminal/common/technical_analysis/volatility_view.py index 52ef91958c4..4cf8735ccc2 100644 --- a/openbb_terminal/common/technical_analysis/volatility_view.py +++ b/openbb_terminal/common/technical_analysis/volatility_view.py @@ -369,11 +369,12 @@ def display_atr( @log_start_end(log=logger) -def display_rvol( +def display_cones( data: pd.DataFrame, symbol: str = "", lower_q: float = 0.25, upper_q: float = 0.75, + is_crypto: bool = False, export: str = "", sheet_name: Optional[str] = None, external_axes: Optional[List[plt.Axes]] = None, @@ -390,6 +391,8 @@ def display_rvol( The lower quantile to calculate for. upper_q: float (default = 0.75) The upper quantile to for. + is_crypto: bool (default = False) + If true, volatility is calculated for 365 days instead of 252. export : str Format of export file sheet_name: str @@ -400,12 +403,14 @@ def display_rvol( Examples -------- df_ta = openbb.stocks.load('XLY') - openbb.ta.rvol_chart(data = df_ta, symbol = 'XLY') + openbb.ta.cones_chart(data = df_ta, symbol = 'XLY') df_ta = openbb.stocks.load('XLE') - openbb.ta.rvol_chart(data = df_ta, symbol = "XLE", lower_q = 0.10, upper_q = 0.90) + openbb.ta.cones_chart(data = df_ta, symbol = "XLE", lower_q = 0.10, upper_q = 0.90) """ - df_ta = volatility_model.rvol(data, lower_q=lower_q, upper_q=upper_q) + df_ta = volatility_model.cones( + data, lower_q=lower_q, upper_q=upper_q, is_crypto=is_crypto + ) lower_q_label = str(int(lower_q * 100)) upper_q_label = str(int(upper_q * 100)) if not df_ta.empty: diff --git a/openbb_terminal/miscellaneous/library/trail_map.csv b/openbb_terminal/miscellaneous/library/trail_map.csv index 421a0bf0877..3442cdad903 100644 --- a/openbb_terminal/miscellaneous/library/trail_map.csv +++ b/openbb_terminal/miscellaneous/library/trail_map.csv @@ -539,5 +539,5 @@ ta.stoch,openbb_terminal.common.technical_analysis.momentum_model.stoch,openbb_t ta.vwap,openbb_terminal.common.technical_analysis.overlap_model.vwap,openbb_terminal.common.technical_analysis.overlap_view.view_vwap ta.wma,openbb_terminal.common.technical_analysis.overlap_model.wma, ta.zlma,openbb_terminal.common.technical_analysis.overlap_model.zlma, -ta.cones,openbb_terminal.common.technical_analysis.volatility_model.rvol,openbb_terminal.common.technical_analysis.volatility_view.display_rvol +ta.cones,openbb_terminal.common.technical_analysis.volatility_model.cones,openbb_terminal.common.technical_analysis.volatility_view.display_cones whoami,openbb_terminal.session.sdk_session.whoami, diff --git a/openbb_terminal/sdk_core/models/ta_sdk_model.py b/openbb_terminal/sdk_core/models/ta_sdk_model.py index 6b8a1c6bca5..54ec75c9d6a 100644 --- a/openbb_terminal/sdk_core/models/ta_sdk_model.py +++ b/openbb_terminal/sdk_core/models/ta_sdk_model.py @@ -99,8 +99,8 @@ class TaRoot(Category): self.obv_chart = lib.common_ta_volume_view.display_obv self.rsi = lib.common_ta_momentum_model.rsi self.rsi_chart = lib.common_ta_momentum_view.display_rsi - self.cones = lib.common_ta_volatility_model.rvol - self.cones_chart = lib.common_ta_volatility_view.display_rvol + self.cones = lib.common_ta_volatility_model.cones + self.cones_chart = lib.common_ta_volatility_view.display_cones self.sma = lib.common_ta_overlap_model.sma self.stoch = lib.common_ta_momentum_model.stoch self.stoch_chart = lib.common_ta_momentum_view.display_stoch diff --git a/openbb_terminal/sdk_core/trail_map.csv b/openbb_terminal/sdk_core/trail_map.csv index 3aa620d9c7e..55ab83c593d 100644 --- a/openbb_terminal/sdk_core/trail_map.csv +++ b/openbb_terminal/sdk_core/trail_map.csv @@ -541,7 +541,7 @@ ta.ma,common_ta_overlap_view.view_ma,common_ta_overlap_view.view_ma ta.macd,common_ta_momentum_model.macd,common_ta_momentum_view.display_macd ta.obv,common_ta_volume_model.obv,common_ta_volume_view.display_obv ta.rsi,common_ta_momentum_model.rsi,common_ta_momentum_view.display_rsi -ta.cones,common_ta_volatility_model.rvol,common_ta_volatility_view.display_rvol +ta.cones,common_ta_volatility_model.cones,common_ta_volatility_view.display_cones ta.sma,common_ta_overlap_model.sma, ta.stoch,common_ta_momentum_model.stoch,common_ta_momentum_view.display_stoch ta.vwap,common_ta_overlap_model.vwap,common_ta_overlap_view.view_vwap diff --git a/openbb_terminal/stocks/technical_analysis/ta_controller.py b/openbb_terminal/stocks/technical_analysis/ta_controller.py index 827ac473a11..5da32966d71 100644 --- a/openbb_terminal/stocks/technical_analysis/ta_controller.py +++ b/openbb_terminal/stocks/technical_analysis/ta_controller.py @@ -1684,6 +1684,13 @@ class TechnicalAnalysisController(StockBaseController): default=0.75, help="The upper % quantile for calculations.", ) + parser.add_argument( + "--is_crypto", + dest="is_crypto", + action="store_true", + default=False, + help="If True, volatility is calculated for 365 days instead of 252.", + ) ns_parser = self.parse_known_args_and_warn( parser, other_args, EXPORT_BOTH_RAW_DATA_AND_FIGURES ) @@ -1692,11 +1699,12 @@ class TechnicalAnalysisController(StockBaseController): no_ticker_message() return - volatility_view.display_rvol( + volatility_view.display_cones( data = self.stock, symbol = self.ticker, lower_q = ns_parser.lower_q, upper_q = ns_parser.upper_q, + is_crypto = ns_parser.is_crypto, export=ns_parser.export, sheet_name=" ".join(ns_parser.sheet_name) if ns_parser.sheet_name