Add indices

This commit is contained in:
Jeroen Bouma
2022-03-10 09:25:36 +01:00
parent 7a40ccdd4f
commit 16cbcdd9c1
5 changed files with 353 additions and 113 deletions

View File

@@ -264,7 +264,7 @@ def get_data(parameter: str, country: str, convert_currency: str = "USD") -> pd.
df = (
df
* yf.Ticker(f"{convert_currency}{country_currency}=X").history(
period="1d"
start=df.index[0]
)["Close"][0]
)

View File

@@ -1,11 +1,11 @@
""" Econ Controller """
__docformat__ = "numpy"
# pylint:disable=too-many-lines,R1710,R0904,C0415
import argparse
import logging
import os
from typing import List
import pandas as pd
from prompt_toolkit.completion import NestedCompleter
@@ -20,7 +20,10 @@ from gamestonk_terminal.economy import (
wsj_view,
econdb_view,
econdb_model,
yfinance_model,
yfinance_view,
)
from gamestonk_terminal.helper_funcs import (
EXPORT_BOTH_RAW_DATA_AND_FIGURES,
EXPORT_ONLY_FIGURES_ALLOWED,
@@ -42,7 +45,7 @@ class EconomyController(BaseController):
"overview",
"futures",
"macro",
"macrous",
"indices",
"valuation",
"performance",
"spectrum",
@@ -145,6 +148,8 @@ class EconomyController(BaseController):
c: None for c in ["energy", "metals", "meats", "grains", "softs"]
}
choices["indices"] = {c: None for c in yfinance_model.INDICES}
choices["macro"]["-p"] = {c: None for c in econdb_model.PARAMETERS}
choices["macro"]["--parameter"] = {c: None for c in econdb_model.PARAMETERS}
choices["macro"]["-c"] = {c: None for c in econdb_model.COUNTRY_CODES}
@@ -152,9 +157,6 @@ class EconomyController(BaseController):
c: None for c in econdb_model.COUNTRY_CODES
}
choices["macrous"]["-t"] = {c: None for c in self.macro_us_types}
choices["macrous"]["--type"] = {c: None for c in self.macro_us_types}
choices["valuation"]["-s"] = {c: None for c in self.valuation_sort_cols}
choices["valuation"]["--sortby"] = {
c: None for c in self.valuation_sort_cols
@@ -185,7 +187,7 @@ Overview
Macro Data
macro collect macro data for a country or countries [src][Source: EconDB][/src]
macrous show United States macro data [src][Source: Alpha Vantage][/src]
indices show the most important indices worldwide [src][Source: Yahoo Finance][/src]
Performance & Valuations
rtps real-time performance sectors [src][Source: Alpha Vantage][/src]
@@ -349,7 +351,7 @@ Index
add_help=False,
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
prog="macro",
description="Get a broad selection of macro data from one or multiple companies. [Source: EconDB}",
description="Get a broad selection of macro data from one or multiple companies. [Source: EconDB]",
)
parser.add_argument(
@@ -449,6 +451,139 @@ Index
export=ns_parser.export,
)
@log_start_end(log=logger)
def call_indices(self, other_args: List[str]):
"""Process indices command"""
parser = argparse.ArgumentParser(
add_help=False,
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
prog="indices",
description="Obtain any set of indices and plot them together. With the -si argument the major indices are "
"shown. By using the arguments (for example 'nasdaq' and 'sp500') you can collect data and "
"plot the graphs together. [Source: Yahoo finance / FinanceDatabase]",
)
parser.add_argument(
"-i",
"--indices",
nargs="+",
dest="indices",
help="One or multiple indices",
)
parser.add_argument(
"-si",
"--show_indices",
dest="show_indices",
help="Show the major indices, their arguments and ticker",
action="store_true",
default=False,
)
parser.add_argument(
"-iv",
"--interval",
type=str,
dest="interval",
help="The preferred interval data is shown at. This can be 1m, 2m, 5m, 15m, 30m, 60m, 90m, 1h, "
"1d, 5d, 1wk, 1mo or 3mo",
choices=[
"1m",
"2m",
"5m",
"15m",
"30m",
"60m",
"90m",
"1h",
"1d",
"5d",
"1wk",
"1mo",
"3mo",
],
default="1d",
)
parser.add_argument(
"-s",
"--start_date",
dest="start_date",
help="The start date of the data (format: YEAR-MONTH-DAY, i.e. 2010-12-31)",
default="2000-01-01",
)
parser.add_argument(
"-e",
"--end_date",
dest="end_date",
help="The end date of the data (format: YEAR-MONTH-DAY, i.e. 2021-06-20)",
default=None,
)
parser.add_argument(
"-c",
"--column",
type=str,
dest="column",
help="The column you wish to load in, by default this is the Adjusted Close column",
default="Adj Close",
)
parser.add_argument(
"-q",
"--query",
type=str,
nargs="+",
dest="query",
help="Search for indices with given keyword",
)
parser.add_argument(
"-l",
"--limit",
type=str,
dest="limit",
help="Takes into account the amount of rows you wish to see for your query ('-q').",
default=10,
)
parser.add_argument(
"-r",
"--raw",
dest="raw",
help="Show raw data",
action="store_true",
default=False,
)
if other_args and "-" not in other_args[0][0]:
other_args.insert(0, "-i")
ns_parser = parse_known_args_and_warn(
parser, other_args, export_allowed=EXPORT_ONLY_RAW_DATA_ALLOWED
)
if ns_parser:
if ns_parser.query and ns_parser.limit:
yfinance_view.search_indices(ns_parser.query, ns_parser.limit)
if ns_parser.show_indices:
print_rich_table(
pd.DataFrame.from_dict(yfinance_model.INDICES, orient="index"),
show_index=True,
index_name="Argument",
headers=["Name", "Ticker"],
title="Major Indices",
)
elif ns_parser.indices:
yfinance_view.show_indices(
indices=ns_parser.indices,
interval=ns_parser.interval,
start_date=ns_parser.start_date,
end_date=ns_parser.end_date,
column=ns_parser.column,
raw=ns_parser.raw,
export=ns_parser.export,
)
@log_start_end(log=logger)
def call_map(self, other_args: List[str]):
"""Process map command"""
@@ -663,110 +798,6 @@ Index
export=ns_parser.export,
)
@log_start_end(log=logger)
def call_macrous(self, other_args: List[str]):
"""Process macrous command"""
parser = argparse.ArgumentParser(
add_help=False,
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
prog="macrous",
description="""
Show a large selection of US Macro data including Real Gross Domestic Product (GDP),
Inflation Rates (INF), Consumer Price Index (CPI), Treasury Yields (TYLD) and
Unemployment Rates (UNEMP) [Source: Alpha Vantage]
""",
)
parser.add_argument(
"-t",
"--type",
help="Type of macro data you wish to view.",
dest="type",
type=str,
choices=self.macro_us_types,
default="GDP",
)
parser.add_argument(
"-i",
"--interval",
help="The interval you wish to show the data for. This is dependent on the type of data.",
dest="interval",
type=str,
choices=self.macro_us_interval,
default="annual",
)
parser.add_argument(
"-s",
"--start",
help="Start year. Quarterly only goes back to 2002.",
dest="start",
type=int,
default=2010,
)
parser.add_argument(
"-m",
"--maturity",
help="Maturity timeline for treasuries (when entering he TYLD parameter)",
dest="maturity",
choices=self.tyld_maturity,
default="5y",
)
parser.add_argument(
"--raw",
help="Display raw data",
action="store_true",
dest="raw",
default=False,
)
if other_args and "-" not in other_args[0][0]:
other_args.insert(0, "-t")
ns_parser = parse_known_args_and_warn(
parser, other_args, export_allowed=EXPORT_BOTH_RAW_DATA_AND_FIGURES
)
if ns_parser:
type_upper = ns_parser.type.upper()
if type_upper == "GDP":
alphavantage_view.display_real_gdp(
interval=ns_parser.interval,
start_year=ns_parser.start,
raw=ns_parser.raw,
export=ns_parser.export,
)
elif type_upper == "INF":
alphavantage_view.display_inflation(
start_year=ns_parser.start,
raw=ns_parser.raw,
export=ns_parser.export,
)
elif type_upper == "CPI":
alphavantage_view.display_cpi(
interval=ns_parser.interval,
start_year=ns_parser.start,
raw=ns_parser.raw,
export=ns_parser.export,
)
elif type_upper == "TYLD":
alphavantage_view.display_treasury_yield(
interval=ns_parser.interval,
maturity=ns_parser.maturity,
start_date=ns_parser.start,
raw=ns_parser.raw,
export=ns_parser.export,
)
elif type_upper == "UNEMP":
alphavantage_view.display_unemployment(
start_year=ns_parser.start,
raw=ns_parser.raw,
export=ns_parser.export,
)
@log_start_end(log=logger)
def call_bigmac(self, other_args: List[str]):
"""Process bigmac command"""

