Kovila
sentiment analysis
dbc10ec
# imports
import toml
import finnhub
import datetime
from transformers import pipeline
from transformers import AutoTokenizer, AutoModelForSequenceClassification
import torch
import pandas as pd
import streamlit as st
st.set_page_config(
page_title="Financial News Headlines Summarization and Sentiment",
page_icon="$",
layout="wide",
initial_sidebar_state="expanded",
)
# load API key
# get API Keys
#with open('secrets.toml', 'r') as f:
# config = toml.load(f)
#FINNHUB_API_KEY = config['FINNHUB']
FINNHUB_API_KEY = st.secrets['FINNHUB']
# function to get financial news
def financial_news(stock_ticker, start_date, end_date, include_headline=True, include_summary=False):
"""
Retrieves financial news for a specified stock within a date range.
Args:
stock_ticker (str): The ticker symbol of the stock (e.g., "AAPL" for Apple Inc.).
start_date (str): The start date for the news search in the format "YYYY-MM-DD".
end_date (str): The end date for the news search in the format "YYYY-MM-DD".
include_headline (bool, optional): If True, includes both headlines and summaries in the result.
Defaults to True.
Returns:
str: A concatenated string of headlines and summaries for the specified stock within the date range.
If `include_headline` is False, only the summary is included.
"""
finnhub_client = finnhub.Client(api_key=FINNHUB_API_KEY)
news_list = finnhub_client.company_news(stock_ticker, _from=start_date, to=end_date)
news = ''
for news_i in news_list:
if stock_ticker in news_i['headline']:
if include_headline:
news = news + ' ' + news_i['headline'] + '.\n\n'
if include_summary:
news = news + ' ' + news_i['summary'] + '.\n\n'
return news
# get financial news summary
@st.cache_resource
def load_summarizer():
return pipeline("summarization", model="facebook/bart-large-cnn")
SUMMARIZER = load_summarizer()
def get_news_summary(news):
news = news.replace('\n\n', ' ')
news_summary = SUMMARIZER(news)
return news_summary[0]['summary_text']
# get financial news sentiment
@st.cache_resource
def load_tokenizer():
return AutoTokenizer.from_pretrained("ProsusAI/finbert")
@st.cache_resource
def load_sentiment_classification_model():
return AutoModelForSequenceClassification.from_pretrained("ProsusAI/finbert")
FINBERT_TOKENIZER = load_tokenizer()
FINBERT_CLASSIFIER = load_sentiment_classification_model()
def get_news_sentiment(news):
news = news.replace('\n\n', ' ')
inputs = FINBERT_TOKENIZER([news.replace('\n\n', '')], padding = True, truncation = True, return_tensors='pt')
outputs = FINBERT_CLASSIFIER(**inputs)
predictions = torch.nn.functional.softmax(outputs.logits, dim=-1)
postive, neutral, negative = tuple(predictions.tolist()[0])
return postive, neutral, negative
# APP
st.title('Financial News Headlines Summarization and Sentiment')
col1, col2 = st.columns(2)
with col1:
st.write('Enter the stock ticker and period for which you want financial news headlines.')
stock_ticker = st.text_input('Stock Ticker:', 'AAPL')
start_date = st.date_input('Start Date:', datetime.datetime.today()-datetime.timedelta(days=20))
end_date = st.date_input('End Date:', datetime.datetime.today())
news = financial_news(stock_ticker, start_date, end_date)
st.divider()
st.subheader('News Headlines:')
st.write(news)
with col2:
st.subheader('Financial News Sentiment')
with st.spinner('finbert model getting sentiment...'):
positive, neutral, negative = get_news_sentiment(news)
# white: #D0D3D4
# red: #E74C3C
# green: #2ECC71
sentiment_df = pd.DataFrame(
{
'sentiment_labels':['positive', 'neutral', 'negative'],
'sentiment':[positive, neutral, negative],
'color':['#2ECC71', '#D0D3D4', '#E74C3C']
}
)
st.bar_chart(sentiment_df, x='sentiment_labels', y='sentiment', color='color', horizontal=True)
st.subheader('Financial News Summary')
with st.spinner('facebook bart model is summarizing the news...'):
news_summary = get_news_summary(news)
st.write(news_summary)