Safwanahmad619 commited on
Commit
1a8b90a
Β·
verified Β·
1 Parent(s): 3d318ce

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +167 -0
app.py ADDED
@@ -0,0 +1,167 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ # ------------------- Constants -------------------
12
+ KSE_100 = [
13
+ "HBL", "UBL", "MCB", "BAHL", "ABL",
14
+ "LUCK", "EFERT", "FCCL", "DGKC", "MLCF",
15
+ "OGDC", "PPL", "POL", "PSO", "SNGP",
16
+ "ENGRO", "HUBC", "KAPCO", "NESTLE", "EFOODS",
17
+ "PSX", "TRG", "SYS", "NML", "ILP",
18
+ "ATRL", "NRL", "HASCOL", "SHEL", "BAFL"
19
+ ] # Add all KSE-100 tickers
20
+
21
+ # ------------------- Hugging Face Models -------------------
22
+ sentiment_analyzer = pipeline("text-classification", model="ProsusAI/finbert")
23
+ news_summarizer = pipeline("summarization", model="facebook/bart-large-cnn")
24
+
25
+ # ------------------- Technical Analysis -------------------
26
+ def calculate_rsi(data, window=14):
27
+ delta = data['Close'].diff()
28
+ gain = (delta.where(delta > 0, 0)).rolling(window=window).mean()
29
+ loss = (-delta.where(delta < 0, 0)).rolling(window=window).mean()
30
+ rs = gain / loss
31
+ return 100 - (100 / (1 + rs))
32
+
33
+ # ------------------- Data Fetching -------------------
34
+ def get_stock_data(ticker):
35
+ try:
36
+ stock = yf.Ticker(f"{ticker}.KA")
37
+ data = stock.history(period="1y")
38
+ if data.empty:
39
+ return None
40
+ data['RSI'] = calculate_rsi(data)
41
+ return data
42
+ except:
43
+ return None
44
+
45
+ # ------------------- Analysis Engine -------------------
46
+ def analyze_ticker(ticker):
47
+ data = get_stock_data(ticker)
48
+ if data is None:
49
+ return None
50
+
51
+ current_price = data['Close'].iloc[-1]
52
+ rsi = data['RSI'].iloc[-1]
53
+
54
+ # Simple Recommendation Logic
55
+ if rsi < 30:
56
+ status = "STRONG BUY"
57
+ color = "green"
58
+ elif rsi > 70:
59
+ status = "STRONG SELL"
60
+ color = "red"
61
+ else:
62
+ status = "HOLD"
63
+ color = "orange"
64
+
65
+ return {
66
+ "ticker": ticker,
67
+ "price": round(current_price, 2),
68
+ "rsi": round(rsi, 2),
69
+ "status": status,
70
+ "color": color
71
+ }
72
+
73
+ # ------------------- Generate Recommendations -------------------
74
+ def get_recommendations():
75
+ recommendations = []
76
+ for ticker in KSE_100:
77
+ analysis = analyze_ticker(ticker)
78
+ if analysis:
79
+ recommendations.append(analysis)
80
+
81
+ df = pd.DataFrame(recommendations)
82
+ df = df.sort_values(by='rsi')
83
+ return df
84
+
85
+ # ------------------- Interface Components -------------------
86
+ def create_stock_analysis(ticker):
87
+ data = get_stock_data(ticker)
88
+ if data is None:
89
+ return "Data not available", None, None
90
+
91
+ # Create Plot
92
+ fig = go.Figure(data=[go.Candlestick(
93
+ x=data.index,
94
+ open=data['Open'],
95
+ high=data['High'],
96
+ low=data['Low'],
97
+ close=data['Close']
98
+ )])
99
+ fig.update_layout(title=f"{ticker} Price Chart")
100
+
101
+ # Analysis
102
+ analysis = analyze_ticker(ticker)
103
+ status_md = f"## {analysis['status']} \n" \
104
+ f"**Price**: {analysis['price']} \n" \
105
+ f"**RSI**: {analysis['rsi']}"
106
+
107
+ return status_md, fig.to_html(), get_news(ticker)
108
+
109
+ def get_news(ticker):
110
+ try:
111
+ url = f"https://www.google.com/search?q={ticker}+stock+pakistan&tbm=nws"
112
+ response = requests.get(url)
113
+ soup = BeautifulSoup(response.text, 'html.parser')
114
+ articles = soup.find_all('div', class_='BNeawe vvjwJb AP7Wnd')[:3]
115
+ return "\n\n".join([a.text for a in articles])
116
+ except:
117
+ return "News unavailable"
118
+
119
+ # ------------------- Gradio Interface -------------------
120
+ with gr.Blocks(title="PSX Trading Dashboard", theme=gr.themes.Soft()) as app:
121
+ with gr.Row():
122
+ # Left Sidebar - KSE-100 List
123
+ with gr.Column(scale=1, min_width=200):
124
+ gr.Markdown("## KSE-100 Constituents")
125
+ kse_list = gr.DataFrame(
126
+ value=pd.DataFrame(KSE_100, columns=["Ticker"]),
127
+ interactive=False,
128
+ height=600
129
+ )
130
+
131
+ # Main Content
132
+ with gr.Column(scale=3):
133
+ gr.Markdown("# PSX Trading Dashboard")
134
+ with gr.Row():
135
+ ticker_input = gr.Textbox(label="Enter Ticker", placeholder="HBL")
136
+ analyze_btn = gr.Button("Analyze")
137
+
138
+ status_output = gr.Markdown()
139
+ chart_output = gr.HTML()
140
+ news_output = gr.Textbox(label="Latest News", interactive=False)
141
+
142
+ # Right Sidebar - Recommendations
143
+ with gr.Column(scale=1, min_width=200):
144
+ gr.Markdown("## Live Recommendations")
145
+ recommendations = gr.DataFrame(
146
+ headers=["Ticker", "Price", "RSI", "Status"],
147
+ datatype=["str", "number", "number", "str"],
148
+ interactive=False,
149
+ height=600
150
+ )
151
+
152
+ # Event Handlers
153
+ analyze_btn.click(
154
+ fn=create_stock_analysis,
155
+ inputs=ticker_input,
156
+ outputs=[status_output, chart_output, news_output]
157
+ )
158
+
159
+ app.load(
160
+ fn=get_recommendations,
161
+ outputs=recommendations,
162
+ every=300 # Refresh every 5 minutes
163
+ )
164
+
165
+ # ------------------- Run App -------------------
166
+ if __name__ == "__main__":
167
+ app.launch(server_port=7860, share=True)