View File

@@ -75,7 +75,10 @@ def display_big_mac_index(
if raw:
print_rich_table(
big_mac, headers=list(big_mac.columns), title="Big Mac Index"
big_mac,
headers=list(big_mac.columns),
title="Big Mac Index",
show_index=True,
)
console.print("")

View File

@@ -0,0 +1,84 @@
""" Yahoo Finance Model """
__docformat__ = "numpy"
import logging
import pandas as pd
import yfinance as yf
from gamestonk_terminal.decorators import log_start_end
from gamestonk_terminal.rich_config import console
logger = logging.getLogger(__name__)
INDICES = {
"sp500": {"name": "S&P 500", "ticker": "^GSPC"},
"nasdaq": {"name": "Nasdaq Composite", "ticker": "^IXIC"},
"dowjones": {"name": "Dow Jones Industrial Average", "ticker": "^DJI"},
"vix": {"name": "CBOE Volatility Index", "ticker": "^VIX"},
"russel": {"name": "Russel 2000 Index", "ticker": "^RUT"},
"tsx": {"name": "TSX Composite", "ticker": "^GSPTSE"},
"nikkei": {"name": "Nikkei 255 Stock Average", "ticker": "^N225"},
"shanghai": {"name": "Shanghai Composite Index", "ticker": "000001.SS"},
"ftse100": {"name": "FTSE 100 Index ('footsie')", "ticker": "^FTSE"},
"stoxx50": {"name": "Euro STOXX 50", "ticker": "^STOXX50E"},
"dax": {"name": "DAX Performance Index", "ticker": "^GDAXI"},
"cac40": {"name": "CAC 40 Index", "ticker": "^FCHI"},
}
@log_start_end(log=logger)
def get_index(
index: str,
interval: str = "1d",
start_date: int = None,
end_date: int = None,
column: str = "Adj Close",
) -> pd.Series:
"""Obtain data on any index [Source: Yahoo Finance]
Parameters
----------
index: str
The index you wish to collect data for.
start_date : str
the selected country
end_date : bool
The currency you wish to convert the data to.
interval : str
Valid intervals: 1m, 2m, 5m, 15m, 30m, 60m, 90m, 1h, 1d, 5d, 1wk, 1mo or 3mo
Intraday data cannot extend last 60 days
column : str
The column you wish to select, by default this is Adjusted Close.
Returns
----------
pd.Series
A series with the requested index
"""
if index in INDICES:
ticker = INDICES[index]["ticker"]
else:
ticker = index
index_data = yf.download(
ticker,
start=start_date,
end=end_date,
interval=interval,
progress=False,
show_errors=False,
)
if column not in index_data.columns:
return console.print(
f"The chosen column is not available for {ticker}. Please choose "
f"between: {', '.join(index_data.columns)}"
)
if index_data.empty or len(index_data) < 2:
return console.print(
f"The chosen index {ticker}, returns no data. Please check if "
f"there is any data available."
)
return index_data[column]

View File

@@ -0,0 +1,122 @@
""" EconDB View """
__docformat__ = "numpy"
import logging
from typing import Optional, List
import pandas as pd
from matplotlib import pyplot as plt
import financedatabase as fd
from gamestonk_terminal.config_plot import PLOT_DPI
from gamestonk_terminal.config_terminal import theme
from gamestonk_terminal.decorators import log_start_end
from gamestonk_terminal.economy.yfinance_model import get_index, INDICES
from gamestonk_terminal.helper_funcs import plot_autoscale, print_rich_table
logger = logging.getLogger(__name__)
@log_start_end(log=logger)
def show_indices(
indices: list,
interval: str = "1d",
start_date: int = None,
end_date: int = None,
column: str = "Adj Close",
raw: bool = False,
external_axes: Optional[List[plt.axes]] = None,
export: str = "",
):
"""Load (and show) the selected indices over time [Source: Yahoo Finance]
Parameters
----------
indices: list
A list of indices you wish to load (and plot).
interval: str
Valid intervals: 1m,2m,5m,15m,30m,60m,90m,1h,1d,5d,1wk,1mo,3mo
Intraday data cannot extend last 60 days
start_date : str
The starting date, format "YEAR-MONTH-DAY", i.e. 2010-12-31.
end_date : str
The end date, format "YEAR-MONTH-DAY", i.e. 2020-06-05.
raw : bool
Whether to display the raw output.
external_axes: Optional[List[plt.axes]]
External axes to plot on
export : str
Export data to csv,json,xlsx or png,jpg,pdf,svg file
Returns
----------
Plots the Series.
"""
indices_data: pd.DataFrame = pd.DataFrame()
if external_axes is None:
_, ax = plt.subplots(figsize=plot_autoscale(), dpi=PLOT_DPI)
else:
ax = external_axes[0]
for index in indices:
indices_data[index] = get_index(index, interval, start_date, end_date, column)
if index in INDICES:
label = INDICES[index]["name"]
else:
label = index
if not indices_data[index].empty:
ax.plot(indices_data[index], label=label)
ax.set_title("Indices")
ax.legend()
if raw:
print_rich_table(
indices_data.fillna("-").iloc[-10:],
headers=list(indices_data.columns),
show_index=True,
title=f"Indices [columns: {column}",
)
if export:
print("Doing nothing!")
theme.style_primary_axis(ax)
if external_axes is None:
theme.visualize_output()
@log_start_end(log=logger)
def search_indices(keyword: list, limit: int = 10):
"""Load (and show) the selected indices over time [Source: Yahoo Finance]
Parameters
----------
keyword: list
The keyword you wish to search for. This can include spaces.
limit: int
The amount of views you want to show, by default this is set to 10.
Returns
----------
Shows a rich table with the available options.
"""
keyword_adjusted = " ".join(keyword)
indices = fd.select_indices()
queried_indices = pd.DataFrame.from_dict(
fd.search_products(indices, keyword_adjusted, "short_name"), orient="index"
)
print_rich_table(
queried_indices.iloc[:limit],
show_index=True,
index_name="ticker",
headers=queried_indices.columns,
title=f"Queried Indices with keyword {keyword_adjusted}",
)