Files
OpenBB/openbb_terminal/economy/nasdaq_model.py
montezdesousa bfc4c021e7 Fix incorrect date typing in signatures (#3524)
* Report fixes

* replace wrong typing

* mypy

* mypy again

Co-authored-by: james <jmaslek11@gmail.com>
2022-11-22 17:15:40 -05:00

212 lines
6.1 KiB
Python

"""NASDAQ Data Link Model"""
__docformat__ = "numpy"
import argparse
import logging
import os
from typing import List, Optional, Union
from datetime import datetime as dt
import pandas as pd
import requests
from openbb_terminal.config_terminal import API_KEY_QUANDL
from openbb_terminal.decorators import check_api_key, log_start_end
from openbb_terminal.rich_config import console
logger = logging.getLogger(__name__)
@log_start_end(log=logger)
def get_economic_calendar(
countries: Union[List[str], str] = "",
start_date: Optional[str] = None,
end_date: Optional[str] = None,
) -> pd.DataFrame:
"""Get economic calendar for countries between specified dates
Parameters
----------
countries : [List[str],str]
List of countries to include in calendar. Empty returns all
start_date : Optional[str]
Start date for calendar
end_date : Optional[str]
End date for calendar
Returns
-------
pd.DataFrame
Economic calendar
Examples
--------
Get todays economic calendar for the United States
>>> from openbb_terminal.sdk import openbb
>>> calendar = openbb.economy.events("United States")
To get multiple countries for a given date, pass the same start and end date as well as
a list of countries
>>> calendars = openbb.economy.events(["United States","Canada"], start_date="2022-11-18", end_date="2022-11-18")
"""
if start_date is None:
start_date = dt.now().strftime("%Y-%m-%d")
if end_date is None:
end_date = dt.now().strftime("%Y-%m-%d")
if countries == "":
countries = []
if isinstance(countries, str):
countries = [countries]
if start_date == end_date:
dates = [start_date]
else:
dates = (
pd.date_range(start=start_date, end=end_date).strftime("%Y-%m-%d").tolist()
)
calendar = pd.DataFrame()
for date in dates:
try:
df = pd.DataFrame(
requests.get(
f"https://api.nasdaq.com/api/calendar/economicevents?date={date}",
headers={
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) "
"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36"
},
).json()["data"]["rows"]
).replace("&nbsp;", "-")
df.loc[:, "Date"] = date
calendar = pd.concat([calendar, df], axis=0)
except TypeError:
continue
if calendar.empty:
console.print("[red]No data found for date range.[/red]")
return pd.DataFrame()
calendar = calendar.rename(
columns={"gmt": "Time (GMT)", "country": "Country", "eventName": "Event"}
)
calendar = calendar.drop(columns=["description"])
if not countries:
return calendar
calendar = calendar[calendar["Country"].isin(countries)].reset_index(drop=True)
if calendar.empty:
console.print(f"[red]No data found for {','.join(countries)}[/red]")
return pd.DataFrame()
return calendar
@log_start_end(log=logger)
def check_country_code_type(list_of_codes: str) -> List[str]:
"""Check that codes are valid for NASDAQ API"""
nasdaq_codes = list(
pd.read_csv(os.path.join(os.path.dirname(__file__), "NASDAQ_CountryCodes.csv"))[
"Code"
]
)
valid_codes = [
code.upper()
for code in list_of_codes.split(",")
if code.upper() in nasdaq_codes
]
if valid_codes:
return valid_codes
raise argparse.ArgumentTypeError("No valid codes provided.")
@log_start_end(log=logger)
def get_country_codes() -> List[str]:
"""Get available country codes for Bigmac index
Returns
-------
List[str]
List of ISO-3 letter country codes.
"""
file = os.path.join(os.path.dirname(__file__), "NASDAQ_CountryCodes.csv")
codes = pd.read_csv(file, index_col=0)
return codes
@log_start_end(log=logger)
@check_api_key(["API_KEY_QUANDL"])
def get_big_mac_index(country_code: str = "USA") -> pd.DataFrame:
"""Get the Big Mac index calculated by the Economist
Parameters
----------
country_code : str
ISO-3 letter country code to retrieve. Codes available through get_country_codes().
Returns
-------
pd.DataFrame
Dataframe with Big Mac index converted to USD equivalent.
"""
URL = f"https://data.nasdaq.com/api/v3/datasets/ECONOMIST/BIGMAC_{country_code}"
URL += f"?column_index=3&api_key={API_KEY_QUANDL}"
try:
r = requests.get(URL)
except Exception:
console.print("[red]Error connecting to NASDAQ API[/red]\n")
return pd.DataFrame()
df = pd.DataFrame()
if r.status_code == 200:
response_json = r.json()
df = pd.DataFrame(response_json["dataset"]["data"])
df.columns = response_json["dataset"]["column_names"]
df["Date"] = pd.to_datetime(df["Date"])
# Wrong API Key
elif r.status_code == 400:
console.print(r.text)
# Premium Feature
elif r.status_code == 403:
console.print(r.text)
# Catching other exception
elif r.status_code != 200:
console.print(r.text)
return df
@log_start_end(log=logger)
@check_api_key(["API_KEY_QUANDL"])
def get_big_mac_indices(country_codes: List[str] = None) -> pd.DataFrame:
"""Display Big Mac Index for given countries
Parameters
----------
country_codes : List[str]
List of country codes (ISO-3 letter country code). Codes available through economy.country_codes().
Returns
-------
pd.DataFrame
Dataframe with Big Mac indices converted to USD equivalent.
"""
if country_codes is None:
country_codes = ["USA"]
df_cols = ["Date"]
df_cols.extend(country_codes)
big_mac = pd.DataFrame(columns=df_cols)
for country in country_codes:
df1 = get_big_mac_index(country)
if not df1.empty:
big_mac[country] = df1["dollar_price"]
big_mac["Date"] = df1["Date"]
big_mac.set_index("Date", inplace=True)
return big_mac