LinkLinkWu commited on
Commit
b302b27
Β·
verified Β·
1 Parent(s): 8b6f436

Upload app (1).py

Browse files
Files changed (1) hide show
  1. app (1).py +139 -0
app (1).py ADDED
@@ -0,0 +1,139 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from func import (
3
+ get_sentiment_pipeline,
4
+ get_ner_pipeline,
5
+ fetch_news,
6
+ analyze_sentiment,
7
+ extract_org_entities,
8
+ )
9
+ import time
10
+
11
+ # ----------- Page Config -----------
12
+ st.set_page_config(
13
+ page_title="EquiPulse: Stock Sentiment Tracker",
14
+ layout="centered",
15
+ initial_sidebar_state="collapsed"
16
+ )
17
+
18
+ # ----------- Custom Styling -----------
19
+ st.markdown("""
20
+ <style>
21
+ body {
22
+ background-color: #ffffff;
23
+ }
24
+ /* Title styling */
25
+ .main-title {
26
+ font-size: 32px;
27
+ font-weight: 700;
28
+ font-family: 'Segoe UI', sans-serif;
29
+ color: #002b45;
30
+ margin-bottom: 1.2rem;
31
+ white-space: nowrap;
32
+ overflow-x: auto;
33
+ }
34
+ .main-title::-webkit-scrollbar {
35
+ height: 4px;
36
+ }
37
+ .main-title::-webkit-scrollbar-thumb {
38
+ background-color: #ccc;
39
+ border-radius: 2px;
40
+ }
41
+ /* Input + Button styling */
42
+ .stTextInput > div > div > input,
43
+ .stTextArea textarea {
44
+ font-size: 16px;
45
+ }
46
+ .stButton>button {
47
+ background-color: #002b45;
48
+ color: white;
49
+ font-size: 16px;
50
+ padding: 0.4rem 1rem;
51
+ border-radius: 6px;
52
+ }
53
+ .stButton>button:hover {
54
+ background-color: #004b78;
55
+ }
56
+ .stMarkdown {
57
+ font-size: 16px;
58
+ }
59
+ </style>
60
+ """, unsafe_allow_html=True)
61
+
62
+ # ----------- Header Title (Centered + Bold + Large + Professional) -----------
63
+ st.markdown("""
64
+ <style>
65
+ .centered-title {
66
+ text-align: center;
67
+ font-size: 36px;
68
+ font-weight: 800;
69
+ font-family: 'Segoe UI', sans-serif;
70
+ color: #002b45;
71
+ margin-top: 20px;
72
+ margin-bottom: 20px;
73
+ }
74
+ </style>
75
+ <div class="centered-title">πŸ“Š EquiPulse: Stock Sentiment Tracker</div>
76
+ """, unsafe_allow_html=True)
77
+
78
+
79
+ # ----------- Description Section -----------
80
+ st.markdown("""
81
+ <div style='font-size:16px; line-height:1.6; color: #333333; margin-bottom: 1rem;'>
82
+ Analyze real-time financial sentiment from news headlines related to companies you're interested in.
83
+ </div>
84
+ """, unsafe_allow_html=True)
85
+
86
+ # ----------- Input Area -----------
87
+ st.markdown("#### 🎯 Enter Your Target Company Tickers")
88
+ free_text = st.text_area("Example: AAPL, NVDA, TSLA", height=90)
89
+
90
+ # ----------- Ticker Extraction -----------
91
+ ner_pipeline = get_ner_pipeline()
92
+ tickers = extract_org_entities(free_text, ner_pipeline)
93
+
94
+ if tickers:
95
+ st.markdown(f"βœ… **Recognized Tickers:** `{', '.join(tickers)}`")
96
+ else:
97
+ tickers = []
98
+
99
+ # ----------- Action Button -----------
100
+ if st.button("πŸ” Get News and Sentiment"):
101
+ if not tickers:
102
+ st.warning("⚠️ Please enter at least one recognizable company name or ticker.")
103
+ else:
104
+ sentiment_pipeline = get_sentiment_pipeline()
105
+ progress_bar = st.progress(0)
106
+ total_stocks = len(tickers)
107
+
108
+ for idx, ticker in enumerate(tickers):
109
+ st.markdown(f"---\n#### πŸ” Analyzing `{ticker}`")
110
+
111
+ news_list = fetch_news(ticker)
112
+
113
+ if news_list:
114
+ sentiments = [analyze_sentiment(news['title'], sentiment_pipeline) for news in news_list]
115
+ pos_count = sentiments.count("Positive")
116
+ neg_count = sentiments.count("Negative")
117
+ total = len(sentiments)
118
+ pos_ratio = pos_count / total if total else 0
119
+ neg_ratio = neg_count / total if total else 0
120
+
121
+ # Simple heuristic for overall sentiment
122
+ if pos_ratio >= 0.25:
123
+ overall = "Positive"
124
+ elif neg_ratio >= 0.75:
125
+ overall = "Negative"
126
+ else:
127
+ overall = "Neutral"
128
+
129
+ # Display news
130
+ st.markdown(f"**πŸ“° Top News for `{ticker}`:**")
131
+ for i, news in enumerate(news_list[:3]):
132
+ st.markdown(f"{i+1}. [{news['title']}]({news['link']}) β€” **{sentiments[i]}**")
133
+
134
+ st.success(f"πŸ“ˆ **Overall Sentiment for `{ticker}`: {overall}**")
135
+ else:
136
+ st.info(f"No recent news found for `{ticker}`.")
137
+
138
+ progress_bar.progress((idx + 1) / total_stocks)
139
+ time.sleep(0.1)