From f78449924bb6a47ec4cdffd906c4b9a0a3d913ac Mon Sep 17 00:00:00 2001 From: Colin Delahunty <72827203+colin99d@users.noreply.github.com> Date: Thu, 17 Aug 2023 07:12:20 -0700 Subject: [PATCH 1/4] Fixed the request function (#5336) * Fixed the request function * Added fix * Added fix * Added fix * Added fix * Added fix --- openbb_terminal/helper_funcs.py | 34 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/openbb_terminal/helper_funcs.py b/openbb_terminal/helper_funcs.py index e93d183cfd5..615e7fb40d0 100644 --- a/openbb_terminal/helper_funcs.py +++ b/openbb_terminal/helper_funcs.py @@ -2078,7 +2078,7 @@ def check_start_less_than_end(start_date: str, end_date: str) -> bool: # Write an abstract helper to make requests from a url with potential headers and params def request( - url: str, method: str = "GET", timeout: int = 0, **kwargs + url: str, method: str = "get", timeout: int = 0, **kwargs ) -> requests.Response: """Abstract helper to make requests from a url with potential headers and params. @@ -2086,8 +2086,11 @@ def request( ---------- url : str Url to make the request to - method : str, optional - HTTP method to use. Can be "GET" or "POST", by default "GET" + method : str + HTTP method to use. Choose from: + delete, get, head, patch, post, put, by default "get" + timeout : int + How many seconds to wait for the server to send data Returns ------- @@ -2099,6 +2102,9 @@ def request( ValueError If invalid method is passed """ + method = method.lower() + if method not in ["delete", "get", "head", "patch", "post", "put"]: + raise ValueError(f"Invalid method: {method}") current_user = get_current_user() # We want to add a user agent to the request, so check if there are any headers # If there are headers, check if there is a user agent, if not add one. @@ -2108,21 +2114,13 @@ def request( if "User-Agent" not in headers: headers["User-Agent"] = get_user_agent() - if method.upper() == "GET": - return requests.get( - url, - headers=headers, - timeout=timeout, - **kwargs, - ) - if method.upper() == "POST": - return requests.post( - url, - headers=headers, - timeout=timeout, - **kwargs, - ) - raise ValueError("Method must be GET or POST") + func = getattr(requests, method) + return func( + url, + headers=headers, + timeout=timeout, + **kwargs, + ) def remove_timezone_from_dataframe(df: pd.DataFrame) -> pd.DataFrame: From f07d116f23f3dfc51a98edd82c5ea0953dc695a5 Mon Sep 17 00:00:00 2001 From: Colin Delahunty <72827203+colin99d@users.noreply.github.com> Date: Thu, 17 Aug 2023 09:18:26 -0700 Subject: [PATCH 2/4] Fixed URL for uploading to the hub (#5340) * Fixed URLs * Added a fix --- openbb_terminal/core/session/hub_model.py | 5 +---- openbb_terminal/settings_controller.py | 9 +++------ 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/openbb_terminal/core/session/hub_model.py b/openbb_terminal/core/session/hub_model.py index 8c711b10d07..1103cb18682 100644 --- a/openbb_terminal/core/session/hub_model.py +++ b/openbb_terminal/core/session/hub_model.py @@ -375,7 +375,6 @@ def upload_config( value: str, type_: Literal["settings", "terminal_style"], auth_header: str, - base_url: str = BackendEnvironment.BASE_URL, timeout: int = TIMEOUT, ) -> Optional[requests.Response]: """Patch user configurations to the server. @@ -390,8 +389,6 @@ def upload_config( The type of the patch. auth_header : str The authorization header, e.g. "Bearer ". - base_url : str - The base url, by default BASE_URL timeout : int The timeout, by default TIMEOUT @@ -409,7 +406,7 @@ def upload_config( try: console.print("Sending to OpenBB hub...") response = requests.patch( - url=base_url + "terminal/user", + url=BackendEnvironment.BASE_URL + "terminal/user", headers={"Authorization": auth_header}, json=data, timeout=timeout, diff --git a/openbb_terminal/settings_controller.py b/openbb_terminal/settings_controller.py index 4ba909c0021..d1aa82d4132 100644 --- a/openbb_terminal/settings_controller.py +++ b/openbb_terminal/settings_controller.py @@ -231,7 +231,7 @@ class SettingsController(BaseController): " Then, place the downloaded file 'openbb_config.richstyle.json'" f" inside {get_current_user().preferences.USER_STYLES_DIRECTORY} or " f"{STYLES_DIRECTORY_REPO}. If you have a hub account you can change colors " - f"here {BackendEnvironment.HUB_URL + 'app/terminal/theme'}.", + f"here {BackendEnvironment.BASE_URL + 'app/terminal/theme'}.", ) if other_args and "-" not in other_args[0][0]: other_args.insert(0, "-s") @@ -246,7 +246,6 @@ class SettingsController(BaseController): value=ns_parser.style, type_="settings", auth_header=get_current_user().profile.get_auth_header(), - base_url=BackendEnvironment.HUB_URL, ) console.print("") console.print("Colors updated.") @@ -267,7 +266,7 @@ class SettingsController(BaseController): dest="style", choices=["dark", "light"], help="Choose chart style. If you have a hub account you can change theme " - f"here {BackendEnvironment.HUB_URL + 'app/terminal/theme/charts-tables'}.", + f"here {BackendEnvironment.BASE_URL + 'app/terminal/theme/charts-tables'}.", required="-h" not in other_args and "--help" not in other_args, ) if other_args and "-" not in other_args[0][0]: @@ -283,7 +282,6 @@ class SettingsController(BaseController): value=ns_parser.style, type_="terminal_style", auth_header=get_current_user().profile.get_auth_header(), - base_url=BackendEnvironment.HUB_URL, ) console.print("") theme.apply_style(ns_parser.style) @@ -305,7 +303,7 @@ class SettingsController(BaseController): dest="style", choices=["dark", "light"], help="Choose table style. If you have a hub account you can change theme " - f"here {BackendEnvironment.HUB_URL + 'app/terminal/theme/charts-tables'}.", + f"here {BackendEnvironment.BASE_URL + 'app/terminal/theme/charts-tables'}.", required="-h" not in other_args and "--help" not in other_args, ) if other_args and "-" not in other_args[0][0]: @@ -321,7 +319,6 @@ class SettingsController(BaseController): value=ns_parser.style, type_="terminal_style", auth_header=get_current_user().profile.get_auth_header(), - base_url=BackendEnvironment.HUB_URL, ) console.print("") console.print("Table theme updated.\n") From a6e66f7a730fb2aa23e805fd8abe8dddba8990a4 Mon Sep 17 00:00:00 2001 From: Danglewood <85772166+deeleeramone@users.noreply.github.com> Date: Thu, 17 Aug 2023 09:25:13 -0700 Subject: [PATCH 3/4] hotfix/fix-stocks-search-sdk3: Fixes the stocks search so that it doesn't `print_rich_table()` for SDK. (#5329) * fixes the stocks search on SDK so the ticker symbol is returned. * export data * unused argument * fix test * more test fixy * test_print_help.txt --- openbb_terminal/stocks/stocks_controller.py | 20 ++++- openbb_terminal/stocks/stocks_helper.py | 81 ++++++++++--------- .../stocks/test_stocks_controller.py | 1 - .../stocks/test_stocks_helper.py | 6 +- .../test_stocks_helper/test_search[False].txt | 5 +- .../test_stocks_helper/test_search[True].txt | 5 +- 6 files changed, 69 insertions(+), 49 deletions(-) diff --git a/openbb_terminal/stocks/stocks_controller.py b/openbb_terminal/stocks/stocks_controller.py index ab0071c84e2..06b4ea0e254 100644 --- a/openbb_terminal/stocks/stocks_controller.py +++ b/openbb_terminal/stocks/stocks_controller.py @@ -246,7 +246,7 @@ class StocksController(StockBaseController): parser, other_args, EXPORT_ONLY_RAW_DATA_ALLOWED, - limit=10, + limit=0, ): # Mapping sector = stocks_helper.map_parse_choices(self.sector)[ns_parser.sector] @@ -263,7 +263,7 @@ class StocksController(StockBaseController): list(stocks_helper.market_coverage_suffix.keys()) )[ns_parser.exchange_country] - stocks_helper.search( + df = stocks_helper.search( query=" ".join(ns_parser.query), country=ns_parser.country, sector=sector, @@ -272,8 +272,22 @@ class StocksController(StockBaseController): exchange=exchange, exchange_country=exchange_country, all_exchanges=ns_parser.all_exchanges, - limit=ns_parser.limit, ) + if ns_parser.export: + export_data( + ns_parser.export, + os.path.dirname(os.path.abspath(__file__)), + "search", + df, + " ".join(ns_parser.sheet_name) if ns_parser.sheet_name else None, + ) + if not ns_parser.export: + stocks_helper.print_rich_table( + df, + show_index=False, + headers=df.columns, + title="Stock Search Results", + ) @log_start_end(log=logger) def call_tob(self, other_args: List[str]): diff --git a/openbb_terminal/stocks/stocks_helper.py b/openbb_terminal/stocks/stocks_helper.py index f50e1c76108..28f4a722798 100644 --- a/openbb_terminal/stocks/stocks_helper.py +++ b/openbb_terminal/stocks/stocks_helper.py @@ -120,7 +120,6 @@ def search( exchange: str = "", exchange_country: str = "", all_exchanges: bool = False, - limit: int = 0, ) -> pd.DataFrame: """Search selected query for tickers. @@ -142,8 +141,6 @@ def search( Search by exchange country to find stock matching the criteria all_exchanges: bool Whether to search all exchanges, without this option only the United States market is searched - limit : int - The limit of results shown, where 0 means all the results Returns ------- @@ -228,43 +225,11 @@ def search( df = df[["name", "country", "sector", "industry_group", "industry", "exchange"]] # To automate renaming columns - headers = [col.replace("_", " ") for col in df.columns.tolist()] - - title = "Companies found" - if query: - title += f" on term {query}" - if exchange_country and exchange: - title += f" on the exchange {exchange} in {exchange_country.replace('_', ' ').title()}" - if exchange and not exchange_country: - title += f" on the exchange {exchange}" - if exchange_country and not exchange: - title += f" on an exchange in {exchange_country.replace('_', ' ').title()}" - if country: - title += f" in {country.replace('_', ' ').title()}" - if sector: - title += f" within {sector}" - if industry_group: - title += f" and {industry_group}" - if industry: - title += f" and {industry}" - if not sector and industry_group: - title += f" within {industry_group}" - if not sector and industry: - title += f" within {industry}" - + df.columns = [col.replace("_", " ") for col in df.columns.tolist()] df = df.fillna(value=np.nan) df = df.iloc[df.isnull().sum(axis=1).mul(1).argsort()] - print_rich_table( - df, - show_index=True, - headers=headers, - index_name="Symbol", - title=title, - limit=limit, - ) - - return df + return df.reset_index() def load( # pylint: disable=too-many-return-statements @@ -1108,3 +1073,45 @@ def heikin_ashi(data: pd.DataFrame) -> pd.DataFrame: ] return pd.concat([data, ha], axis=1) + + +def calculate_adjusted_prices(df: pd.DataFrame, column: str, dividends: bool = False): + """Calculates the split-adjusted prices, or split and dividend adjusted prices. + + Parameters + ------------ + df: pd.DataFrame + DataFrame with unadjusted OHLCV values + Split Factor + Dividend + column: str + The column name to adjust. + dividends: bool + Whether to adjust for both splits and dividends. Default is split-adjusted only. + + Returns + -------- + pd.DataFrame + DataFrame with adjusted prices. + """ + + df = df.copy() + adj_column = "Adj " + column + + # Reverse the DataFrame order, sorting by date in descending order + df.sort_index(ascending=False, inplace=True) + + price_col = df[column].values + split_col = df["Volume Factor"] if column == "Volume" else df["Split Factor"].values + dividend_col = df["Dividend"].values if dividends else np.zeros(len(price_col)) + adj_price_col = np.zeros(len(df.index)) + adj_price_col[0] = price_col[0] + + for i in range(1, len(price_col)): + adj_price_col[i] = adj_price_col[i - 1] + adj_price_col[i - 1] * ( + ((price_col[i] * split_col[i - 1]) - price_col[i - 1] - dividend_col[i - 1]) + / price_col[i - 1] + ) + df[adj_column] = adj_price_col + + # Change the DataFrame order back to dates ascending + df.sort_index(ascending=True, inplace=True) + return df diff --git a/tests/openbb_terminal/stocks/test_stocks_controller.py b/tests/openbb_terminal/stocks/test_stocks_controller.py index 10509a33649..6aaa93d5aa7 100644 --- a/tests/openbb_terminal/stocks/test_stocks_controller.py +++ b/tests/openbb_terminal/stocks/test_stocks_controller.py @@ -266,7 +266,6 @@ def test_call_func_expect_queue(expected_queue, func, queue): [], dict( query="microsoft", - limit=1, country="", sector="", industry_group="", diff --git a/tests/openbb_terminal/stocks/test_stocks_helper.py b/tests/openbb_terminal/stocks/test_stocks_helper.py index 8c35dd4e575..1571f025e0a 100644 --- a/tests/openbb_terminal/stocks/test_stocks_helper.py +++ b/tests/openbb_terminal/stocks/test_stocks_helper.py @@ -57,7 +57,7 @@ def test_search(mocker, use_tab): target="openbb_terminal.core.session.current_user.__current_user", new=mock_current_user, ) - stocks_helper.search( + df = stocks_helper.search( query="microsoft", country="United_States", sector="", @@ -66,7 +66,9 @@ def test_search(mocker, use_tab): exchange="", exchange_country="", all_exchanges=False, - limit=5, + ) + stocks_helper.print_rich_table( + df, show_index=False, title="Company Search Results", headers=df.columns ) diff --git a/tests/openbb_terminal/stocks/txt/test_stocks_helper/test_search[False].txt b/tests/openbb_terminal/stocks/txt/test_stocks_helper/test_search[False].txt index 8e93dc0f168..631687e741d 100644 --- a/tests/openbb_terminal/stocks/txt/test_stocks_helper/test_search[False].txt +++ b/tests/openbb_terminal/stocks/txt/test_stocks_helper/test_search[False].txt @@ -1,3 +1,2 @@ - name country sector industry_group industry exchange -symbol -MSFT Microsoft Corporation United States Information Technology Software & Services Software NMS + symbol name country sector industry group industry exchange +0 MSFT Microsoft Corporation United States Information Technology Software & Services Software NMS diff --git a/tests/openbb_terminal/stocks/txt/test_stocks_helper/test_search[True].txt b/tests/openbb_terminal/stocks/txt/test_stocks_helper/test_search[True].txt index 8e93dc0f168..631687e741d 100644 --- a/tests/openbb_terminal/stocks/txt/test_stocks_helper/test_search[True].txt +++ b/tests/openbb_terminal/stocks/txt/test_stocks_helper/test_search[True].txt @@ -1,3 +1,2 @@ - name country sector industry_group industry exchange -symbol -MSFT Microsoft Corporation United States Information Technology Software & Services Software NMS + symbol name country sector industry group industry exchange +0 MSFT Microsoft Corporation United States Information Technology Software & Services Software NMS From b27bb59ef628c2d6cde36cf231a3a9580212e457 Mon Sep 17 00:00:00 2001 From: Colin Delahunty <72827203+colin99d@users.noreply.github.com> Date: Thu, 17 Aug 2023 14:39:34 -0700 Subject: [PATCH 4/4] Added fixes (#5344) --- openbb_terminal/economy/econdb_model.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openbb_terminal/economy/econdb_model.py b/openbb_terminal/economy/econdb_model.py index d48ae665a77..3ad6e64a6d5 100644 --- a/openbb_terminal/economy/econdb_model.py +++ b/openbb_terminal/economy/econdb_model.py @@ -419,9 +419,12 @@ TRANSFORM = { SCALES = { "Thousands": 1_000, "Tens of thousands": 10_000, + "Hundreds of thousands": 100_000, "Millions": 1_000_000, + "Tens of millions": 10_000_000, "Hundreds of millions": 100_000_000, "Billions": 1_000_000_000, + "Tens of billions": 10_000_000_000, "Units": 1, }