Spaces:
Runtime error
Runtime error
| import gradio as gr | |
| import yfinance as yf | |
| import pandas as pd | |
| import plotly.graph_objects as go | |
| from transformers import pipeline | |
| from datetime import datetime, timedelta | |
| import requests | |
| from bs4 import BeautifulSoup | |
| import feedparser | |
| # ------------------- Constants ------------------- | |
| KSE_100 = [ | |
| "HBL", "UBL", "MCB", "BAHL", "ABL", | |
| "LUCK", "EFERT", "FCCL", "DGKC", "MLCF", | |
| "OGDC", "PPL", "POL", "PSO", "SNGP", | |
| "ENGRO", "HUBC", "KAPCO", "NESTLE", "EFOODS", | |
| "PSX", "TRG", "SYS", "NML", "ILP", | |
| "ATRL", "NRL", "HASCOL", "SHEL", "BAFL" | |
| ] # Add all KSE-100 tickers | |
| # ------------------- Hugging Face Models ------------------- | |
| sentiment_analyzer = pipeline("text-classification", model="ProsusAI/finbert") | |
| news_summarizer = pipeline("summarization", model="facebook/bart-large-cnn") | |
| # ------------------- Technical Analysis ------------------- | |
| def calculate_rsi(data, window=14): | |
| delta = data['Close'].diff() | |
| gain = (delta.where(delta > 0, 0)).rolling(window=window).mean() | |
| loss = (-delta.where(delta < 0, 0)).rolling(window=window).mean() | |
| rs = gain / loss | |
| return 100 - (100 / (1 + rs)) | |
| # ------------------- Data Fetching ------------------- | |
| def get_stock_data(ticker): | |
| try: | |
| stock = yf.Ticker(f"{ticker}.KA") | |
| data = stock.history(period="1y") | |
| if data.empty: | |
| return None | |
| data['RSI'] = calculate_rsi(data) | |
| return data | |
| except: | |
| return None | |
| # ------------------- Analysis Engine ------------------- | |
| def analyze_ticker(ticker): | |
| data = get_stock_data(ticker) | |
| if data is None: | |
| return None | |
| current_price = data['Close'].iloc[-1] | |
| rsi = data['RSI'].iloc[-1] | |
| # Simple Recommendation Logic | |
| if rsi < 30: | |
| status = "STRONG BUY" | |
| color = "green" | |
| elif rsi > 70: | |
| status = "STRONG SELL" | |
| color = "red" | |
| else: | |
| status = "HOLD" | |
| color = "orange" | |
| return { | |
| "ticker": ticker, | |
| "price": round(current_price, 2), | |
| "rsi": round(rsi, 2), | |
| "status": status, | |
| "color": color | |
| } | |
| # ------------------- Generate Recommendations ------------------- | |
| def get_recommendations(): | |
| recommendations = [] | |
| for ticker in KSE_100: | |
| analysis = analyze_ticker(ticker) | |
| if analysis: | |
| recommendations.append(analysis) | |
| df = pd.DataFrame(recommendations) | |
| df = df.sort_values(by='rsi') | |
| return df | |
| # ------------------- Interface Components ------------------- | |
| def create_stock_analysis(ticker): | |
| data = get_stock_data(ticker) | |
| if data is None: | |
| return "Data not available", None, None | |
| # Create Plot | |
| fig = go.Figure(data=[go.Candlestick( | |
| x=data.index, | |
| open=data['Open'], | |
| high=data['High'], | |
| low=data['Low'], | |
| close=data['Close'] | |
| )]) | |
| fig.update_layout(title=f"{ticker} Price Chart") | |
| # Analysis | |
| analysis = analyze_ticker(ticker) | |
| status_md = f"## {analysis['status']} \n" \ | |
| f"**Price**: {analysis['price']} \n" \ | |
| f"**RSI**: {analysis['rsi']}" | |
| return status_md, fig.to_html(), get_news(ticker) | |
| def get_news(ticker): | |
| try: | |
| url = f"https://www.google.com/search?q={ticker}+stock+pakistan&tbm=nws" | |
| response = requests.get(url) | |
| soup = BeautifulSoup(response.text, 'html.parser') | |
| articles = soup.find_all('div', class_='BNeawe vvjwJb AP7Wnd')[:3] | |
| return "\n\n".join([a.text for a in articles]) | |
| except: | |
| return "News unavailable" | |
| # ------------------- Gradio Interface ------------------- | |
| with gr.Blocks(title="PSX Trading Dashboard", theme=gr.themes.Soft()) as app: | |
| with gr.Row(): | |
| # Left Sidebar - KSE-100 List | |
| with gr.Column(scale=1, min_width=200): | |
| gr.Markdown("## KSE-100 Constituents") | |
| kse_list = gr.DataFrame( | |
| value=pd.DataFrame(KSE_100, columns=["Ticker"]), | |
| interactive=False, | |
| height=600 | |
| ) | |
| # Main Content | |
| with gr.Column(scale=3): | |
| gr.Markdown("# PSX Trading Dashboard") | |
| with gr.Row(): | |
| ticker_input = gr.Textbox(label="Enter Ticker", placeholder="HBL") | |
| analyze_btn = gr.Button("Analyze") | |
| status_output = gr.Markdown() | |
| chart_output = gr.HTML() | |
| news_output = gr.Textbox(label="Latest News", interactive=False) | |
| # Right Sidebar - Recommendations | |
| with gr.Column(scale=1, min_width=200): | |
| gr.Markdown("## Live Recommendations") | |
| recommendations = gr.DataFrame( | |
| headers=["Ticker", "Price", "RSI", "Status"], | |
| datatype=["str", "number", "number", "str"], | |
| interactive=False, | |
| height=600 | |
| ) | |
| # Event Handlers | |
| analyze_btn.click( | |
| fn=create_stock_analysis, | |
| inputs=ticker_input, | |
| outputs=[status_output, chart_output, news_output] | |
| ) | |
| app.load( | |
| fn=get_recommendations, | |
| outputs=recommendations, | |
| every=300 # Refresh every 5 minutes | |
| ) | |
| # ------------------- Run App ------------------- | |
| if __name__ == "__main__": | |
| app.launch(server_port=7860, share=True) |