Source code for stocksent.sentiment

import matplotlib.pyplot as plt
import nltk
import numpy as np
import pandas as pd
from nltk.sentiment.vader import SentimentIntensityAnalyzer
from datetime import datetime
from wordcloud import WordCloud

from stocksent.get_sentiment_data import get_sentiment_data

try:
    vader = SentimentIntensityAnalyzer()
except:
    nltk.download('vader_lexicon')
    vader = SentimentIntensityAnalyzer()


[docs]class Sentiment: """ Instantiate ticker(s) for analysis. Provides several functions to analyze sentiments of stocks based on trusted news sources. :param ticker: The ticker or list of tickers. :type ticker: str/list """ def __init__(self, ticker): self.ticker = ticker
[docs] def get_sentiment(self, days=None): """ Returns sentiment of given ticker(s). :param days: Number of days into the past you want the sentiment for. :type days: int """ df = get_sentiment_data(self.ticker) if days is not None: now = datetime.now().date() day_neg = pd.to_timedelta(days, unit='d') oldest_date = now - day_neg df = df[df['date'] >= oldest_date] scores = df['headline'].apply(vader.polarity_scores).tolist() scores = [x['compound'] for x in scores] sentiment = float(np.mean(scores)) final_sentiment = round(sentiment, 4) return final_sentiment
[docs] def get_dataframe(self, days=None): """ Returns dataframe of given ticker(s) with date, time, headlines, source and sentiment. :param days: Number of days into the past you want the sentiment for. :type days: int """ df = get_sentiment_data(self.ticker) scores = df['headline'].apply(vader.polarity_scores).tolist() scores_df = pd.DataFrame(scores) scores_df.columns = ['Negative', 'Neutral', 'Positive', 'Overall'] df = df.join(scores_df, rsuffix='_right') if days is not None: now = datetime.now().date() day_neg = pd.to_timedelta(days, unit='d') oldest_date = now - day_neg df = df[df['date'] >= oldest_date] return df
[docs] def plot(self, days=None, save_figure=False): """ Returns plot of given ticker(s) with sentiment across several days. :param days: Number of days into the past you want the plot for. :type days: int :param save_figure: Option for saving figure as png. :type save_figure: bool """ df = get_sentiment_data(self.ticker) scores = df['headline'].apply(vader.polarity_scores).tolist() scores_df = pd.DataFrame(scores) scores_df.columns = ['Negative', 'Neutral', 'Positive', 'Overall'] df = df.join(scores_df, rsuffix='_right') if days is not None: now = datetime.now().date() day_neg = pd.to_timedelta(days, unit='d') oldest_date = now - day_neg df = df[df['date'] >= oldest_date] plt.rcParams['figure.figsize'] = [10, 6] mean_scores = df.groupby(['ticker', 'date']).mean() mean_scores = mean_scores.unstack() mean_scores = mean_scores.xs('Overall', axis="columns").transpose() mean_scores.plot(kind='bar') plt.tight_layout() plt.grid() if save_figure: plt.savefig(str(datetime.now().timestamp()) + ".png") plt.show() pass
[docs] def word_cloud(self, days=None, save_figure=False, figsize=(15, 8)): """ Returns a word cloud plot of given ticker(s). :param days: Number of days into the past you want the word cloud for. :type days: int :param save_figure: Option for saving figure as png. :type save_figure: bool :param figsize: Option for resizing plot. :type save_figure: tuple """ df = get_sentiment_data(self.ticker) scores = df['headline'].apply(vader.polarity_scores).tolist() scores_df = pd.DataFrame(scores) scores_df.columns = ['Negative', 'Neutral', 'Positive', 'Overall'] df = df.join(scores_df, rsuffix='_right') if days is not None: now = datetime.now().date() day_neg = pd.to_timedelta(days, unit='d') oldest_date = now - day_neg df = df[df['date'] >= oldest_date] unique_string = " ".join(df['headline'].tolist()) wordcloud = WordCloud(width=1000, height=500).generate(unique_string) plt.figure(figsize=figsize) plt.imshow(wordcloud) plt.axis("off") if save_figure: plt.savefig(str(datetime.now().timestamp()) + ".png") plt.show() pass