summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Maslek <jmaslek11@gmail.com>2022-10-21 09:36:31 -0400
committerGitHub <noreply@github.com>2022-10-21 15:36:31 +0200
commit70d35ff598553069421e7e20a67671bdd47d030b (patch)
tree989a4383fb93978fe31ead1ab7da93b6d95344b8
parent459e103a5a565217e99150ced13a0fc7899d9283 (diff)
Economic calendar (#2936)
* First push * Second commit * Comment out 'spread' * list to List
-rw-r--r--.pre-commit-config.yaml6
-rw-r--r--openbb_terminal/economy/economy_controller.py95
-rw-r--r--openbb_terminal/economy/nasdaq_model.py69
-rw-r--r--openbb_terminal/economy/nasdaq_view.py32
-rw-r--r--openbb_terminal/miscellaneous/data_sources_default.json4
-rw-r--r--tests/openbb_terminal/economy/cassettes/test_nasdaq_model/test_get_economic_calendar.yaml287
-rw-r--r--tests/openbb_terminal/economy/cassettes/test_nasdaq_model/test_get_economic_calendar_bad_country_name.yaml285
-rw-r--r--tests/openbb_terminal/economy/cassettes/test_nasdaq_view/test_display_economic_calendar.yaml292
-rw-r--r--tests/openbb_terminal/economy/cassettes/test_nasdaq_view/test_display_economic_calendar_bad_country.yaml292
-rw-r--r--tests/openbb_terminal/economy/csv/test_nasdaq_model/test_get_economic_calendar.csv35
-rw-r--r--tests/openbb_terminal/economy/csv/test_nasdaq_model/test_get_economic_calendar_bad_country_name.csv1
-rw-r--r--tests/openbb_terminal/economy/test_economy_controller.py42
-rw-r--r--tests/openbb_terminal/economy/test_nasdaq_model.py18
-rw-r--r--tests/openbb_terminal/economy/test_nasdaq_view.py16
-rw-r--r--tests/openbb_terminal/economy/txt/test_economy_controller/test_print_help.txt5
-rw-r--r--tests/openbb_terminal/economy/txt/test_nasdaq_view/test_display_economic_calendar.txt5
-rw-r--r--tests/openbb_terminal/economy/txt/test_nasdaq_view/test_display_economic_calendar_bad_country.txt1
-rw-r--r--website/content/terminal/economy/events/_index.md88
18 files changed, 1496 insertions, 77 deletions
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 91939833359..366a280762b 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -9,7 +9,7 @@ repos:
args:
[
"--ignore-files=settings_controller.py,featflags_controller.py,keys_controller.py,degiro_controller.py,",
- "--ignore-commands=login,alswe,info_swe,goodness,resources,yf,yolo,from,to,featflags,guess,settings,survey,intro",
+ "--ignore-commands=login,alswe,info_swe,goodness,resources,yf,yolo,from,to,featflags,guess,settings,survey,intro"
]
entry: python custom_pre_commit/check_doc.py
- repo: https://github.com/pre-commit/pre-commit-hooks
@@ -32,7 +32,7 @@ repos:
- id: flake8
entry: flake8 --ignore=E203,W503 --max-line-length=122 --exclude ./build/pyinstaller/*
- repo: https://github.com/codespell-project/codespell
- rev: v2.2.1
+ rev: v2.2.2
hooks:
- id: codespell
entry: codespell
@@ -68,7 +68,7 @@ repos:
["--baseline", ".secrets.baseline", "--exclude-files", "cassettes/*", "--exclude-files", "website/content/api/*"]
exclude: package.lock.json
- repo: https://github.com/asottile/pyupgrade
- rev: v3.0.0
+ rev: v3.1.0
hooks:
- id: pyupgrade
args: [--py38-plus]
diff --git a/openbb_terminal/economy/economy_controller.py b/openbb_terminal/economy/economy_controller.py
index 2a6bb319542..db409b83d76 100644
--- a/openbb_terminal/economy/economy_controller.py
+++ b/openbb_terminal/economy/economy_controller.py
@@ -6,7 +6,7 @@ import argparse
import logging
import os
import itertools
-from datetime import date
+from datetime import date, datetime as dt
from typing import List, Dict, Any
import pandas as pd
@@ -69,7 +69,7 @@ class EconomyController(BaseController):
"rtps",
"bigmac",
"ycrv",
- "spread",
+ # "spread",
"events",
"edebt",
]
@@ -388,7 +388,8 @@ class EconomyController(BaseController):
mt.add_cmd("map")
mt.add_cmd("bigmac")
mt.add_cmd("ycrv")
- mt.add_cmd("spread")
+ # Comment out spread while investpy is donw :()
+ # mt.add_cmd("spread")
mt.add_cmd("events")
mt.add_cmd("edebt")
mt.add_raw("\n")
@@ -1269,33 +1270,17 @@ class EconomyController(BaseController):
"--country",
action="store",
dest="country",
- nargs="+",
- default="all",
+ type=str,
+ default="",
help="Display calendar for specific country.",
)
parser.add_argument(
- "-i",
- "--importance",
- action="store",
- dest="importance",
- choices=investingcom_model.IMPORTANCES,
- help="Event importance classified as high, medium, low or all.",
- )
- parser.add_argument(
- "--categories",
- action="store",
- dest="category",
- choices=investingcom_model.CATEGORIES,
- default=None,
- help="Event category.",
- )
- parser.add_argument(
"-s",
"--start",
dest="start_date",
type=valid_date,
help="The start date of the data (format: YEAR-MONTH-DAY, i.e. 2010-12-31)",
- default=None,
+ default=dt.now().strftime("%Y-%m-%d"),
)
parser.add_argument(
"-e",
@@ -1303,8 +1288,32 @@ class EconomyController(BaseController):
dest="end_date",
type=valid_date,
help="The start date of the data (format: YEAR-MONTH-DAY, i.e. 2010-12-31)",
+ default=dt.now().strftime("%Y-%m-%d"),
+ )
+ parser.add_argument(
+ "-d",
+ "--date",
+ dest="spec_date",
+ type=valid_date,
+ help="Get a specific date for events. Overrides start and end dates.",
default=None,
)
+ parser.add_argument(
+ "-i",
+ "--importance",
+ action="store",
+ dest="importance",
+ choices=investingcom_model.IMPORTANCES,
+ help="Event importance classified as high, medium, low or all.",
+ )
+ parser.add_argument(
+ "--categories",
+ action="store",
+ dest="category",
+ choices=investingcom_model.CATEGORIES,
+ default=None,
+ help="[INVESTING source only] Event category.",
+ )
ns_parser = self.parse_known_args_and_warn(
parser,
other_args,
@@ -1315,7 +1324,8 @@ class EconomyController(BaseController):
if ns_parser:
if isinstance(ns_parser.country, list):
- ns_parser.country = " ".join(ns_parser.country)
+ if ns_parser.source == "Investing":
+ ns_parser.country = " ".join(ns_parser.country)
if ns_parser.start_date:
start_date = ns_parser.start_date.strftime("%Y-%m-%d")
@@ -1327,15 +1337,36 @@ class EconomyController(BaseController):
else:
end_date = None
- investingcom_view.display_economic_calendar(
- country=ns_parser.country,
- importance=ns_parser.importance,
- category=ns_parser.category,
- start_date=start_date,
- end_date=end_date,
- limit=ns_parser.limit,
- export=ns_parser.export,
- )
+ if ns_parser.source == "Investing":
+ investingcom_view.display_economic_calendar(
+ country=ns_parser.country,
+ importance=ns_parser.importance,
+ category=ns_parser.category,
+ start_date=start_date,
+ end_date=end_date,
+ limit=ns_parser.limit,
+ export=ns_parser.export,
+ )
+ elif ns_parser.source == "Nasdaq":
+ countries = (
+ ns_parser.country.replace("_", " ").title().split(",")
+ if ns_parser.country
+ else []
+ )
+
+ if ns_parser.spec_date:
+ start_date = ns_parser.spec_date.strftime("%Y-%m-%d")
+ end_date = ns_parser.spec_date.strftime("%Y-%m-%d")
+
+ else:
+ start_date, end_date = sorted([start_date, end_date])
+ nasdaq_view.display_economic_calendar(
+ country=countries,
+ start_date=start_date,
+ end_date=end_date,
+ limit=ns_parser.limit,
+ export=ns_parser.export,
+ )
@log_start_end(log=logger)
def call_plot(self, other_args: List[str]):
diff --git a/openbb_terminal/economy/nasdaq_model.py b/openbb_terminal/economy/nasdaq_model.py
index 00e7943b159..d0c1b5b22de 100644
--- a/openbb_terminal/economy/nasdaq_model.py
+++ b/openbb_terminal/economy/nasdaq_model.py
@@ -4,8 +4,9 @@ __docformat__ = "numpy"
import argparse
import logging
import os
-from typing import List
+from typing import List, Union
+from datetime import datetime as dt
import pandas as pd
import requests
@@ -17,6 +18,72 @@ logger = logging.getLogger(__name__)
@log_start_end(log=logger)
+def get_economic_calendar(
+ countries: Union[List[str], str] = "",
+ start_date: str = dt.now().strftime("%Y-%m-%d"),
+ end_date: str = dt.now().strftime("%Y-%m-%d"),
+) -> 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 : str
+ Start date for calendar
+ end_date : str
+ End date for calendar
+
+ Returns
+ -------
+ pd.DataFrame
+ Economic calendar
+ """
+ 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(
diff --git a/openbb_terminal/economy/nasdaq_view.py b/openbb_terminal/economy/nasdaq_view.py
index 6cb05b6cb40..62e47428fe8 100644
--- a/openbb_terminal/economy/nasdaq_view.py
+++ b/openbb_terminal/economy/nasdaq_view.py
@@ -24,6 +24,38 @@ logger = logging.getLogger(__name__)
@log_start_end(log=logger)
+def display_economic_calendar(
+ country: str, start_date: str, end_date: str, limit: int = 10, export: str = ""
+) -> None:
+ """Display economic calendar for specified country between start and end dates
+
+ Parameters
+ ----------
+ country : str
+ Country to display calendar for
+ start_date : str
+ Start date for calendar
+ end_date : str
+ End date for calendar
+ limit : int
+ Limit number of rows to display
+ export : str
+ Export data to csv or excel file
+ """
+ df = nasdaq_model.get_economic_calendar(country, start_date, end_date)
+ if df.empty:
+ return
+ print_rich_table(
+ df.head(limit),
+ title="Economic Calendar",
+ show_index=False,
+ headers=df.columns,
+ )
+ console.print()
+ export_data(export, os.path.dirname(os.path.abspath(__file__)), "events", df)
+
+
+@log_start_end(log=logger)
@check_api_key(["API_KEY_QUANDL"])
def display_big_mac_index(
country_codes: List[str] = None,
diff --git a/openbb_terminal/miscellaneous/data_sources_default.json b/openbb_terminal/miscellaneous/data_sources_default.json
index 69abfc2ca25..c5866995949 100644
--- a/openbb_terminal/miscellaneous/data_sources_default.json
+++ b/openbb_terminal/miscellaneous/data_sources_default.json
@@ -471,8 +471,8 @@
"futures": ["WallStreetJournal", "Finviz"],
"map": ["Finviz"],
"bigmac": ["Nasdaq"],
- "ycrv": ["Investing", "FRED"],
- "events": ["Investing"],
+ "ycrv": ["FRED","Investing"],
+ "events": ["Nasdaq","Investing"],
"edebt": ["Wikipedia"],
"rtps": ["AlphaVantage"],
"valuation": ["Finviz"],
diff --git a/tests/openbb_terminal/economy/cassettes/test_nasdaq_model/test_get_economic_calendar.yaml b/tests/openbb_terminal/economy/cassettes/test_nasdaq_model/test_get_economic_calendar.yaml
new file mode 100644
index 00000000000..be450ac9300
--- /dev/null
+++ b/tests/openbb_terminal/economy/cassettes/test_nasdaq_model/test_get_economic_calendar.yaml
@@ -0,0 +1,287 @@
+interactions:
+- request:
+ body: null
+ headers:
+ Accept:
+ - '*/*'
+ Accept-Encoding:
+ - gzip, deflate
+ Connection:
+ - keep-alive
+ 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
+ method: GET
+ uri: https://api.nasdaq.com/api/calendar/economicevents?date=2022-10-20
+ response:
+ body:
+ string: !!binary |
+ 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
+ headers:
+ Cache-Control:
+ - max-age=0, no-cache, no-store
+ Connection:
+ - keep-alive
+ Content-Encoding:
+ - gzip
+ Content-Length:
+ - '5794'
+ Content-Type:
+ - application/json; charset=utf-8
+ Date:
+ - Thu, 20 Oct 2022 18:39:21 GMT
+ Expires:
+ - Thu, 20 Oct 2022 18:39:21 GMT
+ Pragma:
+ - no-cache
+ Server:
+ - Kestrel
+ Set-Cookie:
+ - ak_bmsc=1242A8EC1F36C47371F1457E7DB3DBB4~000000000000000000000000000000~YAAQNmdNaNQvE+mDAQAA9lix9hGHUpglbH6QFrpy75NqGEHA4l7C3n6udz2BXpi1d1nrGpy1B0oQ2lH8MNnSc8mC+sqAKyEjDEg4mvaKWdQZFWzqUPR0UNeBJOeOJG5vONWuDBEJrrBXFcHpDI/JN7yOhjwFOFn00+NJHy9XkoqgDhoVzEbCfaJuQ99TcTOoUzJOhxTaJ2RmJumD1MSZ8yQb3bk/Msdwrwu9GdSWiACJMPPqQG4who1QT+trSrrtuVKWL6XZpcH2lsIurtvhJ/lWURT98qhR4VcENcugrspwAta1dCYvGNkjTnG9ke8cx8USq5fe6go7/XcF26k360Nr88ejkbjL7IVgsJjd18G7Y8hpYZSWH6CRcB0=;
+ Domain=.nasdaq.com; Path=/; Expires=Thu, 20 Oct 2022 20:39:21 GMT; Max-Age=7200;
+ HttpOnly
+ Strict-Transport-Security:
+ - max-age=86400
+ Vary:
+ - Accept-Encoding
+ X-EdgeConnect-MidMile-RTT:
+ - '21'
+ - '21'
+ - '21'
+ X-EdgeConnect-Origin-MEX-Latency:
+ - '32'
+ - '32'
+ - '32'
+ gid:
+ - '104'
+ lang:
+ - en
+ rid:
+ - 4663e294-866f-4eff-b17d-91f36a716833
+ srctype:
+ - default
+ status:
+ code: 200
+ message: OK
+- request:
+ body: null
+ headers:
+ Accept:
+ - '*/*'
+ Accept-Encoding:
+ - gzip, deflate
+ Connection:
+ - keep-alive
+ 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
+ method: GET
+ uri: https://api.nasdaq.com/api/calendar/economicevents?date=2022-10-21
+ response:
+ body:
+ string: !!binary |
+ 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
+ NzAPQ+VTRXRsgwBsoZ0P6BtpDG79h2Fbp