diff --git a/openbb_terminal/economy/economy_controller.py b/openbb_terminal/economy/economy_controller.py index 1a738e3ec03..a623c492f7d 100644 --- a/openbb_terminal/economy/economy_controller.py +++ b/openbb_terminal/economy/economy_controller.py @@ -11,6 +11,7 @@ from typing import List, Dict, Any import pandas as pd from prompt_toolkit.completion import NestedCompleter +from openbb_terminal.decorators import check_api_key from openbb_terminal import feature_flags as obbff from openbb_terminal.decorators import log_start_end from openbb_terminal.economy import ( @@ -603,6 +604,7 @@ Performance & Valuations self.update_runtime_choices() + @check_api_key(["API_FRED_KEY"]) def call_fred(self, other_args: List[str]): """Process fred command""" parser = argparse.ArgumentParser( @@ -669,10 +671,12 @@ Performance & Valuations if ns_parser.query: query = " ".join(ns_parser.query) df_search = fred_model.get_series_notes(query) - fred_view.notes(series_term=query, num=ns_parser.limit) - self.fred_query = df_search["id"].head(ns_parser.limit) - self.update_runtime_choices() + if not df_search.empty: + fred_view.notes(series_term=query, num=ns_parser.limit) + + self.fred_query = df_search["id"].head(ns_parser.limit) + self.update_runtime_choices() if ns_parser.parameter: series_dict = {} diff --git a/openbb_terminal/economy/finviz_model.py b/openbb_terminal/economy/finviz_model.py index fdd1688cf11..0f4638e68dc 100644 --- a/openbb_terminal/economy/finviz_model.py +++ b/openbb_terminal/economy/finviz_model.py @@ -8,6 +8,7 @@ import pandas as pd import requests from finvizfinance.group import performance, spectrum, valuation +from openbb_terminal.rich_config import console from openbb_terminal.decorators import log_start_end from openbb_terminal.helper_funcs import get_user_agent @@ -30,9 +31,15 @@ def get_valuation_performance_data(group: str, data_type: str) -> pd.DataFrame: pd.DataFrame dataframe with valuation/performance data """ - if data_type == "valuation": - return valuation.Valuation().screener_view(group=group) - return performance.Performance().screener_view(group=group) + + try: + if data_type == "valuation": + return valuation.Valuation().screener_view(group=group) + elif data_type == "performance": + return performance.Performance().screener_view(group=group) + except IndexError: + console.print("Data not found.\n") + return pd.DataFrame() @log_start_end(log=logger) diff --git a/openbb_terminal/economy/finviz_view.py b/openbb_terminal/economy/finviz_view.py index 19c491919a8..bda36499e99 100644 --- a/openbb_terminal/economy/finviz_view.py +++ b/openbb_terminal/economy/finviz_view.py @@ -58,6 +58,10 @@ def display_performance( Export data to csv,json,xlsx or png,jpg,pdf,svg file """ df_group = finviz_model.get_valuation_performance_data(s_group, "performance") + + if df_group.empty: + return + df_group = df_group.rename( columns={ "Perf Week": "Week", @@ -115,6 +119,10 @@ def display_valuation( Export data to csv,json,xlsx or png,jpg,pdf,svg file """ df_group = finviz_model.get_valuation_performance_data(s_group, "valuation") + + if df_group.empty: + return + df_group["Market Cap"] = df_group["Market Cap"].apply( lambda x: float(x.strip("B")) if x.endswith("B") else float(x.strip("M")) / 1000 ) diff --git a/openbb_terminal/stocks/government/quiverquant_view.py b/openbb_terminal/stocks/government/quiverquant_view.py index 4f9f33de561..e187ff71f64 100644 --- a/openbb_terminal/stocks/government/quiverquant_view.py +++ b/openbb_terminal/stocks/government/quiverquant_view.py @@ -908,7 +908,7 @@ def display_lobbying(ticker: str, num: int = 10): "$" + str(int(float(row["Amount"]))) if row["Amount"] is not None else "N/A" ) console.print(f"{row['Date']}: {row['Client']} {amount}") - if row["Amount"] is not None: + if (row["Amount"] is not None) and (row["Specific_Issue"] is not None): console.print( "\t" + row["Specific_Issue"].replace("\n", " ").replace("\r", "") ) diff --git a/openbb_terminal/stocks/screener/presets/README.md b/openbb_terminal/stocks/screener/presets/README.md index 9dea6e724c6..718a792fe6a 100644 --- a/openbb_terminal/stocks/screener/presets/README.md +++ b/openbb_terminal/stocks/screener/presets/README.md @@ -1,26 +1,26 @@ # PRESETS -* [How to add presets](#how-to-add-presets) -* [template](#template) -* [sexy_year](#sexy_year) -* [buffett_like](#buffett_like) -* [cheap_bottom_dividend](#cheap_bottom_dividend) -* [cheap_dividend](#cheap_dividend) -* [cheap_oversold](#cheap_oversold) -* [cdeath_cross](#death_cross) -* [golden_cross](#golden_cross) -* [heavy_inst_ins](#heavy_inst_ins) -* [modified_dreman](#modified_dreman) -* [modified_neff](#modified_neff) -* [rosenwald](#rosenwald) -* [rosenwald_gtfo](#rosenwald_gtfo) -* [undervalue](#undervalue) +- [How to add presets](#how-to-add-presets) +- [template](#template) +- [sexy_year](#sexy_year) +- [buffett_like](#buffett_like) +- [cheap_bottom_dividend](#cheap_bottom_dividend) +- [cheap_dividend](#cheap_dividend) +- [cheap_oversold](#cheap_oversold) +- [cdeath_cross](#death_cross) +- [golden_cross](#golden_cross) +- [heavy_inst_ins](#heavy_inst_ins) +- [modified_dreman](#modified_dreman) +- [modified_neff](#modified_neff) +- [rosenwald](#rosenwald) +- [rosenwald_gtfo](#rosenwald_gtfo) +- [undervalue](#undervalue) --- ## How to add presets -1. Go to the folder GamestonkTerminal/gamestonk_terminal/screener/presets. +1. Go to the folder GamestonkTerminal/openbb_terminal/screener/presets. 2. There should be a `README.md` file and multiple `.ini` files. One of these `.ini` files should be named `template.ini`. @@ -44,140 +44,140 @@ 5 -8. Start the terminal, and go to the `> scr` menu. In there, you can play with it on the terminal as shown: +8. Start the terminal, and go to the `> scr` menu. In there, you can play with it on the terminal as shown: - * **view**: Allows to see the screeners available. I.e. all `.ini` files in presets folder. - 6 + - **view**: Allows to see the screeners available. I.e. all `.ini` files in presets folder. + 6 - * **view **: Allows to see the specific parameters set for the preset selected. - Captura de ecrã 2021-06-28, às 23 58 35 + - **view **: Allows to see the specific parameters set for the preset selected. + Captura de ecrã 2021-06-28, às 23 58 35 - * **set **: Allows to set this preset as main filter. See that the help menu will display a different - `PRESET: my_own_filter` - 7 + - **set **: Allows to set this preset as main filter. See that the help menu will display a different + `PRESET: my_own_filter` + 7 - * **historical, overview, valuation, financial, ownership, performance, technical** commands will now be performed on - tickers that are filtered with the selected preset. Note: Since it is likely that there will be a big range of - tickers, we cap it to 10 randomly. So, it is normal if for the same filter the user sees 10 different tickers. - If the user wants to see more than 10 tickers, it can select a different limit using `-l` flag. + - **historical, overview, valuation, financial, ownership, performance, technical** commands will now be performed on + tickers that are filtered with the selected preset. Note: Since it is likely that there will be a big range of + tickers, we cap it to 10 randomly. So, it is normal if for the same filter the user sees 10 different tickers. + If the user wants to see more than 10 tickers, it can select a different limit using `-l` flag. 8 9. Share with other Apes. You can do so by either creating yourself a Pull Request with this change, or asking a dev - (e.g. @Sexy_Year) on our discord server to add it for you. + (e.g. @Sexy_Year) on our discord server to add it for you. --- ## template -* **Author of preset:** GamestonkTerminal -* **Contact:** -* **Description:** Template with all available filters and their options menu. More information can be found in +- **Author of preset:** GamestonkTerminal +- **Contact:** +- **Description:** Template with all available filters and their options menu. More information can be found in and --- ## sexy_year -* **Author of preset:** Sexy Year -* **Contact:** Add contact of author, if (s)he whishes to be contacted. This can be an hyperlink, an e-mail, wtv -* **Description:** This is just a sample. The user that adds the preset can add a description for what type of stocks +- **Author of preset:** Sexy Year +- **Contact:** Add contact of author, if (s)he whishes to be contacted. This can be an hyperlink, an e-mail, wtv +- **Description:** This is just a sample. The user that adds the preset can add a description for what type of stocks these filters are aimed for --- ## buffett_like -* **Author of preset:** Traceabl3 -* **Contact:** via smoke signals -* **Description:** Buffet like value screener (Value invsting for long term growth) +- **Author of preset:** Traceabl3 +- **Contact:** via smoke signals +- **Description:** Buffet like value screener (Value invsting for long term growth) --- ## cheap_bottom_dividend -* **Author of preset:** Traceabl3 -* **Contact:** swing the bullroarer -* **ABOUT:** High Yield Dividend stonks that are at-or-near their lowest price. Inverse Head and shoulders pattern recognized. +- **Author of preset:** Traceabl3 +- **Contact:** swing the bullroarer +- **ABOUT:** High Yield Dividend stonks that are at-or-near their lowest price. Inverse Head and shoulders pattern recognized. --- ## cheap_dividend -* **Author of preset:** Traceabl3 -* **Contact:** illuminated bat symbol in the sky -* **Description:** cheap dividend stocks +- **Author of preset:** Traceabl3 +- **Contact:** illuminated bat symbol in the sky +- **Description:** cheap dividend stocks --- ## cheap_oversold -* **Author of preset:** Traceabl3 -* **Contact:** hit me on my skytel pager -* **Description:** Cheap stonks that are oversold: under 10% above the low, and oversold on the RSI. +- **Author of preset:** Traceabl3 +- **Contact:** hit me on my skytel pager +- **Description:** Cheap stonks that are oversold: under 10% above the low, and oversold on the RSI. --- ## death_cross -* **Author of preset:** Traceabl3 -* **Contact:** take the red pill -* **Description:** Death cross : when the 50sma crosses below the 200 sma -* **More information:** +- **Author of preset:** Traceabl3 +- **Contact:** take the red pill +- **Description:** Death cross : when the 50sma crosses below the 200 sma +- **More information:** --- ## golden_cross -* **Author of preset:** Traceabl3 -* **Contact:** flip the pigeons -* **Description:** Golden Cross when the 50 day moves above the 200 day from below. +- **Author of preset:** Traceabl3 +- **Contact:** flip the pigeons +- **Description:** Golden Cross when the 50 day moves above the 200 day from below. --- ## heavy_inst_ins -* **Author of preset:** Traceabl3 -* **Contact:** blow into the conch shell -* **Description:** Heavily owned by institutions and insiders (>30% each) +- **Author of preset:** Traceabl3 +- **Contact:** blow into the conch shell +- **Description:** Heavily owned by institutions and insiders (>30% each) --- ## modified_dreman -* **Author of preset:** Traceabl3 -* **Contact:** Drum Telegraphy -* **Description:** Modified Version of the Dreman Screener. +- **Author of preset:** Traceabl3 +- **Contact:** Drum Telegraphy +- **Description:** Modified Version of the Dreman Screener. --- ## modified_neff -* **Author of preset:** Traceabl3 -* **Contact:** bang the drums -* **Description:** Neff Screener with modifications // operational margin <50% -* **More information:** +- **Author of preset:** Traceabl3 +- **Contact:** bang the drums +- **Description:** Neff Screener with modifications // operational margin <50% +- **More information:** --- ## rosenwald -* **Author of preset:** Traceabl3 -* **Contact:** three shots in the air. -* **Description:** the classic rosenwald screen based on some dude I work with best guess. +- **Author of preset:** Traceabl3 +- **Contact:** three shots in the air. +- **Description:** the classic rosenwald screen based on some dude I work with best guess. --- ## rosenwald_gtfo -* **Author of preset:** Traceabl3 -* **Contact:** wave the white flag -* **Description:** Too many indicators indicating an impending downturn. +- **Author of preset:** Traceabl3 +- **Contact:** wave the white flag +- **Description:** Too many indicators indicating an impending downturn. --- ## undervalue -* **Author of preset:** Traceabl3 -* **Contact:** message on tor browser. -* **Description:** Potential Undervalued stocks +- **Author of preset:** Traceabl3 +- **Contact:** message on tor browser. +- **Description:** Potential Undervalued stocks diff --git a/tests/openbb_terminal/common/behavioural_analysis/test_finbrain_view.py b/tests/openbb_terminal/common/behavioural_analysis/test_finbrain_view.py index 6c2d57d5b23..cb82f7c8119 100644 --- a/tests/openbb_terminal/common/behavioural_analysis/test_finbrain_view.py +++ b/tests/openbb_terminal/common/behavioural_analysis/test_finbrain_view.py @@ -19,7 +19,7 @@ def test_display_sentiment_analysis(color, mocker): target="openbb_terminal.common.behavioural_analysis.finbrain_view.export_data" ) - # MOCK GTFF + # MOCK OBBFF mocker.patch.object(target=helper_funcs.obbff, attribute="USE_ION", new=True) mocker.patch.object( target=finbrain_view.rich_config, attribute="USE_COLOR", new=color @@ -44,7 +44,7 @@ def test_display_sentiment_analysis_empty_df(mocker): target="openbb_terminal.common.behavioural_analysis.finbrain_view.export_data" ) - # MOCK GTFF + # MOCK OBBFF mocker.patch.object(target=helper_funcs.obbff, attribute="USE_ION", new=True) # MOCK GET_SENTIMENT diff --git a/tests/openbb_terminal/economy/test_finviz_view.py b/tests/openbb_terminal/economy/test_finviz_view.py index 489a7af85f1..bff7c777c65 100644 --- a/tests/openbb_terminal/economy/test_finviz_view.py +++ b/tests/openbb_terminal/economy/test_finviz_view.py @@ -39,7 +39,7 @@ def test_map_sp500_view(mocker): ], ) def test_display_performance(mocker, tab): - # MOCK GTFF + # MOCK OBBFF mocker.patch.object(target=helper_funcs.obbff, attribute="USE_TABULATE_DF", new=tab) mocker.patch.object(target=helper_funcs.obbff, attribute="USE_ION", new=True) @@ -65,7 +65,7 @@ def test_display_performance(mocker, tab): ], ) def test_display_valuation(mocker, tab): - # MOCK GTFF + # MOCK OBBFF mocker.patch.object(target=helper_funcs.obbff, attribute="USE_TABULATE_DF", new=tab) mocker.patch.object(target=helper_funcs.obbff, attribute="USE_ION", new=True) @@ -116,7 +116,7 @@ def test_display_spectrum(mocker): ], ) def test_display_future(mocker, tab): - # MOCK GTFF + # MOCK OBBFF mocker.patch.object(target=helper_funcs.obbff, attribute="USE_TABULATE_DF", new=tab) mocker.patch.object(target=helper_funcs.obbff, attribute="USE_ION", new=True) diff --git a/tests/openbb_terminal/economy/test_wsj_view.py b/tests/openbb_terminal/economy/test_wsj_view.py index d725dbfa96f..464f91ba5d0 100644 --- a/tests/openbb_terminal/economy/test_wsj_view.py +++ b/tests/openbb_terminal/economy/test_wsj_view.py @@ -26,7 +26,7 @@ from openbb_terminal import helper_funcs ) @pytest.mark.record_stdout def test_call_func(func, mocker, tab): - # MOCK GTFF + # MOCK OBBFF mocker.patch.object(target=helper_funcs.obbff, attribute="USE_TABULATE_DF", new=tab) # MOCK EXPORT_DATA diff --git a/tests/openbb_terminal/stocks/insider/test_openinsider_view.py b/tests/openbb_terminal/stocks/insider/test_openinsider_view.py index 13b2b482c60..db383c34d3e 100644 --- a/tests/openbb_terminal/stocks/insider/test_openinsider_view.py +++ b/tests/openbb_terminal/stocks/insider/test_openinsider_view.py @@ -64,7 +64,7 @@ def test_print_insider_filter_no_table(mocker): [True, False], ) def test_print_insider_data(color, mocker): - # MOCK GTFF + # MOCK OBBFF mocker.patch.object( target=openinsider_view.rich_config, attribute="USE_COLOR", new=color ) diff --git a/tests/openbb_terminal/stocks/sector_industry_analysis/test_sia_controller.py b/tests/openbb_terminal/stocks/sector_industry_analysis/test_sia_controller.py index 59c1af966b6..0adcdf0a927 100644 --- a/tests/openbb_terminal/stocks/sector_industry_analysis/test_sia_controller.py +++ b/tests/openbb_terminal/stocks/sector_industry_analysis/test_sia_controller.py @@ -509,7 +509,7 @@ def test_call_func_no_parser(func, mocker): def test_controller_init_summary_profile(countries, industries, mocker, sectors): path_controller = "openbb_terminal.stocks.sector_industry_analysis.sia_controller" - # MOCK GTFF + # MOCK OBBFF mocker.patch( target=f"{path_controller}.obbff.USE_PROMPT_TOOLKIT", new=True, @@ -568,7 +568,7 @@ def test_controller_init_market_cap(market_cap, mocker): def test_update_runtime_choices(mocker): path_controller = "openbb_terminal.stocks.sector_industry_analysis.sia_controller" - # MOCK GTFF + # MOCK OBBFF mocker.patch( target=f"{path_controller}.obbff.USE_PROMPT_TOOLKIT", new=True,