diff options
author | nectariosouzo <nectariosouzounidis@gmail.com> | 2023-10-02 19:20:12 -0400 |
---|---|---|
committer | nectariosouzo <nectariosouzounidis@gmail.com> | 2023-10-02 19:20:12 -0400 |
commit | 4836170cf0ff4d45c5c7797f1f8c332af94ff44a (patch) | |
tree | a7daf8c58fb282b00d46359aee8c66219c24e980 | |
parent | fed04cfaab32231ec2f832dcbeedf9782f30de99 (diff) |
Add progress bar and get bulk prices
-rw-r--r-- | openbb_terminal/etf/fmp_model.py | 104 | ||||
-rw-r--r-- | openbb_terminal/etf/fmp_view.py | 12 |
2 files changed, 76 insertions, 40 deletions
diff --git a/openbb_terminal/etf/fmp_model.py b/openbb_terminal/etf/fmp_model.py index e9aa69bbe85..39720586efc 100644 --- a/openbb_terminal/etf/fmp_model.py +++ b/openbb_terminal/etf/fmp_model.py @@ -3,7 +3,7 @@ __docformat__ = "numpy" import json import logging -from typing import Any, Dict, List, Union +from typing import Any, Dict, List from urllib.error import HTTPError from urllib.request import urlopen @@ -12,7 +12,7 @@ import pandas as pd from openbb_terminal.core.session.current_user import get_current_user from openbb_terminal.decorators import check_api_key, log_start_end from openbb_terminal.helper_funcs import request -from openbb_terminal.rich_config import console +from openbb_terminal.rich_config import console, optional_rich_track logger = logging.getLogger(__name__) @@ -55,14 +55,14 @@ def get_etf_sector_weightings(name: str) -> Dict: @log_start_end(log=logger) @check_api_key(["API_KEY_FINANCIALMODELINGPREP"]) def get_stock_price_change( - ticker: str, start_date: str, end_date: str -) -> Union[None, float]: + tickers: List[str], start_date: str, end_date: str +) -> Dict[str, float]: """Get stock's price percent change over specified time period. Parameters ---------- - ticker : str - Ticker to get information from. + tickers : List[str] + Ticker(s) to get information for. start: str Date from which data is fetched in format YYYY-MM-DD end: str @@ -70,42 +70,65 @@ def get_stock_price_change( Returns ------- - Union[None, float] - Percent change of closing price over time period + Dict[str, float] + Percent change of closing price over time period, or dictionary of ticker, change pairs. """ + tickers_tracker = optional_rich_track( + tickers, False, "Gathering stock prices", len(tickers) + ) current_user = get_current_user() - - url = f"""https://financialmodelingprep.com/api/v3/historical-price-full/{ticker}?\ + data_aggregate = dict() + + for tick in tickers_tracker: + tickers_req = str(tick) + "," + for _ in range(4): + try: + _tick = next(tickers_tracker) + tickers_req += _tick + "," + except StopIteration: + break + + url = f"""https://financialmodelingprep.com/api/v3/historical-price-full/{tickers_req}?\ from={start_date}&to={end_date}&serietype=line\ &apikey={current_user.credentials.API_KEY_FINANCIALMODELINGPREP}""" - response = request(url) - if response.status_code != 200 or "Error Message" in response.json(): - message = f"Error, Status Code: {response.status_code}." - message = ( - message - if "Error Message" not in response.json() - else message + "\n" + response.json()["Error Message"] + ".\n" - ) - console.print(message) - return None - data = response.json() - close_end = data["historical"][0]["close"] - close_start = data["historical"][-1]["close"] - pct_change = 100 * (close_end - close_start) / close_start + response = request(url) + if response.status_code != 200 or "Error Message" in response.json(): + message = f"Error, Status Code: {response.status_code}." + message = ( + message + if "Error Message" not in response.json() + else message + "\n" + response.json()["Error Message"] + ".\n" + ) + console.print(message) + return dict() + + data = response.json() + stock_list = data + if "historicalStockList" in data: + stock_list = data["historicalStockList"] + + for stock in stock_list: + close_end = stock["historical"][0]["close"] + close_start = stock["historical"][-1]["close"] + pct_change = 100 * (close_end - close_start) / close_start + data_aggregate[stock["symbol"]] = pct_change - return pct_change + return data_aggregate @log_start_end(log=logger) @check_api_key(["API_KEY_FINANCIALMODELINGPREP"]) -def get_etf_holdings(ticker: str) -> List[Dict[str, Any]]: +def get_etf_holdings(ticker: str, limit: int = 10) -> List[Dict[str, Any]]: """This endpoint returns all stocks held by a specific ETF. Parameters ---------- ticker : str ETF ticker. + limit: int + Limit amount of stocks to return. FMP returns data + by descending weighting. Returns ------- @@ -127,13 +150,16 @@ def get_etf_holdings(ticker: str) -> List[Dict[str, Any]]: console.print(message) return [] - return response.json() + return response.json()[0:limit] @log_start_end(log=logger) @check_api_key(["API_KEY_FINANCIALMODELINGPREP"]) def get_holdings_pct_change( - ticker: str, start_date: str, end_date: str + ticker: str, + start_date: str, + end_date: str, + limit: int = 10, ) -> pd.DataFrame: """Calculate percent change for each holding in ETF. @@ -141,25 +167,35 @@ def get_holdings_pct_change( ---------- ticker : str ETF ticker. + limit: int + Limit amount of stocks to return. FMP returns data + by descending weighting. Returns ------- pd.DataFrame Calculated percentage change for each stock in the ETF, in descending order. """ - df = pd.DataFrame(columns=["Ticker", "Name", "Percent Change"], data=[]) - holdings = get_etf_holdings(ticker) + df = pd.DataFrame(columns=["Ticker", "Name", "Percent Change"], data=[]) + holdings = get_etf_holdings(ticker, limit) + tickers = [] for stock in holdings: - pct_change = get_stock_price_change(stock["asset"], start_date, end_date) - if pct_change is None: - pct_change = 0 + tickers.append(stock.get("asset", " ")) + pct_changes = get_stock_price_change(tickers, start_date, end_date) + + for stock in holdings: + pct_change = pct_changes.get(stock["asset"], 0) + if pct_change == 0: + console.print( + f"""Percent change not found for: {stock["asset"]}: {stock["name"]}""" + ) new_df = pd.DataFrame( { "Ticker": stock["asset"], "Name": stock["name"], - "Percent Change": pct_change, + "Percent Change": pct_changes.get(stock["asset"], 0), }, index=[0], ) diff --git a/openbb_terminal/etf/fmp_view.py b/openbb_terminal/etf/fmp_view.py index 90c2f8e46d8..14598cdbbbc 100644 --- a/openbb_terminal/etf/fmp_view.py +++ b/openbb_terminal/etf/fmp_view.py @@ -134,21 +134,21 @@ def view_etf_holdings_performance( Parameters ---------- ticker: str - ETF ticker + ETF ticker. start_date: str - Date from which data is fetched in format YYYY-MM-DD + Date from which data is fetched in format YYYY-MM-DD. end: str - Date from which data is fetched in format YYYY-MM-DD + Date from which data is fetched in format YYYY-MM-DD. limit: int - Limit number of holdings to view. Sorted by descending percent change. + Limit number of holdings to view. Sorted by holding percentage (desc). raw: bool Display holding performance sheet_name: str Optionally specify the name of the sheet the data is exported to. export: str - Type of format to export data + Type of format to export data. """ - data = fmp_model.get_holdings_pct_change(ticker, start_date, end_date).head(limit) + data = fmp_model.get_holdings_pct_change(ticker, start_date, end_date, limit) if raw: print_rich_table( |