Refactoring comparison analysis

This commit is contained in:
Artem Veremey
2021-04-20 13:21:49 -07:00
parent e33a5d4682
commit 296bb4b321
4 changed files with 155 additions and 45 deletions

View File

@@ -2,23 +2,24 @@
__docformat__ = "numpy"
import argparse
import requests
import random
from typing import List
from datetime import datetime
import requests
import pandas as pd
from matplotlib import pyplot as plt
from finvizfinance.screener.overview import Overview
from prompt_toolkit.completion import NestedCompleter
from gamestonk_terminal import feature_flags as gtff
from gamestonk_terminal import config_terminal as cfg
from finvizfinance.screener.overview import Overview
from gamestonk_terminal.helper_funcs import get_flair, parse_known_args_and_warn
from gamestonk_terminal.comparison_analysis import yahoo_finance_api as yf_api
from gamestonk_terminal.comparison_analysis import market_watch_api as mw_api
from gamestonk_terminal.comparison_analysis import finbrain_api as f_api
from gamestonk_terminal.comparison_analysis import yahoo_finance_view
from gamestonk_terminal.comparison_analysis import market_watch_view
from gamestonk_terminal.comparison_analysis import finbrain_view
from gamestonk_terminal.comparison_analysis import finviz_compare_view
from gamestonk_terminal.portfolio_optimization import po_controller
from gamestonk_terminal.menu import session
from prompt_toolkit.completion import NestedCompleter
class ComparisonAnalysisController:
@@ -54,9 +55,23 @@ class ComparisonAnalysisController:
start: datetime,
interval: str,
similar: List[str],
user: bool,
):
"""Constructor"""
"""Constructor
Parameters
----------
stock : pd.DataFrame
Stock data
ticker : str
Stock ticker
start : datetime
Start time
interval : str
Time interval
similar : List[str]
List of similar tickers
"""
self.similar = similar
self.user = ""
self.stock = stock
@@ -69,7 +84,6 @@ class ComparisonAnalysisController:
choices=self.CHOICES,
)
@staticmethod
def print_help(self):
"""Print help"""
@@ -108,14 +122,21 @@ class ComparisonAnalysisController:
print(" performance brief performance comparison")
print(" technical brief technical comparison")
print("")
if self.similar:
print(" > po portfolio optimization for selected tickers")
print("")
return
@staticmethod
def get_similar_companies(self, other_args: List[str]):
""" Get similar companies. [Source: Polygon API] """
"""Get similar companies. [Source: Polygon API]
Parameters
----------
other_args : List[str]
argparse other args
"""
parser = argparse.ArgumentParser(
add_help=False,
prog="get",
@@ -189,9 +210,15 @@ class ComparisonAnalysisController:
print("")
return
@staticmethod
def select_similar_companies(self, other_args: List[str]):
""" Select similar companies, e.g. NIO,XPEV,LI"""
"""Select similar companies, e.g. NIO,XPEV,LI
Parameters
----------
other_args : List[str]
argparse other args
"""
parser = argparse.ArgumentParser(
add_help=False,
prog="select",
@@ -242,7 +269,7 @@ class ComparisonAnalysisController:
def call_help(self, _):
"""Process Help command"""
self.print_help(self)
self.print_help()
def call_q(self, _):
"""Process Q command - quit the menu"""
@@ -254,43 +281,43 @@ class ComparisonAnalysisController:
def call_get(self, other_args: List[str]):
"""Process get command"""
self.get_similar_companies(self, other_args)
self.get_similar_companies(other_args)
def call_select(self, other_args: List[str]):
"""Process select command"""
self.select_similar_companies(self, other_args)
self.select_similar_companies(other_args)
def call_historical(self, other_args: List[str]):
"""Process historical command"""
yf_api.historical(
yahoo_finance_view.historical(
other_args, self.stock, self.ticker, self.start, self.interval, self.similar
)
def call_hcorr(self, other_args: List[str]):
"""Process historical correlation command"""
yf_api.correlation(
yahoo_finance_view.correlation(
other_args, self.stock, self.ticker, self.start, self.interval, self.similar
)
def call_income(self, other_args: List[str]):
"""Process income command"""
mw_api.compare_income(other_args, self.ticker, self.similar)
market_watch_view.compare_income(other_args, self.ticker, self.similar)
def call_balance(self, other_args: List[str]):
"""Process balance command"""
mw_api.compare_balance(other_args, self.ticker, self.similar)
market_watch_view.compare_balance(other_args, self.ticker, self.similar)
def call_cashflow(self, other_args: List[str]):
"""Process cashflow command"""
mw_api.compare_cashflow(other_args, self.ticker, self.similar)
market_watch_view.compare_cashflow(other_args, self.ticker, self.similar)
def call_sentiment(self, other_args: List[str]):
"""Process sentiment command"""
f_api.sentiment_compare(other_args, self.ticker, self.similar)
finbrain_view.sentiment_compare(other_args, self.ticker, self.similar)
def call_scorr(self, other_args: List[str]):
"""Process sentiment correlation command"""
f_api.sentiment_correlation(other_args, self.ticker, self.similar)
finbrain_view.sentiment_correlation(other_args, self.ticker, self.similar)
def call_overview(self, other_args: List[str]):
"""Process overview command"""
@@ -324,11 +351,21 @@ class ComparisonAnalysisController:
def menu(stock: pd.DataFrame, ticker: str, start: datetime, interval: str):
"""Comparison Analysis Menu"""
"""Comparison Analysis Menu
ca_controller = ComparisonAnalysisController(
stock, ticker, start, interval, [], False
)
Parameters
----------
stock : pd.DataFrame
Stock data
ticker : str
Stock ticker
start : datetime
Time start
interval : str
Time interval
"""
ca_controller = ComparisonAnalysisController(stock, ticker, start, interval, [])
ca_controller.call_help(None)
while True:

View File

@@ -10,6 +10,7 @@ import pandas as pd
from pandas.plotting import register_matplotlib_converters
import numpy as np
import seaborn as sns
from gamestonk_terminal.helper_funcs import (
parse_known_args_and_warn,
plot_autoscale,
@@ -33,6 +34,7 @@ def sentiment_compare(other_args: List[str], ticker: str, similar: List[str]):
similar : List[str]
Similar companies to compare income with
"""
parser = argparse.ArgumentParser(
add_help=False,
prog="sentiment_compare",
@@ -98,6 +100,7 @@ def sentiment_correlation(other_args: List[str], ticker: str, similar: List[str]
similar : List[str]
Similar companies to compare income with
"""
parser = argparse.ArgumentParser(
add_help=False,
prog="sentiment_compare",
@@ -164,6 +167,7 @@ def get_sentiments(similar: List[str]) -> pd.DataFrame:
DataFrame()
Contains sentiment analysis from several tickers
"""
df_sentiment = pd.DataFrame()
for ticker in similar:
result = requests.get(f"https://api.finbrain.tech/v0/sentiments/{ticker}")
@@ -196,6 +200,7 @@ def plot_sentiments(df_sentiment: pd.DataFrame, similar: List[str]):
similar : List[str]
List of similar companies
"""
plt.figure(figsize=plot_autoscale(), dpi=PLOT_DPI)
for idx, ticker in enumerate(similar):
@@ -251,6 +256,7 @@ def plot_correlation(df_sentiment: pd.DataFrame, similar: List[str]):
similar : List[str]
List of similar companies
"""
plt.figure(figsize=plot_autoscale(), dpi=PLOT_DPI)
mask = np.zeros((len(similar), len(similar)), dtype=bool)

View File

@@ -27,6 +27,7 @@ def compare_income(other_args: List[str], ticker: str, similar: List[str]):
similar : List[str]
Similar companies to compare income with
"""
parser = argparse.ArgumentParser(
add_help=False,
prog="income",
@@ -132,6 +133,7 @@ def compare_balance(other_args: List[str], ticker: str, similar: List[str]):
similar : List[str]
Similar companies to compare income with
"""
parser = argparse.ArgumentParser(
add_help=False,
prog="compare_balance",
@@ -237,6 +239,7 @@ def compare_cashflow(other_args: List[str], ticker: str, similar: List[str]):
similar : List[str]
Similar companies to compare income with
"""
parser = argparse.ArgumentParser(
add_help=False,
prog="compare_cashflow",

View File

@@ -1,4 +1,9 @@
""" Comparison Analysis Yahoo Finance View """
__docformat__ = "numpy"
import argparse
from typing import List
from datetime import datetime
import numpy as np
import pandas as pd
from pandas.plotting import register_matplotlib_converters
@@ -21,6 +26,24 @@ d_candle_types = {
def check_one_of_ohlca(type_candles: str) -> str:
"""Convert a candle type
Parameters
----------
type_candles : str
OHLCA candle type
Returns
-------
str
Converted candle type
Raises
------
argparse.ArgumentTypeError
Unknown candle type
"""
if (
type_candles == "o"
or type_candles == "h"
@@ -32,7 +55,32 @@ def check_one_of_ohlca(type_candles: str) -> str:
raise argparse.ArgumentTypeError("The type of candles specified is not recognized")
def historical(l_args, df_stock, s_ticker, s_start, s_interval, similar):
def historical(
other_args: List[str],
df_stock: pd.DataFrame,
ticker: str,
start: datetime,
interval: str,
similar: List[str],
):
"""Display historical data from Yahoo Finance
Parameters
----------
other_args : List[str]
Command line arguments to be processed with argparse
df_stock : pd.DataFrame
Stock data
ticker : str
Ticker symbol
start : datetime
Time start
interval : str
Time interval
similar : List[str]
List of similar tickers
"""
parser = argparse.ArgumentParser(
add_help=False,
prog="historical",
@@ -66,11 +114,11 @@ def historical(l_args, df_stock, s_ticker, s_start, s_interval, similar):
)
try:
if s_interval != "1440min":
if interval != "1440min":
print("Intraday historical data analysis comparison is not yet available.")
# Alpha Vantage only supports 5 calls per minute, we need another API to get intraday data
else:
ns_parser = parse_known_args_and_warn(parser, l_args)
ns_parser = parse_known_args_and_warn(parser, other_args)
if not ns_parser:
return
@@ -80,16 +128,14 @@ def historical(l_args, df_stock, s_ticker, s_start, s_interval, similar):
similar += ns_parser.l_also
plt.figure(figsize=plot_autoscale(), dpi=PLOT_DPI)
plt.title(f"Similar companies to {s_ticker}")
df_stock = yf.download(
s_ticker, start=s_start, progress=False, threads=False
)
plt.title(f"Similar companies to {ticker}")
df_stock = yf.download(ticker, start=start, progress=False, threads=False)
plt.plot(
df_stock.index, df_stock[d_candle_types[ns_parser.type_candle]].values
)
# plt.plot(df_stock.index, df_stock["5. adjusted close"].values, lw=2)
l_min = [df_stock.index[0]]
l_leg = [s_ticker]
l_leg = [ticker]
l_stocks = similar[:]
@@ -98,7 +144,7 @@ def historical(l_args, df_stock, s_ticker, s_start, s_interval, similar):
for symbol in l_stocks:
try:
df_similar_stock = yf.download(
symbol, start=s_start, progress=False, threads=False
symbol, start=start, progress=False, threads=False
)
if not df_similar_stock.empty:
plt.plot(
@@ -141,7 +187,25 @@ def historical(l_args, df_stock, s_ticker, s_start, s_interval, similar):
print(e, "\n")
def correlation(l_args, df_stock, s_ticker, s_start, s_interval, similar):
def correlation(other_args, df_stock, ticker, start, interval, similar):
"""[summary]
Parameters
----------
other_args : [type]
Command line arguments to be processed with argparse
df_stock : pd.DataFrame
Stock data
ticker : str
Ticker symbol
start : datetime
Time start
interval : str
Time interval
similar : [type]
List of similar tickers
"""
parser = argparse.ArgumentParser(
add_help=False,
prog="corr",
@@ -176,11 +240,11 @@ def correlation(l_args, df_stock, s_ticker, s_start, s_interval, similar):
)
try:
if s_interval != "1440min":
if interval != "1440min":
print("Intraday historical data analysis comparison is not yet available.")
# Alpha Vantage only supports 5 calls per minute, we need another API to get intraday data
else:
ns_parser = parse_known_args_and_warn(parser, l_args)
ns_parser = parse_known_args_and_warn(parser, other_args)
if not ns_parser:
return
@@ -193,21 +257,21 @@ def correlation(l_args, df_stock, s_ticker, s_start, s_interval, similar):
print("Provide at least a similar company for correlation")
else:
d_stock = {}
d_stock[s_ticker] = yf.download(s_ticker, start=s_start, progress=False)
l_min = [d_stock[s_ticker].index[0]]
d_stock[ticker] = yf.download(ticker, start=start, progress=False)
l_min = [d_stock[ticker].index[0]]
for symbol in similar:
d_stock[symbol] = yf.download(symbol, start=s_start, progress=False)
d_stock[symbol] = yf.download(symbol, start=start, progress=False)
if not d_stock[symbol].empty:
l_min.append(d_stock[symbol].index[0])
min_start_date = max(l_min)
df_stock = d_stock[s_ticker][
df_stock = d_stock[ticker][
d_candle_types[ns_parser.type_candle]
].rename(s_ticker)
].rename(ticker)
for symbol in d_stock:
if symbol != s_ticker:
if symbol != ticker:
if not d_stock[symbol].empty:
df_stock = pd.concat(
[