Spaces:
Sleeping
Sleeping
Create app.py
Browse files
app.py
ADDED
@@ -0,0 +1,145 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import pandas as pd
|
2 |
+
import numpy as np
|
3 |
+
from sklearn.linear_model import LinearRegression
|
4 |
+
from sklearn.ensemble import RandomForestRegressor
|
5 |
+
import gradio as gr
|
6 |
+
import yfinance as yf
|
7 |
+
import finnhub
|
8 |
+
import logging
|
9 |
+
|
10 |
+
# Setup logging
|
11 |
+
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
12 |
+
|
13 |
+
# Initialize Finnhub client (for financial data)
|
14 |
+
finnhub_client = finnhub.Client(api_key="your_finnhub_api_key")
|
15 |
+
|
16 |
+
# Define Shariah compliance rules
|
17 |
+
def is_shariah_compliant(row):
|
18 |
+
try:
|
19 |
+
# Check debt/asset ratio
|
20 |
+
if row['debt_to_asset_ratio'] > 0.33:
|
21 |
+
return False
|
22 |
+
# Check interest income
|
23 |
+
if row['interest_income'] / row['total_revenue'] > 0.05:
|
24 |
+
return False
|
25 |
+
# Check prohibited business activities
|
26 |
+
if row['alcohol_revenue'] > 0 or row['gambling_revenue'] > 0 or row['tobacco_revenue'] > 0:
|
27 |
+
return False
|
28 |
+
return True
|
29 |
+
except Exception as e:
|
30 |
+
logging.error(f"Error in Shariah compliance check: {e}")
|
31 |
+
return False
|
32 |
+
|
33 |
+
def get_stock_data(market):
|
34 |
+
tickers = []
|
35 |
+
if market == 'US':
|
36 |
+
tickers = yf.Tickers("^GSPC").symbols
|
37 |
+
elif market == 'HK':
|
38 |
+
tickers = yf.Tickers("^HSI").symbols
|
39 |
+
elif market == 'IN':
|
40 |
+
tickers = yf.Tickers("^BSESN").symbols
|
41 |
+
else:
|
42 |
+
logging.warning(f"Market {market} is not supported")
|
43 |
+
return pd.DataFrame()
|
44 |
+
|
45 |
+
# Fetch financial data from Finnhub
|
46 |
+
data = []
|
47 |
+
for ticker in tickers:
|
48 |
+
try:
|
49 |
+
company_profile = finnhub_client.company_profile2(symbol=ticker)
|
50 |
+
financials = finnhub_client.company_basic_financials(symbol=ticker, metric='all')
|
51 |
+
|
52 |
+
row = {
|
53 |
+
'stock_symbol': ticker,
|
54 |
+
'market': market,
|
55 |
+
'sector': company_profile.get('finnhubIndustry', 'Unknown'),
|
56 |
+
'debt_to_asset_ratio': financials['metric'].get('debtToAssets', np.nan),
|
57 |
+
'interest_income': financials['metric'].get('interestIncome', np.nan),
|
58 |
+
'total_revenue': financials['metric'].get('totalRevenue', np.nan),
|
59 |
+
'alcohol_revenue': 0, # Placeholder, needs additional data source
|
60 |
+
'gambling_revenue': 0, # Placeholder, needs additional data source
|
61 |
+
'tobacco_revenue': 0 # Placeholder, needs additional data source
|
62 |
+
}
|
63 |
+
data.append(row)
|
64 |
+
except Exception as e:
|
65 |
+
logging.error(f"Failed to fetch data for {ticker}: {e}")
|
66 |
+
continue
|
67 |
+
|
68 |
+
return pd.DataFrame(data)
|
69 |
+
|
70 |
+
def predict_stock_performance(market, sector, investment_horizon, model_type):
|
71 |
+
# Fetch stock data for the selected market
|
72 |
+
df = get_stock_data(market)
|
73 |
+
if df.empty:
|
74 |
+
return "No data available for the selected market."
|
75 |
+
|
76 |
+
# Apply Shariah compliance filtering
|
77 |
+
df['is_shariah_compliant'] = df.apply(is_shariah_compliant, axis=1)
|
78 |
+
shariah_compliant_df = df[df['is_shariah_compliant']]
|
79 |
+
|
80 |
+
if shariah_compliant_df.empty:
|
81 |
+
return "No Shariah-compliant stocks found."
|
82 |
+
|
83 |
+
# Check for required columns before training the model
|
84 |
+
required_columns = ['price_to_earnings', 'dividend_yield', 'revenue_growth']
|
85 |
+
for col in required_columns:
|
86 |
+
if col not in shariah_compliant_df.columns:
|
87 |
+
logging.error(f"Missing column: {col}")
|
88 |
+
return f"Error: Missing required financial data ({col})."
|
89 |
+
|
90 |
+
# Financial analysis and forecasting
|
91 |
+
X = shariah_compliant_df[required_columns]
|
92 |
+
y = shariah_compliant_df.get('future_price', pd.Series())
|
93 |
+
|
94 |
+
if y.empty:
|
95 |
+
return "Error: Future price data not available."
|
96 |
+
|
97 |
+
# Train the selected model
|
98 |
+
try:
|
99 |
+
if model_type == 'linear_regression':
|
100 |
+
model = LinearRegression()
|
101 |
+
elif model_type == 'random_forest':
|
102 |
+
model = RandomForestRegressor()
|
103 |
+
else:
|
104 |
+
return "Invalid model type selected."
|
105 |
+
|
106 |
+
model.fit(X, y)
|
107 |
+
|
108 |
+
# Predict future stock performance
|
109 |
+
shariah_compliant_df['predicted_price'] = model.predict(X)
|
110 |
+
except Exception as e:
|
111 |
+
logging.error(f"Model training failed: {e}")
|
112 |
+
return "Error in model training or prediction."
|
113 |
+
|
114 |
+
# Rank and recommend the top Shariah-compliant stocks
|
115 |
+
top_stocks = shariah_compliant_df[shariah_compliant_df['sector'] == sector].sort_values('predicted_price', ascending=False).head(5)
|
116 |
+
|
117 |
+
if top_stocks.empty:
|
118 |
+
return "No top stocks found in the selected sector."
|
119 |
+
|
120 |
+
# Prepare the output for the Gradio interface
|
121 |
+
output = '\n'.join(f"{row['stock_symbol']}: {row['predicted_price']}" for _, row in top_stocks.iterrows())
|
122 |
+
return output
|
123 |
+
|
124 |
+
def update_sectors(market):
|
125 |
+
df = get_stock_data(market)
|
126 |
+
if df.empty:
|
127 |
+
return []
|
128 |
+
|
129 |
+
return df['sector'].unique().tolist()
|
130 |
+
|
131 |
+
# Create the Gradio interface
|
132 |
+
with gr.Blocks() as app:
|
133 |
+
with gr.Row():
|
134 |
+
market = gr.Dropdown(['US', 'HK', 'IN'], label='Market', interactive=True)
|
135 |
+
sector = gr.Dropdown([], label='Sector', interactive=True)
|
136 |
+
|
137 |
+
investment_horizon = gr.Slider(1, 10, step=1, label='Investment Horizon (years)')
|
138 |
+
model_type = gr.Radio(['linear_regression', 'random_forest'], label='Model Type')
|
139 |
+
|
140 |
+
output = gr.Textbox(label='Recommended Shariah-Compliant Stocks')
|
141 |
+
|
142 |
+
market.change(fn=update_sectors, inputs=[market], outputs=[sector])
|
143 |
+
gr.Button('Predict').click(fn=predict_stock_performance, inputs=[market, sector, investment_horizon, model_type], outputs=[output])
|
144 |
+
|
145 |
+
app.launch()
|