Improve economy menu (#1036)

* Improve econ search command

* Clean up finviz commands

* Add sorting on all the futures and fix the table column names

* Improve some plotting features

* review comments
This commit is contained in:
jmaslek
2021-12-07 12:12:47 -05:00
committed by GitHub
parent 2afb1bc6d3
commit 3e35a6acd7
7 changed files with 344 additions and 146 deletions

View File

@@ -9,7 +9,7 @@ if env_files:
# Choose one of: stocks, options, crypto, economy, etf, portfolio, forex
DEFAULT_CONTEXT = ""
# Choose one of: developer, user
# Set to True to see full stack traces for debugging/error reporting
DEBUG_MODE = False
# By default the jupyter notebook will be run on port 8888

View File

@@ -241,7 +241,7 @@ def display_cpi(
fig, ax = plt.subplots(figsize=plot_autoscale(), dpi=cfp.PLOT_DPI)
ax.plot(cpi.date, cpi.CPI, marker="o", c="dodgerblue")
ax.set_xlabel("Date")
ax.set_title(f"{int_string} CPI from {year_str}")
ax.set_title(f"{int_string} Consumer Price Index from {year_str}")
ax.set_ylabel("CPI ")
ax.grid("on")
fig.tight_layout()

View File

@@ -7,6 +7,7 @@ from datetime import datetime, timedelta
import os
from typing import List
import pandas as pd
from prompt_toolkit.completion import NestedCompleter
from gamestonk_terminal import feature_flags as gtff
@@ -69,7 +70,6 @@ class EconomyController:
CHOICES_COMMANDS = [
"feargreed",
"events",
"overview",
"indices",
"futures",
@@ -122,8 +122,6 @@ What do you want to do?
CNN:
feargreed CNN Fear and Greed Index
Finnhub:
events economic impact events
Wall St. Journal:
overview market data overview
indices US indices overview
@@ -471,6 +469,22 @@ NASDAQ DataLink (formerly Quandl):
prog="energy",
description="Energy future overview. [Source: Finviz]",
)
parser.add_argument(
"-s",
"--sortby",
dest="sort_col",
type=str,
choices=["ticker", "last", "change", "prevClose"],
default="ticker",
)
parser.add_argument(
"-a",
"-ascend",
dest="ascend",
help="Flag to sort in ascending order",
action="store_true",
default=False,
)
parser.add_argument(
"--export",
choices=["csv", "json", "xlsx"],
@@ -485,6 +499,8 @@ NASDAQ DataLink (formerly Quandl):
finviz_view.display_future(
future_type="Energy",
sort_col=ns_parser.sort_col,
ascending=ns_parser.ascend,
export=ns_parser.export,
)
@@ -497,6 +513,22 @@ NASDAQ DataLink (formerly Quandl):
prog="metals",
description="Metals future overview. [Source: Finviz]",
)
parser.add_argument(
"-s",
"--sortby",
dest="sort_col",
type=str,
choices=["ticker", "last", "change", "prevClose"],
default="ticker",
)
parser.add_argument(
"-a",
"-ascend",
dest="ascend",
help="Flag to sort in ascending order",
action="store_true",
default=False,
)
parser.add_argument(
"--export",
choices=["csv", "json", "xlsx"],
@@ -511,6 +543,8 @@ NASDAQ DataLink (formerly Quandl):
finviz_view.display_future(
future_type="Metals",
sort_col=ns_parser.sort_col,
ascending=ns_parser.ascend,
export=ns_parser.export,
)
@@ -523,6 +557,22 @@ NASDAQ DataLink (formerly Quandl):
prog="meats",
description="Meats future overview. [Source: Finviz]",
)
parser.add_argument(
"-s",
"--sortby",
dest="sort_col",
type=str,
choices=["ticker", "last", "change", "prevClose"],
default="ticker",
)
parser.add_argument(
"-a",
"-ascend",
dest="ascend",
help="Flag to sort in ascending order",
action="store_true",
default=False,
)
parser.add_argument(
"--export",
choices=["csv", "json", "xlsx"],
@@ -537,6 +587,8 @@ NASDAQ DataLink (formerly Quandl):
finviz_view.display_future(
future_type="Meats",
sort_col=ns_parser.sort_col,
ascending=ns_parser.ascend,
export=ns_parser.export,
)
@@ -549,6 +601,22 @@ NASDAQ DataLink (formerly Quandl):
prog="grains",
description="Grains future overview. [Source: Finviz]",
)
parser.add_argument(
"-s",
"--sortby",
dest="sort_col",
type=str,
choices=["ticker", "last", "change", "prevClose"],
default="ticker",
)
parser.add_argument(
"-a",
"-ascend",
dest="ascend",
help="Flag to sort in ascending order",
action="store_true",
default=False,
)
parser.add_argument(
"--export",
choices=["csv", "json", "xlsx"],
@@ -563,6 +631,8 @@ NASDAQ DataLink (formerly Quandl):
finviz_view.display_future(
future_type="Grains",
sort_col=ns_parser.sort_col,
ascending=ns_parser.ascend,
export=ns_parser.export,
)
@@ -575,6 +645,22 @@ NASDAQ DataLink (formerly Quandl):
prog="softs",
description="Softs future overview. [Source: Finviz]",
)
parser.add_argument(
"-s",
"--sortby",
dest="sort_col",
type=str,
choices=["ticker", "last", "change", "prevClose"],
default="ticker",
)
parser.add_argument(
"-a",
"-ascend",
dest="ascend",
help="Flag to sort in ascending order",
action="store_true",
default=False,
)
parser.add_argument(
"--export",
choices=["csv", "json", "xlsx"],
@@ -589,6 +675,8 @@ NASDAQ DataLink (formerly Quandl):
finviz_view.display_future(
future_type="Softs",
sort_col=ns_parser.sort_col,
ascending=ns_parser.ascend,
export=ns_parser.export,
)
@@ -648,10 +736,42 @@ NASDAQ DataLink (formerly Quandl):
"-g",
"--group",
type=str,
default="Sector",
default="sector",
nargs="+",
dest="group",
help="Data group (sector, industry or country)",
choices=list(self.d_GROUPS.keys()),
)
parser.add_argument(
"-s",
"--sortby",
dest="sort_col",
type=str,
choices=[
"Name",
"MarketCap",
"P/E",
"FwdP/E",
"PEG",
"P/S",
"P/B",
"P/C",
"P/FCF",
"EPSpast5Y",
"EPSnext5Y",
"Salespast5Y",
"Change",
"Volume",
],
default="Name",
help="Column to sort by",
)
parser.add_argument(
"-a",
"-ascend",
dest="ascend",
help="Flag to sort in ascending order",
action="store_true",
default=False,
)
parser.add_argument(
"--export",
@@ -661,18 +781,22 @@ NASDAQ DataLink (formerly Quandl):
dest="export",
help="Export dataframe data to csv,json,xlsx file",
)
if other_args:
if "-" not in other_args[0]:
other_args.insert(0, "-g")
other_args = [other_args[0], " ".join(other_args[1:])]
if other_args and "-" not in other_args[0]:
other_args.insert(0, "-g")
ns_parser = parse_known_args_and_warn(parser, other_args)
if not ns_parser:
return
finviz_view.view_group_data(
s_group=self.d_GROUPS[ns_parser.group],
data_type="valuation",
group = (
" ".join(ns_parser.group)
if isinstance(ns_parser.group, list)
else ns_parser.group
)
finviz_view.display_valuation(
s_group=self.d_GROUPS[group],
sort_col=ns_parser.sort_col,
ascending=ns_parser.ascend,
export=ns_parser.export,
)
@@ -691,10 +815,10 @@ NASDAQ DataLink (formerly Quandl):
"-g",
"--group",
type=str,
default="Sector",
default="sector",
nargs="+",
dest="group",
help="Data group (sector, industry or country)",
choices=list(self.d_GROUPS.keys()),
)
parser.add_argument(
"-s",
@@ -735,14 +859,16 @@ NASDAQ DataLink (formerly Quandl):
)
if other_args and "-" not in other_args[0]:
other_args.insert(0, "-g")
ns_parser = parse_known_args_and_warn(parser, other_args)
if not ns_parser:
return
finviz_view.view_group_data(
s_group=self.d_GROUPS[ns_parser.group],
data_type="performance",
group = (
" ".join(ns_parser.group)
if isinstance(ns_parser.group, list)
else ns_parser.group
)
finviz_view.display_performance(
s_group=self.d_GROUPS[group],
sort_col=ns_parser.sort_col,
ascending=ns_parser.ascend,
export=ns_parser.export,
@@ -764,9 +890,9 @@ NASDAQ DataLink (formerly Quandl):
"--group",
type=str,
default="sector",
nargs="+",
dest="group",
help="Data group (sector, industry or country)",
choices=list(self.d_GROUPS.keys()),
)
parser.add_argument(
"--export",
@@ -776,23 +902,22 @@ NASDAQ DataLink (formerly Quandl):
dest="export",
help="Export plot to png,jpg,pdf,svg file",
)
if other_args:
if "-" not in other_args[0]:
other_args.insert(0, "-g")
other_args = [other_args[0], " ".join(other_args[1:])]
if other_args and "-" not in other_args[0]:
other_args.insert(0, "-g")
ns_parser = parse_known_args_and_warn(parser, other_args)
if not ns_parser:
return
finviz_view.view_group_data(
s_group=self.d_GROUPS[ns_parser.group],
data_type="spectrum",
export="",
group = (
" ".join(ns_parser.group)
if isinstance(ns_parser.group, list)
else ns_parser.group
)
finviz_view.display_spectrum(s_group=self.d_GROUPS[group])
# Due to Finviz implementation of Spectrum, we delete the generated spectrum figure
# after saving it and displaying it to the user
os.remove(ns_parser.group + ".jpg")
os.remove(self.d_GROUPS[group] + ".jpg")
@try_except
def call_rtps(self, other_args: List[str]):
@@ -1054,6 +1179,8 @@ NASDAQ DataLink (formerly Quandl):
default=False,
)
if other_args and "-m" not in other_args[0]:
other_args.insert(0, "-m")
ns_parser = parse_known_args_and_warn(
parser, other_args, export_allowed=EXPORT_BOTH_RAW_DATA_AND_FIGURES
)
@@ -1216,6 +1343,13 @@ NASDAQ DataLink (formerly Quandl):
Get historical Big Mac Index [Nasdaq Data Link]
""",
)
parser.add_argument(
"--codes",
help="Flag to show all country codes",
dest="codes",
action="store_true",
default=False,
)
parser.add_argument(
"-c",
"--countries",
@@ -1237,6 +1371,11 @@ NASDAQ DataLink (formerly Quandl):
if not ns_parser:
return
if ns_parser.codes:
file = os.path.join(os.path.dirname(__file__), "NASDAQ_CountryCodes.csv")
print(pd.read_csv(file, index_col=0).to_string(index=False), "\n")
return
nasdaq_view.display_big_mac_index(
country_codes=ns_parser.countries,
raw=ns_parser.raw,

View File

@@ -7,7 +7,6 @@ import pandas as pd
from PIL import Image
from tabulate import tabulate
from matplotlib import pyplot as plt
from gamestonk_terminal import feature_flags as gtff
from gamestonk_terminal.economy import finviz_model
@@ -34,21 +33,18 @@ def map_sp500_view(period: str, map_type: str):
print("")
def view_group_data(
def display_performance(
s_group: str,
data_type: str,
sort_col: str = "Name",
ascending: bool = False,
ascending: bool = True,
export: str = "",
):
"""View group (sectors, industry or country) valuation/performance/spectrum data. [Source: Finviz]
"""View group (sectors, industry or country) performance data. [Source: Finviz]
Parameters
----------
s_group : str
group between sectors, industry or country
data_type : str
select data type to see data between valuation, performance and spectrum
sort_col : str
Column to sort by
ascending : bool
@@ -56,89 +52,148 @@ def view_group_data(
export : str
Export data to csv,json,xlsx or png,jpg,pdf,svg file
"""
if data_type in ("valuation", "performance"):
df_group = finviz_model.get_valuation_performance_data(s_group, data_type)
df_group = df_group.rename(
columns={
"Perf Week": "Week",
"Perf Month": "Month",
"Perf Quart": "3Month",
"Perf Half": "6Month",
"Perf Year": "1Year",
"Perf YTD": "YTD",
"Avg Volume": "AvgVolume",
"Rel Volume": "RelVolume",
}
)
df_group["Week"] = df_group["Week"].apply(lambda x: float(x.strip("%")) / 100)
df_group = df_group.sort_values(by=sort_col, ascending=ascending)
df_group["Volume"] = df_group["Volume"] / 1_000_000
df_group["AvgVolume"] = df_group["AvgVolume"] / 1_000_000
df_group = df_group.rename(
columns={"Volume": "Volume (1M)", "AvgVolume": "AvgVolume (1M)"}
)
if gtff.USE_TABULATE_DF:
print(
tabulate(
df_group.fillna(""),
showindex=False,
headers=df_group.columns,
tablefmt="fancy_grid",
floatfmt=[
"",
".3f",
".3f",
".3f",
".3f",
".3f",
".3f",
".2f",
".0f",
".2f",
".2f",
".0f",
],
)
)
else:
print(df_group.fillna("").to_string(index=False))
print("")
export_data(
export,
os.path.dirname(os.path.abspath(__file__)),
data_type,
df_group,
)
elif data_type == "spectrum":
finviz_model.get_spectrum_data(s_group)
print("")
img = Image.open(s_group + ".jpg")
plt.imshow(img)
export_data(
export,
os.path.dirname(os.path.abspath(__file__)),
"spectrum",
)
img.show()
else:
df_group = finviz_model.get_valuation_performance_data(s_group, "performance")
df_group = df_group.rename(
columns={
"Perf Week": "Week",
"Perf Month": "Month",
"Perf Quart": "3Month",
"Perf Half": "6Month",
"Perf Year": "1Year",
"Perf YTD": "YTD",
"Avg Volume": "AvgVolume",
"Rel Volume": "RelVolume",
}
)
df_group["Week"] = df_group["Week"].apply(lambda x: float(x.strip("%")) / 100)
df_group = df_group.sort_values(by=sort_col, ascending=ascending)
df_group["Volume"] = df_group["Volume"] / 1_000_000
df_group["AvgVolume"] = df_group["AvgVolume"] / 1_000_000
df_group = df_group.rename(
columns={"Volume": "Volume (1M)", "AvgVolume": "AvgVolume (1M)"}
)
if gtff.USE_TABULATE_DF:
print(
"Invalid data type. Choose between valuation, performance and spectrum.\n"
tabulate(
df_group.fillna(""),
showindex=False,
headers=df_group.columns,
tablefmt="fancy_grid",
floatfmt=[
"",
".3f",
".3f",
".3f",
".3f",
".3f",
".3f",
".2f",
".0f",
".2f",
".2f",
".0f",
],
)
)
else:
print(df_group.fillna("").to_string(index=False))
print("")
export_data(
export,
os.path.dirname(os.path.abspath(__file__)),
"performance",
df_group,
)
def display_future(future_type: str = "Indices", export: str = ""):
def display_valuation(
s_group: str,
sort_col: str = "Name",
ascending: bool = True,
export: str = "",
):
"""View group (sectors, industry or country) valuation data. [Source: Finviz]
Parameters
----------
s_group : str
group between sectors, industry or country
sort_col : str
Column to sort by
ascending : bool
Flag to sort in ascending order
export : str
Export data to csv,json,xlsx or png,jpg,pdf,svg file
"""
df_group = finviz_model.get_valuation_performance_data(s_group, "valuation")
df_group["Market Cap"] = df_group["Market Cap"].apply(lambda x: float(x.strip("B")))
df_group.columns = [col.replace(" ", "") for col in df_group.columns]
df_group = df_group.sort_values(by=sort_col, ascending=ascending)
df_group["Volume"] = df_group["Volume"] / 1_000_000
df_group = df_group.rename(columns={"Volume": "Volume (1M)"})
if gtff.USE_TABULATE_DF:
print(
tabulate(
df_group.fillna(""),
showindex=False,
headers=df_group.columns,
tablefmt="fancy_grid",
floatfmt=".2f",
)
)
else:
print(df_group.fillna("").to_string(index=False))
print("")
export_data(
export,
os.path.dirname(os.path.abspath(__file__)),
"valuation",
df_group,
)
def display_spectrum(s_group: str, export: str = ""):
"""Display finviz spectrum in system viewer [Source: Finviz]
Parameters
----------
s_group: str
group between sectors, industry or country
export: str
Format to export data
"""
finviz_model.get_spectrum_data(s_group)
print("")
img = Image.open(s_group + ".jpg")
export_data(
export,
os.path.dirname(os.path.abspath(__file__)),
"spectrum",
)
img.show()
def display_future(
future_type: str = "Indices",
sort_col: str = "ticker",
ascending: bool = False,
export: str = "",
):
"""Display table of a particular future type. [Source: Finviz]
Parameters
----------
future_type : str
From the following: Indices, Energy, Metals, Meats, Grains, Softs, Bonds, Currencies
sort_col : str
Column to sort by
ascending : bool
Flag to sort in ascending order
export : str
Export data to csv,json,xlsx or png,jpg,pdf,svg file
"""
@@ -146,14 +201,14 @@ def display_future(future_type: str = "Indices", export: str = ""):
df = pd.DataFrame(d_futures[future_type])
df = df.set_index("label")
df = df.sort_values(by=sort_col, ascending=ascending)
if gtff.USE_TABULATE_DF:
print(
tabulate(
df[["prevClose", "last", "change"]].fillna(""),
showindex=True,
floatfmt=".2f",
headers=df.columns,
headers=["prevClose", "last", "change (%)"],
tablefmt="fancy_grid",
)
)

View File

@@ -1,4 +1,4 @@
""" Fred View """
""" Fred Model """
__docformat__ = "numpy"
from typing import List, Tuple
@@ -10,45 +10,30 @@ from fredapi import Fred
from gamestonk_terminal import config_terminal as cfg
def get_series_notes(series_term: str, num: int) -> str:
def get_series_notes(series_term: str) -> pd.DataFrame:
"""Get Series notes. [Source: FRED]
Parameters
----------
series_term : str
Search for this series term
num : int
Maximum number of series notes to display
Returns
----------
notes : str
Series notes output
pd.DataFrame
DataFrame of matched series
"""
fred.key(cfg.API_FRED_KEY)
d_series = fred.search(series_term)
if "seriess" not in d_series:
return "No Series found using this term!\n"
return pd.DataFrame()
if not d_series["seriess"]:
return pd.DataFrame()
df_fred = pd.DataFrame(d_series["seriess"])
if df_fred.empty:
return "No Series found using this term!\n"
df_fred = df_fred.sort_values(by=["popularity"], ascending=False).head(num)
notes = ""
for _, series in df_fred.iterrows():
if series["notes"]:
notes += series["id"] + "\n"
notes += "-" * len(series["id"]) + "\n"
notes += series["notes"] + "\n\n"
if not notes:
return "Series notes not found!\n"
return notes
df_fred["notes"] = df_fred["notes"].fillna("No description provided.")
return df_fred
def get_series_ids(series_term: str, num: int) -> Tuple[List[str], List[str]]:

View File

@@ -2,6 +2,7 @@
__docformat__ = "numpy"
import os
import textwrap
import matplotlib.pyplot as plt
import pandas as pd
@@ -26,7 +27,28 @@ def notes(series_term: str, num: int):
num : int
Maximum number of series notes to display
"""
print(fred_model.get_series_notes(series_term, num))
df_search = fred_model.get_series_notes(series_term)
if df_search.empty:
print("No matches found. \n")
return
df_search["notes"] = df_search["notes"].apply(
lambda x: "\n".join(textwrap.wrap(x, width=100)) if isinstance(x, str) else x
)
df_search["title"] = df_search["title"].apply(
lambda x: "\n".join(textwrap.wrap(x, width=50)) if isinstance(x, str) else x
)
if gtff.USE_TABULATE_DF:
print(
tabulate(
df_search[["id", "title", "notes"]].head(num),
tablefmt="fancy_grid",
headers=["Series ID", "Title", "Description"],
showindex=False,
)
)
else:
print(df_search[["id", "title", "notes"]].head(num).to_string(index=False))
print("")
def display_series(series: str, start_date: str, raw: bool, export: str):

View File

@@ -27,7 +27,6 @@ def display_big_mac_index(
export : str, optional
Format data, by default ""
"""
big_mac = pd.DataFrame()
df_cols = ["Date"]
df_cols.extend(country_codes)
big_mac = pd.DataFrame(columns=df_cols)
@@ -37,8 +36,10 @@ def display_big_mac_index(
big_mac["Date"] = df1["Date"]
big_mac.set_index("Date", inplace=True)
fig, ax = plt.subplots(figsize=plot_autoscale(), dpi=PLOT_DPI)
big_mac.plot(ax=ax)
big_mac.plot(ax=ax, marker="o")
ax.legend(bbox_to_anchor=(1, 1))
ax.set_title("Big Mac Index (USD)")
ax.set_ylabel("Price of Big Mac in USD")
ax.grid("on")
if gtff.USE_ION:
plt.ion()
@@ -47,11 +48,7 @@ def display_big_mac_index(
if raw:
if gtff.USE_TABULATE_DF:
print(
tabulate(
big_mac.head(20), headers=big_mac.columns, tablefmt="fancy_grid"
)
)
print(tabulate(big_mac, headers=big_mac.columns, tablefmt="fancy_grid"))
else:
print(big_mac.head(20).to_string())