mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-10-27 12:40:35 +00:00
Add sentiment analysis comparison and correlation
This commit is contained in:
@@ -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__(
|
||||
@@ -84,13 +87,16 @@ class ComparisonAnalysisController:
|
||||
print(" select select similar companies")
|
||||
print("")
|
||||
if self.similar:
|
||||
print(" historical historical data comparison")
|
||||
print(" corr correlation between similar companies")
|
||||
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 +207,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 +225,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 +256,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:
|
||||
|
||||
272
gamestonk_terminal/comparison_analysis/finbrain_api.py
Normal file
272
gamestonk_terminal/comparison_analysis/finbrain_api.py
Normal 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()
|
||||
Reference in New Issue
Block a user