Safwanahmad619 commited on
Commit
007ca59
Β·
verified Β·
1 Parent(s): 3932cf5

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +114 -0
app.py ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import yfinance as yf
3
+ import pandas as pd
4
+ import plotly.graph_objects as go
5
+ from transformers import pipeline
6
+ from datetime import datetime, timedelta
7
+ import requests
8
+ from bs4 import BeautifulSoup
9
+ import feedparser
10
+
11
+ # ------------------- Hugging Face Models -------------------
12
+ sentiment_analyzer = pipeline("text-classification", model="ProsusAI/finbert")
13
+ news_summarizer = pipeline("summarization", model="facebook/bart-large-cnn")
14
+ ner_model = pipeline("ner", model="dslim/bert-base-NER")
15
+ translator = pipeline("translation", model="Helsinki-NLP/opus-mt-ur-en")
16
+
17
+ # ------------------- Technical Analysis -------------------
18
+ def calculate_rsi(data, window=14):
19
+ delta = data['Close'].diff()
20
+ gain = (delta.where(delta > 0, 0)).rolling(window=window).mean()
21
+ loss = (-delta.where(delta < 0, 0)).rolling(window=window).mean()
22
+ rs = gain / loss
23
+ rsi = 100 - (100 / (1 + rs))
24
+ return rsi
25
+
26
+ # ------------------- Fetch PSX Data -------------------
27
+ def get_stock_data(ticker, period="1y"):
28
+ try:
29
+ stock = yf.Ticker(f"{ticker}.KAR")
30
+ data = stock.history(period=period)
31
+ if data.empty:
32
+ return None, "Error: Ticker not found or no data."
33
+ data['RSI'] = calculate_rsi(data)
34
+ return data, None
35
+ except Exception as e:
36
+ return None, f"Error: {str(e)}"
37
+
38
+ # ------------------- Sentiment & News Analysis -------------------
39
+ def analyze_sentiment(text):
40
+ return sentiment_analyzer(text)[0]['label']
41
+
42
+ def summarize_news(url):
43
+ response = requests.get(url)
44
+ soup = BeautifulSoup(response.text, 'html.parser')
45
+ paragraphs = soup.find_all('p')
46
+ article = ' '.join([p.get_text() for p in paragraphs[:5]])
47
+ summary = news_summarizer(article, max_length=100, min_length=30)[0]['summary_text']
48
+ return summary
49
+
50
+ def get_geo_news():
51
+ feed = feedparser.parse("https://www.dawn.com/feeds/pakistan")
52
+ news = []
53
+ for entry in feed.entries[:3]:
54
+ summary = summarize_news(entry.link)
55
+ sentiment = analyze_sentiment(entry.title)
56
+ news.append({"title": entry.title, "summary": summary, "sentiment": sentiment})
57
+ return news
58
+
59
+ # ------------------- Generate Signal -------------------
60
+ def generate_signal(rsi, sentiment_score, news_score):
61
+ if rsi < 30 and sentiment_score > 0.5 and news_score > 0.5:
62
+ return "STRONG BUY 🟒"
63
+ elif rsi > 70 or sentiment_score < -0.5:
64
+ return "STRONG SELL πŸ”΄"
65
+ else:
66
+ return "HOLD 🟑"
67
+
68
+ # ------------------- Gradio Interface -------------------
69
+ def analyze_stock(ticker):
70
+ # Fetch Data
71
+ data, error = get_stock_data(ticker)
72
+ if error:
73
+ return error, None, None
74
+
75
+ # Technical Analysis
76
+ latest_rsi = data['RSI'].iloc[-1]
77
+
78
+ # Sentiment & News Analysis
79
+ news = get_geo_news()
80
+ sentiment_scores = [1 if n['sentiment'] == 'positive' else -1 for n in news]
81
+ sentiment_score = sum(sentiment_scores) / len(sentiment_scores) if sentiment_scores else 0
82
+
83
+ # Generate Signal
84
+ signal = generate_signal(latest_rsi, sentiment_score, 0.5)
85
+
86
+ # Plot
87
+ fig = go.Figure(data=[go.Candlestick(x=data.index,
88
+ open=data['Open'], high=data['High'],
89
+ low=data['Low'], close=data['Close'])])
90
+ fig.update_layout(title=f"{ticker} Price Chart")
91
+
92
+ # News Summary
93
+ news_html = "<h3>Latest Geopolitical News:</h3>"
94
+ for n in news:
95
+ news_html += f"<p><b>{n['title']}</b> ({n['sentiment']})<br>{n['summary']}</p>"
96
+
97
+ return signal, fig.to_html(), news_html
98
+
99
+ # ------------------- Launch Gradio App -------------------
100
+ iface = gr.Interface(
101
+ fn=analyze_stock,
102
+ inputs=gr.Textbox(label="Enter PSX Stock Ticker (e.g., HBL, LUCK)"),
103
+ outputs=[
104
+ gr.Textbox(label="Recommendation"),
105
+ gr.HTML(label="Price Chart"),
106
+ gr.HTML(label="News Analysis")
107
+ ],
108
+ title="🟒 PSX Stock Analysis Chatbot πŸ”΄",
109
+ description="Real-time Technical, Sentiment, and News Analysis for Pakistan Stock Exchange",
110
+ allow_flagging="never"
111
+ )
112
+
113
+ if __name__ == "__main__":
114
+ iface.launch(share=True) # Set share=True for public URL