summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornectariosouzo <nectariosouzounidis@gmail.com>2023-10-02 19:20:12 -0400
committernectariosouzo <nectariosouzounidis@gmail.com>2023-10-02 19:20:12 -0400
commit4836170cf0ff4d45c5c7797f1f8c332af94ff44a (patch)
treea7daf8c58fb282b00d46359aee8c66219c24e980
parentfed04cfaab32231ec2f832dcbeedf9782f30de99 (diff)
Add progress bar and get bulk prices
-rw-r--r--openbb_terminal/etf/fmp_model.py104
-rw-r--r--openbb_terminal/etf/fmp_view.py12
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(