|
|
|
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", |
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
FINNHUB_API_KEY = st.secrets['FINNHUB'] |
|
|
|
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 |
|
|
|
|
|
@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'] |
|
|
|
|
|
@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 |
|
|
|
|
|
|
|
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) |
|
|
|
|
|
|
|
|
|
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) |