Merge pull request #250 from DidierRLopes/sentiment-comparison

Add Sentiment area under Comparison Analysis
This commit is contained in:
DidierRLopes
2021-03-22 01:29:39 +00:00
committed by GitHub
5 changed files with 341 additions and 21 deletions

View File

@@ -121,6 +121,7 @@
* [x] Add multi-ticker historical data comparison (@didier) - [PR #141](https://github.com/DidierRLopes/GamestonkTerminal/pull/141)
* [x] Add multi-ticker financials comparison (@didier) - [PR #237](https://github.com/DidierRLopes/GamestonkTerminal/pull/237)
* [x] Add multi-ticker sentiment comparison (@didier) - [PR #250](https://github.com/DidierRLopes/GamestonkTerminal/pull/250)
### Long term
@@ -144,9 +145,10 @@
* [ ] Merge data from different brokers
* [ ] Refactor
- [x] Add robinhood (@jmaslek) - [PR #209](https://github.com/DidierRLopes/GamestonkTerminal/pull/209)
- [x] Add robinhood (@jmaslek) - [PR #229](https://github.com/DidierRLopes/GamestonkTerminal/pull/229)
- [ ] Add Brokers (td, alpaca, webull, etc) (@jmaslek)
- [ ] Merge data from different brokers (@jmaslek)
### Long term
- [ ] Summaries / tear sheets (@jmaslek)

View File

@@ -8,14 +8,18 @@ This menu aims to compare a pre-loaded stock with similar companies, and the usa
* select similar companies
* [historical](#historical)
* historical data comparison [Yahoo Finance]
* [corr](#corr)
* correlation between similar companies [Yahoo Finance]
* [hcorr](#hcorr)
* historical correlation between similar companies [Yahoo Finance]
* [income](#income)
* income financials comparison [Market Watch]
* [balance](#balance)
* balance financials comparison [Market Watch]
* [cashflow](#cashflow)
* cashflow financials comparison [Market Watch]
* [sentiment](#sentiment)
* sentiment analysis comparison [FinBrain]
* [scorr](#corr)
* sentiment correlation between similar companies [FinBrain]
## get <a name="get"></a>
@@ -52,13 +56,13 @@ Historical price comparison between similar companies [Source: Yahoo Finance]
![historical](https://user-images.githubusercontent.com/25267873/110699590-ef2b8500-81e6-11eb-95e3-144793a83a80.png)
## corr <a name="corr"></a>
## hcorr <a name="hcorr"></a>
```text
usage: corr [-s L_SIMILAR] [-a L_ALSO] [-t TYPE_CANDLE]
usage: hcorr [-s L_SIMILAR] [-a L_ALSO] [-t TYPE_CANDLE]
```
Historical price comparison between similar companies [Source: Yahoo Finance]
Historical price correlation between similar companies [Source: Yahoo Finance]
* -s : similar companies to compare with. Default pre-loaded ones.
* -a : apart from loaded similar companies also compare with.
@@ -114,4 +118,31 @@ Cashflow financials comparison between similar companies [Source: Market Watch]
<img width="1010" alt="Captura de ecrã 2021-03-20, às 09 12 59" src="https://user-images.githubusercontent.com/25267873/111865169-54a51180-895d-11eb-8d31-b499ab74854e.png">
## sentiment <a name="sentiment"></a>
```text
usage: sentiment [-s L_SIMILAR] [-a L_ALSO]
```
Sentiment analysis comparison [Source: FinBrain]
* -s : similar companies to compare with. Default pre-loaded ones.
* -a : apart from loaded similar companies also compare with.
<img width="754" alt="Captura de ecrã 2021-03-20, às 15 57 06" src="https://user-images.githubusercontent.com/25267873/111920503-45ba7e00-8a87-11eb-9a5c-aefb20793f7f.png">
## scorr <a name="scorr"></a>
```text
usage: scorr [-s L_SIMILAR] [-a L_ALSO] [-t TYPE_CANDLE]
```
Sentiment correlation between similar companies [Source: FinBrain]
* -s : similar companies to compare with. Default pre-loaded ones.
* -a : apart from loaded similar companies also compare with.
<img width="282" alt="Captura de ecrã 2021-03-20, às 15 57 01" src="https://user-images.githubusercontent.com/25267873/111920499-4521e780-8a87-11eb-9533-6844ba92f8f0.png">

View File

@@ -6,12 +6,13 @@ import requests
from typing import List
from datetime import datetime
import pandas as pd
from matplotlib import pyplot as plt
from gamestonk_terminal import feature_flags as gtff
from gamestonk_terminal import config_terminal as cfg
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.menu import session
from prompt_toolkit.completion import NestedCompleter
@@ -27,10 +28,12 @@ class ComparisonAnalysisController:
"get",
"select",
"historical",
"corr",
"hcorr",
"income",
"balance",
"cashflow",
"sentiment",
"scorr",
]
def __init__(
@@ -83,14 +86,16 @@ class ComparisonAnalysisController:
print(" get get similar companies [Polygon API]")
print(" select select similar companies")
print("")
if self.similar:
print(" historical historical data comparison")
print(" corr correlation between similar companies")
print("")
print(" income income financials comparison")
print(" balance balance financials comparison")
print(" cashflow cashflow comparison")
print("")
print(" historical historical price data comparison")
print(" hcorr historical price correlation")
print("")
print(" income income financials comparison")
print(" balance balance financials comparison")
print(" cashflow cashflow comparison")
print("")
print(" sentiment sentiment analysis comparison")
print(" scorr sentiment correlation")
print("")
return
@staticmethod
@@ -201,8 +206,8 @@ class ComparisonAnalysisController:
other_args, self.stock, self.ticker, self.start, self.interval, self.similar
)
def call_corr(self, other_args: List[str]):
"""Process correlation command"""
def call_hcorr(self, other_args: List[str]):
"""Process historical correlation command"""
yf_api.correlation(
other_args, self.stock, self.ticker, self.start, self.interval, self.similar
)
@@ -219,6 +224,14 @@ class ComparisonAnalysisController:
"""Process cashflow command"""
mw_api.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)
def call_scorr(self, other_args: List[str]):
"""Process sentiment correlation command"""
f_api.sentiment_correlation(other_args, self.ticker, self.similar)
def menu(stock: pd.DataFrame, ticker: str, start: datetime, interval: str):
"""Comparison Analysis Menu"""
@@ -242,6 +255,8 @@ def menu(stock: pd.DataFrame, ticker: str, start: datetime, interval: str):
an_input = input(f"{get_flair()} (ca)> ")
try:
plt.close("all")
process_input = ca_controller.switch(an_input)
if process_input is not None:

View File

@@ -0,0 +1,272 @@
""" Comparison Analysis Finbrain API """
__docformat__ = "numpy"
import argparse
from typing import List
import requests
from matplotlib import pyplot as plt
import matplotlib.dates as mdates
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,
)
from gamestonk_terminal.config_plot import PLOT_DPI
from gamestonk_terminal import feature_flags as gtff
register_matplotlib_converters()
def sentiment_compare(other_args: List[str], ticker: str, similar: List[str]):
"""Plot sentiments across similar companies
Parameters
----------
other_args : List[str]
Command line arguments to be processed with argparse
ticker : str
Main ticker to compare income
similar : List[str]
Similar companies to compare income with
"""
parser = argparse.ArgumentParser(
add_help=False,
prog="sentiment_compare",
description="""
FinBrain's sentiment comparison across similar tickers.
Finbrain collects the news headlines from 15+ major financial news
sources on a daily basis and analyzes them to generate sentiment scores
for more than 4500 US stocks.FinBrain Technologies develops deep learning
algorithms for financial analysis and prediction, which currently serves
traders from more than 150 countries all around the world.
[Source: https://finbrain.tech]
""",
)
parser.add_argument(
"-s",
"--similar",
dest="l_similar",
type=lambda s: [str(item).upper() for item in s.split(",")],
default=similar,
help="similar companies to compare with.",
)
parser.add_argument(
"-a",
"--also",
dest="l_also",
type=lambda s: [str(item).upper() for item in s.split(",")],
default=[],
help="apart from loaded similar companies also compare with.",
)
try:
ns_parser = parse_known_args_and_warn(parser, other_args)
if not ns_parser:
return
l_similar = ns_parser.l_similar
l_similar += ns_parser.l_also
# Add main ticker to similar list of companies
l_similar = [ticker] + l_similar
df_sentiment = get_sentiments(l_similar)
if not df_sentiment.empty:
plot_sentiments(df_sentiment, l_similar)
print("")
except Exception as e:
print(e, "\n")
return
def sentiment_correlation(other_args: List[str], ticker: str, similar: List[str]):
"""Plot correlation sentiments across similar companies
Parameters
----------
other_args : List[str]
Command line arguments to be processed with argparse
ticker : str
Main ticker to compare income
similar : List[str]
Similar companies to compare income with
"""
parser = argparse.ArgumentParser(
add_help=False,
prog="sentiment_compare",
description="""
FinBrain's sentiment correlation across similar tickers.
Finbrain collects the news headlines from 15+ major financial news
sources on a daily basis and analyzes them to generate sentiment scores
for more than 4500 US stocks.FinBrain Technologies develops deep learning
algorithms for financial analysis and prediction, which currently serves
traders from more than 150 countries all around the world.
[Source: https://finbrain.tech]
""",
)
parser.add_argument(
"-s",
"--similar",
dest="l_similar",
type=lambda s: [str(item).upper() for item in s.split(",")],
default=similar,
help="similar companies to compare with.",
)
parser.add_argument(
"-a",
"--also",
dest="l_also",
type=lambda s: [str(item).upper() for item in s.split(",")],
default=[],
help="apart from loaded similar companies also compare with.",
)
try:
ns_parser = parse_known_args_and_warn(parser, other_args)
if not ns_parser:
return
l_similar = ns_parser.l_similar
l_similar += ns_parser.l_also
# Add main ticker to similar list of companies
l_similar = [ticker] + l_similar
df_sentiment = get_sentiments(l_similar)
if not df_sentiment.empty:
plot_correlation(df_sentiment, l_similar)
print("")
except Exception as e:
print(e, "\n")
return
def get_sentiments(similar: List[str]) -> pd.DataFrame:
"""Gets Sentiment analysis from several tickers provided by FinBrain's API
Parameters
----------
similar : List[str]
Similar tickers to get the sentiment analysis from
Returns
-------
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}")
if result.status_code == 200:
if "sentimentAnalysis" in result.json():
df_sentiment[ticker] = [
float(val)
for val in list(result.json()["sentimentAnalysis"].values())
]
else:
print(f"Unexpected data format from FinBrain API for {ticker}")
else:
print(f"Request error in retrieving {ticker} sentiment from FinBrain API")
if not df_sentiment.empty:
df_sentiment.index = list(result.json()["sentimentAnalysis"].keys())
df_sentiment.sort_index(ascending=True, inplace=True)
return df_sentiment
def plot_sentiments(df_sentiment: pd.DataFrame, similar: List[str]):
"""Plot Sentiment analysis comparison between similar companies
Parameters
----------
df_sentiment : pd.DataFrame
Dataframe with sentiment analysis from several similar companies
similar : List[str]
List of similar companies
"""
plt.figure(figsize=plot_autoscale(), dpi=PLOT_DPI)
for idx, ticker in enumerate(similar):
offset = 2 * idx
plt.axhline(y=offset, color="k", linestyle="--", lw=2)
plt.axhline(y=offset + 1, color="k", linestyle="--", lw=1)
senValues = np.array(pd.to_numeric(df_sentiment[ticker].values))
senNone = np.array(0 * len(df_sentiment))
plt.fill_between(
df_sentiment.index,
pd.to_numeric(df_sentiment[ticker].values) + offset,
offset,
where=(senValues < senNone),
alpha=0.60,
color="red",
interpolate=True,
)
plt.fill_between(
df_sentiment.index,
pd.to_numeric(df_sentiment[ticker].values) + offset,
offset,
where=(senValues >= senNone),
alpha=0.60,
color="green",
interpolate=True,
)
plt.xlabel("Time")
plt.ylabel("Sentiment")
plt.axhline(y=-1, color="k", linestyle="--", lw=1)
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.yticks(np.arange(len(similar)) * 2, similar)
plt.title(f"FinBrain's Sentiment Analysis since {df_sentiment.index[0]}")
plt.gca().xaxis.set_major_locator(mdates.DayLocator(interval=1))
plt.gcf().autofmt_xdate()
if gtff.USE_ION:
plt.ion()
plt.show()
def plot_correlation(df_sentiment: pd.DataFrame, similar: List[str]):
"""Plot Sentiment correlation between similar companies
Parameters
----------
df_sentiment : pd.DataFrame
Dataframe with sentiment analysis from several similar companies
similar : List[str]
List of similar companies
"""
plt.figure(figsize=plot_autoscale(), dpi=PLOT_DPI)
mask = np.zeros((len(similar), len(similar)), dtype=bool)
mask[np.triu_indices(len(mask))] = True
sns.heatmap(
df_sentiment.corr(),
cbar_kws={"ticks": [-1.0, -0.5, 0.0, 0.5, 1.0]},
cmap="RdYlGn",
linewidths=1,
annot=True,
vmin=-1,
vmax=1,
mask=mask,
)
if gtff.USE_ION:
plt.ion()
plt.show()

View File

@@ -77,7 +77,7 @@ def compare_income(other_args: List[str], ticker: str, similar: List[str]):
l_similar += ns_parser.l_also
# Add main ticker to similar list of companies
l_similar.insert(0, ticker)
l_similar = [ticker] + l_similar
l_timeframes, ddf_financials = prepare_comparison_financials(
l_similar, "income", ns_parser.b_quarter
@@ -182,7 +182,7 @@ def compare_balance(other_args: List[str], ticker: str, similar: List[str]):
l_similar += ns_parser.l_also
# Add main ticker to similar list of companies
l_similar.insert(0, ticker)
l_similar = [ticker] + l_similar
l_timeframes, ddf_financials = prepare_comparison_financials(
l_similar, "balance", ns_parser.b_quarter
@@ -287,7 +287,7 @@ def compare_cashflow(other_args: List[str], ticker: str, similar: List[str]):
l_similar += ns_parser.l_also
# Add main ticker to similar list of companies
l_similar.insert(0, ticker)
l_similar = [ticker] + l_similar
l_timeframes, ddf_financials = prepare_comparison_financials(
l_similar, "cashflow", ns_parser.b_quarter