diff --git a/gamestonk_terminal/config_terminal.py b/gamestonk_terminal/config_terminal.py
index f1b8757890d..6939d823cee 100644
--- a/gamestonk_terminal/config_terminal.py
+++ b/gamestonk_terminal/config_terminal.py
@@ -25,3 +25,6 @@ API_POLYGON_KEY = os.getenv("GT_API_POLYGON_KEY") or "REPLACE_ME"
API_TWITTER_KEY = os.getenv("GT_API_TWITTER_KEY") or "REPLACE_ME"
API_TWITTER_SECRET_KEY = os.getenv("GT_API_TWITTER_SECRET_KEY") or "REPLACE_ME"
API_TWITTER_BEARER_TOKEN = os.getenv("GT_API_TWITTER_BEARER_TOKEN") or "REPLACE_ME"
+
+# https://fred.stlouisfed.org/docs/api/api_key.html
+API_FRED_KEY = os.getenv("GT_FRED_API_KEY") or "REPLACE_ME"
diff --git a/gamestonk_terminal/fred/README.md b/gamestonk_terminal/fred/README.md
new file mode 100644
index 00000000000..f781a1ac1e4
--- /dev/null
+++ b/gamestonk_terminal/fred/README.md
@@ -0,0 +1,124 @@
+# FRED
+
+https://fred.stlouisfed.org
+
+The purpose of fred is to have the ability to look at economic data. This page offers 2 options:
+
+* [predefined](#gdp)
+ * Get predefined data
+* [cust](#cust)
+ * Get custom fred data
+
+The current predefined options are
+* GDP
+* 1,5,10,30 Year Treasury Rates
+* 30 Year Mortgage Rates
+* Unemployment Rate
+* Effective Federal Funds rate
+* Moody's AAA Corporate Bond
+* CAD to USD Conversion.
+
+## predefined
+```text
+usage: selected [-n N_TO_GET] [-s START_DATE] [--noplot] [--hidedata]
+```
+Gets predefined data. Arguments
+* selected : Key from the predefined list.
+* -s : Start Date. Format YYYY-mm-dd. First point to get. Defaults to Jan 1 2019
+* --noplot : Flag to hide plot
+* --hidedata : Flag to suppress printing output. Useful for data released daily/weekly.
+
+To plot the 30-Year Mortgage rates since 2018-01-01 suppressing the output.
+````
+mort30 -s 2018-01-01 --hidedata
+````
+
+
+
+To show all GDP data since 1/1/2016, with no plot.
+````
+gdp -s 2016-01-01 --noplot
+````
+Output:
+````
+ GDP
+Date
+2016-01-01 18470.156
+2016-04-01 18656.207
+2016-07-01 18821.359
+2016-10-01 19032.580
+2017-01-01 19237.435
+2017-04-01 19379.232
+2017-07-01 19617.288
+2017-10-01 19937.963
+2018-01-01 20242.215
+2018-04-01 20552.653
+2018-07-01 20742.723
+2018-10-01 20909.853
+2019-01-01 21115.309
+2019-04-01 21329.877
+2019-07-01 21540.325
+2019-10-01 21747.394
+2020-01-01 21561.139
+2020-04-01 19520.114
+2020-07-01 21170.252
+2020-10-01 21487.896
+````
+
+
+## cust
+
+The fred database has many different datasets freely available. They each have their own custom SERIES_ID which can be obtained through the website.
+
+````
+usage: cust [-i --id] [-s START_DATE] [--noplot] [--hidedata]
+````
+* -i/--id : Series ID for FRED data. Required argument
+* -s : Start Date. Format YYYY-mm-dd. First point to get. Defaults to Jan 1 2015.
+* --noplot : Flag to suppress output plot.
+* --hidedata : Flag to suppress data output
+
+An example of custom data could be the USD/EURO exchange rate.
+According to https://fred.stlouisfed.org/series/DEXUSEU , the series ID is DEXUSEU. So to plot this from the start of February 2021 to now (3/17)
+
+````
+cust --id DEXUSEU -s 2021-02-01
+````
+This will plot and display:
+
+
+````
+ DEXUSEU
+Date
+2021-02-01 1.2070
+2021-02-02 1.2020
+2021-02-03 1.2025
+2021-02-04 1.1974
+2021-02-05 1.2035
+2021-02-08 1.2045
+2021-02-09 1.2106
+2021-02-10 1.2132
+2021-02-11 1.2127
+2021-02-12 1.2126
+2021-02-15 NaN
+2021-02-16 1.2107
+2021-02-17 1.2042
+2021-02-18 1.2078
+2021-02-19 1.2136
+2021-02-22 1.2155
+2021-02-23 1.2142
+2021-02-24 1.2143
+2021-02-25 1.2229
+2021-02-26 1.2093
+2021-03-01 1.2054
+2021-03-02 1.2079
+2021-03-03 1.2073
+2021-03-04 1.2045
+2021-03-05 1.1914
+2021-03-08 1.1849
+2021-03-09 1.1885
+2021-03-10 1.1900
+2021-03-11 1.1978
+````
+
+Note the NaN on 2-15, which corresponds to President's Day.
\ No newline at end of file
diff --git a/gamestonk_terminal/fred/__init__.py b/gamestonk_terminal/fred/__init__.py
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/gamestonk_terminal/fred/fred_api.py b/gamestonk_terminal/fred/fred_api.py
new file mode 100644
index 00000000000..1b90ca10e87
--- /dev/null
+++ b/gamestonk_terminal/fred/fred_api.py
@@ -0,0 +1,191 @@
+import argparse
+import pandas as pd
+from pandas.plotting import register_matplotlib_converters
+import matplotlib.pyplot as plt
+from fredapi import Fred
+from gamestonk_terminal.helper_funcs import (
+ parse_known_args_and_warn,
+ valid_date,
+ plot_autoscale,
+)
+from gamestonk_terminal.config_plot import PLOT_DPI
+from gamestonk_terminal.config_terminal import API_FRED_KEY
+from gamestonk_terminal import feature_flags as gtff
+
+register_matplotlib_converters()
+
+api_map = {
+ "gdp": "GDP",
+ "t10": "DGS10",
+ "t1": "DGS1",
+ "t5": "DGS5",
+ "t30": "DGS30",
+ "mort30": "MORTGAGE30US",
+ "fedrate": "FEDFUNDS",
+ "moodAAA": "AAA",
+ "usdcad": "DEXCAUS",
+ "unemp": "UNRATE",
+}
+title_map = {
+ "gdp": "Gross Domestic Product",
+ "t10": "10-Year Treasury Constant Maturity Rate",
+ "t1": "1-Year Treasury Constant Maturity Rate",
+ "t5": "5-Year Treasury Constant Maturity Rate",
+ "t30": "30-Year Treasury Constant Maturity Rate",
+ "mort30": "30-Year Mortgage Rate",
+ "fedrate": "Effective Federal Funds Rate",
+ "moodAAA": "Moody's Seasoned AAA Corporate Bond Yield",
+ "usdcad": "Canada / U.S. Foreign Exchange Rate",
+ "unemp": "Unemployment Rate",
+}
+
+
+def get_fred_data(l_args, choice):
+ fred = Fred(api_key=API_FRED_KEY)
+
+ parser = argparse.ArgumentParser(
+ add_help=False,
+ prog="Custom",
+ description="""
+ Custom Data
+ """,
+ )
+
+ parser.add_argument(
+ "-s",
+ dest="start_date",
+ type=valid_date,
+ default="2019-01-01",
+ required=False,
+ help="Starting date (YYYY-MM-DD) of data",
+ )
+
+ parser.add_argument(
+ "--noplot",
+ action="store_false",
+ default=True,
+ dest="noplot",
+ help="Suppress output plot",
+ )
+
+ parser.add_argument(
+ "--hidedata",
+ action="store_false",
+ default=True,
+ dest="hidedata",
+ help="Suppress data display plot",
+ )
+
+ try:
+ ns_parser = parse_known_args_and_warn(parser, l_args)
+
+ if not ns_parser:
+ return
+
+ string_to_get = api_map[choice]
+ title = title_map[choice]
+ data = fred.get_series(string_to_get, ns_parser.start_date)
+
+ data = pd.DataFrame(data, columns=[f"{string_to_get}"])
+ data.index.name = "Date"
+ if ns_parser.hidedata:
+ print(data)
+ print("")
+ if ns_parser.noplot:
+ plt.figure(figsize=plot_autoscale(), dpi=PLOT_DPI)
+ plt.plot(data.index, data.iloc[:, 0], "-ok")
+ plt.xlabel("Time")
+ plt.xlim(data.index[0], data.index[-1])
+ plt.ylabel(f"{string_to_get}")
+ plt.grid(b=True, which="major", color="#666666", linestyle="-")
+ plt.minorticks_on()
+ plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2)
+ plt.title(title)
+ plt.show()
+ print("")
+
+ if gtff.USE_ION:
+ plt.ion()
+
+ except SystemExit:
+ print("")
+ except Exception as e:
+ print(e)
+ print("")
+ return
+
+
+def custom_data(l_args):
+ fred = Fred(api_key=API_FRED_KEY)
+
+ parser = argparse.ArgumentParser(
+ add_help=False,
+ prog="Custom",
+ description="""
+ Custom Data
+ """,
+ )
+ parser.add_argument(
+ "-i", "--id", dest="series_id", required=True, type=str, help="FRED Series ID"
+ )
+
+ parser.add_argument(
+ "-s",
+ dest="start_date",
+ type=valid_date,
+ default="2019-01-01",
+ required=False,
+ help="Starting date (YYYY-MM-DD) of data",
+ )
+
+ parser.add_argument(
+ "--noplot",
+ action="store_false",
+ default=True,
+ dest="noplot",
+ help="Suppress output plot",
+ )
+
+ parser.add_argument(
+ "--hidedata",
+ action="store_false",
+ default=True,
+ dest="hidedata",
+ help="Suppress data display plot",
+ )
+
+ try:
+ ns_parser = parse_known_args_and_warn(parser, l_args)
+
+ if not ns_parser:
+ return
+
+ data = fred.get_series(ns_parser.series_id, ns_parser.start_date)
+
+ data = pd.DataFrame(data, columns=[f"{ns_parser.series_id}"])
+ data.index.name = "Date"
+ if ns_parser.hidedata:
+ print(data)
+ print("")
+ if ns_parser.noplot:
+ plt.figure(figsize=plot_autoscale(), dpi=PLOT_DPI)
+ plt.plot(data.index, data.iloc[:, 0], "-ok")
+ plt.xlabel("Time")
+ plt.xlim(data.index[0], data.index[-1])
+ plt.ylabel(f"{ns_parser.series_id}")
+ plt.grid(b=True, which="major", color="#666666", linestyle="-")
+ plt.minorticks_on()
+ plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2)
+ plt.title(f"FRED {ns_parser.series_id} Series")
+ plt.show()
+ print("")
+
+ if gtff.USE_ION:
+ plt.ion()
+
+ except SystemExit:
+ print("")
+ except Exception as e:
+ print(e)
+ print("")
+ return
diff --git a/gamestonk_terminal/fred/fred_menu.py b/gamestonk_terminal/fred/fred_menu.py
new file mode 100644
index 00000000000..5a7734835be
--- /dev/null
+++ b/gamestonk_terminal/fred/fred_menu.py
@@ -0,0 +1,90 @@
+import argparse
+from matplotlib import pyplot as plt
+from prompt_toolkit.completion import NestedCompleter
+from gamestonk_terminal import feature_flags as gtff
+from gamestonk_terminal.helper_funcs import get_flair
+from gamestonk_terminal.menu import session
+from gamestonk_terminal.fred import fred_api
+
+
+def print_fred():
+ """ Print help """
+
+ print("\nFred Economic Data:")
+ print(" help show this menu again")
+ print(" q quit this menu, and shows back to main menu")
+ print(" quit quit to abandon program")
+ print(" ")
+ print(" gdp GDP")
+ print(" unemp Unemployment Rate")
+ print(" t1 1-Year Treasury Constant Maturity Rate")
+ print(" t5 5-Year Treasury Constant Maturity Rate")
+ print(" t10 10-Year Treasury Constant Maturity Rate")
+ print(" t30 30-Year Treasury Constant Maturity Rate")
+ print(" mort30 30-Year Fixed Rate Mortgage Average")
+ print(" fedrate Effective Federal Funds Rate")
+ print(" moodAAA Moody's Seasoned AAA Corporate Bond Yield")
+ print(" usdcad Canada / U.S. Foreign Exchange Rate (CAD per 1 USD)")
+ print("")
+ print(" cust User Specified FRED Data - Please Specify --id")
+ print("")
+ return
+
+
+def fred_menu():
+ plt.close("all")
+ fred_parser = argparse.ArgumentParser(prog="fred", add_help=False)
+ defined_choices = [
+ "gdp",
+ "unemp",
+ "t1",
+ "t5",
+ "t10",
+ "t30",
+ "mort30",
+ "fedrate",
+ "moodAAA",
+ "usdcad",
+ ]
+ choices = ["help", "q", "quit", "cust"] + defined_choices
+
+ fred_parser.add_argument("cmd", choices=choices)
+ completer = NestedCompleter.from_nested_dict({c: None for c in choices})
+
+ should_print_help = True
+ while True:
+ if should_print_help:
+ print_fred()
+ should_print_help = False
+
+ # Get input command from user
+ if session and gtff.USE_PROMPT_TOOLKIT:
+ as_input = session.prompt(
+ f"{get_flair()} (fred)> ",
+ completer=completer,
+ )
+ else:
+ as_input = input(f"{get_flair()} (fred)> ")
+ try:
+ (ns_known_args, l_args) = fred_parser.parse_known_args(as_input.split())
+
+ except SystemExit:
+ print("The command selected doesn't exist\n")
+ continue
+
+ if ns_known_args.cmd == "help":
+ should_print_help = True
+
+ elif ns_known_args.cmd == "q":
+ # Leave the fred menu
+ return False
+
+ elif ns_known_args.cmd == "quit":
+ # Abandon the program
+ return True
+
+ elif ns_known_args.cmd in defined_choices:
+ fred_api.get_fred_data(l_args, ns_known_args.cmd)
+
+ elif ns_known_args.cmd == "cust":
+ fred_api.custom_data(l_args)
diff --git a/gamestonk_terminal/helper_funcs.py b/gamestonk_terminal/helper_funcs.py
index 17e255bba25..1f0ab039d11 100644
--- a/gamestonk_terminal/helper_funcs.py
+++ b/gamestonk_terminal/helper_funcs.py
@@ -357,6 +357,16 @@ def get_flair() -> str:
return ""
+def str_to_bool(value):
+ if isinstance(value, bool):
+ return value
+ if value.lower() in {"false", "f", "0", "no", "n"}:
+ return False
+ if value.lower() in {"true", "t", "1", "yes", "y"}:
+ return True
+ raise ValueError(f"{value} is not a valid boolean value")
+
+
def get_screeninfo():
screens = get_monitors() # Get all available monitors
if len(screens) - 1 < cfgPlot.MONITOR: # Check to see if chosen monitor is detected
diff --git a/gamestonk_terminal/main_helper.py b/gamestonk_terminal/main_helper.py
index 30e9905287c..78272a3b092 100644
--- a/gamestonk_terminal/main_helper.py
+++ b/gamestonk_terminal/main_helper.py
@@ -53,6 +53,10 @@ def print_help(s_ticker, s_start, s_interval, b_is_market_open):
print(
" sen sentiment of the market, \t from: reddit, stocktwits, twitter"
)
+ print(
+ " fred economic data, \t\t\t from: Federal Reserve Bank of St. Louis "
+ )
+
if s_ticker:
print(
" res research web page, \t e.g.: macroaxis, yahoo finance, fool"
diff --git a/poetry.lock b/poetry.lock
index 5b554d913be..45b449e6623 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -476,6 +476,17 @@ category = "main"
optional = true
python-versions = "*"
+[[package]]
+name = "fredapi"
+version = "0.4.3"
+description = "Python API for Federal Reserve Economic Data (FRED) from St. Louis Fed"
+category = "main"
+optional = false
+python-versions = "*"
+
+[package.dependencies]
+pandas = "*"
+
[[package]]
name = "ftfy"
version = "5.9"
@@ -2506,7 +2517,8 @@ prediction = ["fbprophet", "tensorflow", "pmdarima", "transformers", "flair", "t
[metadata]
lock-version = "1.1"
python-versions = "^3.6.8"
-content-hash = "c4a363cd8824c8ccab409ccfc74956db82f9cf9800cd46539b14c7ea927f36de"
+content-hash = "184502c6b8d4b7db5baa4323e7f70b2585c6140c304583f0678e24681b8f9c9b"
+
[metadata.files]
absl-py = [
@@ -2810,6 +2822,10 @@ flatbuffers = [
{file = "flatbuffers-1.12-py2.py3-none-any.whl", hash = "sha256:9e9ef47fa92625c4721036e7c4124182668dc6021d9e7c73704edd395648deb9"},
{file = "flatbuffers-1.12.tar.gz", hash = "sha256:63bb9a722d5e373701913e226135b28a6f6ac200d5cc7b4d919fa38d73b44610"},
]
+fredapi = [
+ {file = "fredapi-0.4.3-py3-none-any.whl", hash = "sha256:e06075592eabddadfe0635f3c59e9072c9f48647430328b4582171ea10f7df2f"},
+ {file = "fredapi-0.4.3.tar.gz", hash = "sha256:d9b3194fb60541991bd33f019c710d4a9580ecfb5e47efbf2d2571888a2aac02"},
+]
ftfy = [
{file = "ftfy-5.9.tar.gz", hash = "sha256:8c4fb2863c0b82eae2ab3cf353d9ade268dfbde863d322f78d6a9fd5cefb31e9"},
]
diff --git a/pyproject.toml b/pyproject.toml
index e775e13f428..84c831a6e37 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -38,6 +38,7 @@ jupyter = "^1.0.0"
mplfinance = "^0.12.7-alpha.7"
seaborn = "^0.11.0"
scipy = "1.5.4"
+fredapi = "^0.4.3"
screeninfo = "^0.6.7"
[tool.poetry.dev-dependencies]
diff --git a/requirements.txt b/requirements.txt
index 8c767a55b06..06971cc844c 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -25,6 +25,7 @@ decorator==4.4.2; python_full_version >= "3.6.1" and python_version >= "3.6" and
defusedxml==0.7.1; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6"
entrypoints==0.3; python_version >= "3.6"
finviz==1.3.4
+fredapi==0.4.3
fundamentalanalysis==0.2.6
hijri-converter==2.1.1; python_version >= "3.6"
holidays==0.10.5.2
diff --git a/terminal.py b/terminal.py
index 48c7e7cab05..7fdcdf2f797 100644
--- a/terminal.py
+++ b/terminal.py
@@ -22,6 +22,7 @@ from gamestonk_terminal.papermill import papermill_controller as mill
from gamestonk_terminal.sentiment import sen_menu as sm
from gamestonk_terminal.technical_analysis import ta_menu as tam
from gamestonk_terminal.comparison_analysis import ca_menu as cam
+from gamestonk_terminal.fred import fred_menu as fm
# import warnings
# warnings.simplefilter("always")
@@ -71,6 +72,7 @@ def main():
"dd",
"pred",
"ca",
+ "fred",
]
menu_parser.add_argument("opt", choices=choices)
completer = NestedCompleter.from_nested_dict({c: None for c in choices})
@@ -178,6 +180,9 @@ def main():
elif ns_known_args.opt == "dd":
b_quit = ddm.dd_menu(df_stock, s_ticker, s_start, s_interval)
+ elif ns_known_args.opt == "fred":
+ b_quit = fm.fred_menu()
+
elif ns_known_args.opt == "pred":
if not gtff.ENABLE_PREDICT: