File size: 4,302 Bytes
fce802f
 
 
 
 
bbfab4a
 
004a155
fce802f
 
dbc10ec
 
 
 
 
 
fce802f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bbfab4a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
fce802f
830c56a
bbfab4a
dbc10ec
830c56a
08a3338
 
 
 
 
 
 
830c56a
 
08a3338
 
 
830c56a
08a3338
 
 
 
 
 
 
 
 
 
 
 
 
 
 
830c56a
08a3338
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# 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)