Spaces:
Sleeping
Sleeping
Update Gradio app with multiple files
Browse files- app.py +41 -29
- data_processor.py +6 -4
- requirements.txt +1 -0
- sentiment_analyzer.py +1 -12
- trading_logic.py +14 -13
app.py
CHANGED
|
@@ -46,34 +46,46 @@ def create_chart_analysis(interval, asset_name):
|
|
| 46 |
# Prepare additional plots for indicators
|
| 47 |
ap = []
|
| 48 |
|
| 49 |
-
# Add moving averages
|
| 50 |
-
|
| 51 |
-
|
|
|
|
|
|
|
| 52 |
|
| 53 |
# Add Bollinger Bands
|
| 54 |
-
|
| 55 |
-
|
|
|
|
| 56 |
|
| 57 |
# Create figure
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
axes
|
| 76 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 77 |
|
| 78 |
# Prepare data for Chronos
|
| 79 |
prepared_data = data_processor.prepare_for_chronos(df)
|
|
@@ -89,7 +101,7 @@ def create_chart_analysis(interval, asset_name):
|
|
| 89 |
|
| 90 |
# Calculate TP/SL
|
| 91 |
tp, sl = trading_logic.calculate_tp_sl(
|
| 92 |
-
current_price, df['ATR'].iloc[-1], signal
|
| 93 |
)
|
| 94 |
|
| 95 |
# Create metrics display
|
|
@@ -99,9 +111,9 @@ def create_chart_analysis(interval, asset_name):
|
|
| 99 |
"Confidence": f"{confidence:.1%}",
|
| 100 |
"Take Profit": f"${tp:,.2f}" if tp else "N/A",
|
| 101 |
"Stop Loss": f"${sl:,.2f}" if sl else "N/A",
|
| 102 |
-
"RSI": f"{df['RSI'].iloc[-1]:.1f}",
|
| 103 |
-
"MACD": f"{df['MACD'].iloc[-1]:.4f}",
|
| 104 |
-
"Volume": f"{df['Volume'].iloc[-1]:,.0f}"
|
| 105 |
}
|
| 106 |
|
| 107 |
# Create prediction chart using matplotlib
|
|
@@ -349,4 +361,4 @@ if __name__ == "__main__":
|
|
| 349 |
server_port=7860,
|
| 350 |
share=False,
|
| 351 |
show_api=True
|
| 352 |
-
)
|
|
|
|
| 46 |
# Prepare additional plots for indicators
|
| 47 |
ap = []
|
| 48 |
|
| 49 |
+
# Add moving averages (last 100 data points)
|
| 50 |
+
if 'SMA_20' in df.columns:
|
| 51 |
+
ap.append(mpf.make_addplot(df['SMA_20'].iloc[-100:], color='#FFA500', width=1.5, label='SMA 20'))
|
| 52 |
+
if 'SMA_50' in df.columns:
|
| 53 |
+
ap.append(mpf.make_addplot(df['SMA_50'].iloc[-100:], color='#FF4500', width=1.5, label='SMA 50'))
|
| 54 |
|
| 55 |
# Add Bollinger Bands
|
| 56 |
+
if 'BB_upper' in df.columns and 'BB_lower' in df.columns:
|
| 57 |
+
ap.append(mpf.make_addplot(df['BB_upper'].iloc[-100:], color='#4169E1', width=1, linestyle='dashed', label='BB Upper'))
|
| 58 |
+
ap.append(mpf.make_addplot(df['BB_lower'].iloc[-100:], color='#4169E1', width=1, linestyle='dashed', label='BB Lower'))
|
| 59 |
|
| 60 |
# Create figure
|
| 61 |
+
try:
|
| 62 |
+
fig, axes = mpf.plot(
|
| 63 |
+
df[-100:], # Show last 100 candles
|
| 64 |
+
type='candle',
|
| 65 |
+
style='yahoo',
|
| 66 |
+
title=f'{asset_name} - {interval}',
|
| 67 |
+
ylabel='Price (USD)',
|
| 68 |
+
volume=True,
|
| 69 |
+
addplot=ap,
|
| 70 |
+
figsize=(12, 8),
|
| 71 |
+
returnfig=True,
|
| 72 |
+
warn_too_much_data=200,
|
| 73 |
+
tight_layout=True
|
| 74 |
+
)
|
| 75 |
+
|
| 76 |
+
# Adjust layout
|
| 77 |
+
fig.patch.set_facecolor('white')
|
| 78 |
+
if axes:
|
| 79 |
+
axes[0].set_facecolor('white')
|
| 80 |
+
axes[0].grid(True, alpha=0.3)
|
| 81 |
+
except Exception as plot_error:
|
| 82 |
+
print(f"Mplfinance plot error: {plot_error}")
|
| 83 |
+
fig, axes = plt.subplots(figsize=(12, 8), facecolor='white')
|
| 84 |
+
fig.patch.set_facecolor('white')
|
| 85 |
+
axes.text(0.5, 0.5, f'Chart Plot Error: {str(plot_error)}', ha='center', va='center',
|
| 86 |
+
transform=axes.transAxes, fontsize=14, color='red')
|
| 87 |
+
axes.set_title('Plot Generation Error', color='black')
|
| 88 |
+
axes.axis('off')
|
| 89 |
|
| 90 |
# Prepare data for Chronos
|
| 91 |
prepared_data = data_processor.prepare_for_chronos(df)
|
|
|
|
| 101 |
|
| 102 |
# Calculate TP/SL
|
| 103 |
tp, sl = trading_logic.calculate_tp_sl(
|
| 104 |
+
current_price, df['ATR'].iloc[-1] if 'ATR' in df.columns else 10, signal
|
| 105 |
)
|
| 106 |
|
| 107 |
# Create metrics display
|
|
|
|
| 111 |
"Confidence": f"{confidence:.1%}",
|
| 112 |
"Take Profit": f"${tp:,.2f}" if tp else "N/A",
|
| 113 |
"Stop Loss": f"${sl:,.2f}" if sl else "N/A",
|
| 114 |
+
"RSI": f"{df['RSI'].iloc[-1]:.1f}" if 'RSI' in df.columns else "N/A",
|
| 115 |
+
"MACD": f"{df['MACD'].iloc[-1]:.4f}" if 'MACD' in df.columns else "N/A",
|
| 116 |
+
"Volume": f"{df['Volume'].iloc[-1]:,.0f}" if 'Volume' in df.columns else "N/A"
|
| 117 |
}
|
| 118 |
|
| 119 |
# Create prediction chart using matplotlib
|
|
|
|
| 361 |
server_port=7860,
|
| 362 |
share=False,
|
| 363 |
show_api=True
|
| 364 |
+
)
|
data_processor.py
CHANGED
|
@@ -89,8 +89,9 @@ class DataProcessor:
|
|
| 89 |
df['ATR'] = true_range.rolling(window=14).mean()
|
| 90 |
|
| 91 |
# Volume indicators
|
| 92 |
-
|
| 93 |
-
|
|
|
|
| 94 |
|
| 95 |
return df
|
| 96 |
|
|
@@ -102,9 +103,10 @@ class DataProcessor:
|
|
| 102 |
|
| 103 |
# Asset-specific fundamentals
|
| 104 |
if ticker == "BTC-USD":
|
|
|
|
| 105 |
fundamentals = {
|
| 106 |
"Strength Index": round(np.random.uniform(30, 80), 1),
|
| 107 |
-
"Market Cap": f"${
|
| 108 |
"24h Volume": f"${np.random.uniform(20, 80):.1f}B",
|
| 109 |
"Volatility": f"{np.random.uniform(40, 120):.1f}%",
|
| 110 |
"Network Hash Rate": f"{np.random.uniform(300, 600):.0f} EH/s",
|
|
@@ -151,4 +153,4 @@ class DataProcessor:
|
|
| 151 |
'mean': mean,
|
| 152 |
'std': std,
|
| 153 |
'original': prices
|
| 154 |
-
}
|
|
|
|
| 89 |
df['ATR'] = true_range.rolling(window=14).mean()
|
| 90 |
|
| 91 |
# Volume indicators
|
| 92 |
+
if 'Volume' in df.columns:
|
| 93 |
+
df['Volume_SMA'] = df['Volume'].rolling(window=20).mean()
|
| 94 |
+
df['Volume_ratio'] = df['Volume'] / df['Volume_SMA']
|
| 95 |
|
| 96 |
return df
|
| 97 |
|
|
|
|
| 103 |
|
| 104 |
# Asset-specific fundamentals
|
| 105 |
if ticker == "BTC-USD":
|
| 106 |
+
market_cap = info.get('marketCap', 0)
|
| 107 |
fundamentals = {
|
| 108 |
"Strength Index": round(np.random.uniform(30, 80), 1),
|
| 109 |
+
"Market Cap": f"${market_cap:,.0f}" if market_cap else "N/A",
|
| 110 |
"24h Volume": f"${np.random.uniform(20, 80):.1f}B",
|
| 111 |
"Volatility": f"{np.random.uniform(40, 120):.1f}%",
|
| 112 |
"Network Hash Rate": f"{np.random.uniform(300, 600):.0f} EH/s",
|
|
|
|
| 153 |
'mean': mean,
|
| 154 |
'std': std,
|
| 155 |
'original': prices
|
| 156 |
+
}
|
requirements.txt
CHANGED
|
@@ -14,3 +14,4 @@ yfinance
|
|
| 14 |
seaborn
|
| 15 |
plotly
|
| 16 |
tqdm
|
|
|
|
|
|
| 14 |
seaborn
|
| 15 |
plotly
|
| 16 |
tqdm
|
| 17 |
+
chronos-forecasting
|
sentiment_analyzer.py
CHANGED
|
@@ -64,15 +64,4 @@ class SentimentAnalyzer:
|
|
| 64 |
return sentiment, news_html
|
| 65 |
|
| 66 |
except Exception as e:
|
| 67 |
-
return 0, f"<p>Error analyzing sentiment: {str(e)}</p>"
|
| 68 |
-
|
| 69 |
-
**Key Changes Made:**
|
| 70 |
-
|
| 71 |
-
1. **Error Handling**: Instead of returning `str(e)`, the functions now create proper matplotlib figures with error messages displayed as text within the plot
|
| 72 |
-
2. **Interval Fix**: Removed "4h" interval from dropdown since it's not supported for BTC-USD
|
| 73 |
-
3. **UI Colors**: Ensured all components have white background with black text for proper visibility
|
| 74 |
-
4. **Consistent Plot Returns**: All code paths now return valid matplotlib figure objects
|
| 75 |
-
5. **Better Error Messages**: Errors are now displayed inside the plot area rather than breaking the UI
|
| 76 |
-
6. **Data Validation**: Added more checks for empty dataframes and invalid inputs
|
| 77 |
-
|
| 78 |
-
The app should now load without errors and properly display both Gold and Bitcoin analysis with a clean white theme.
|
|
|
|
| 64 |
return sentiment, news_html
|
| 65 |
|
| 66 |
except Exception as e:
|
| 67 |
+
return 0, f"<p>Error analyzing sentiment: {str(e)}</p>"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
trading_logic.py
CHANGED
|
@@ -11,16 +11,16 @@ class TradingLogic:
|
|
| 11 |
return "hold", 0.0
|
| 12 |
|
| 13 |
# Get last values
|
| 14 |
-
rsi = df['RSI'].iloc[-1]
|
| 15 |
-
macd = df['MACD'].iloc[-1]
|
| 16 |
-
macd_signal = df['MACD_signal'].iloc[-1]
|
| 17 |
|
| 18 |
# Prediction trend
|
| 19 |
pred_trend = np.polyfit(range(len(predictions)), predictions, 1)[0]
|
| 20 |
|
| 21 |
# Price vs predictions
|
| 22 |
pred_mean = np.mean(predictions)
|
| 23 |
-
price_diff_pct = (pred_mean - current_price) / current_price
|
| 24 |
|
| 25 |
# Initialize signals
|
| 26 |
signals = []
|
|
@@ -51,13 +51,14 @@ class TradingLogic:
|
|
| 51 |
confidences.append(min(abs(price_diff_pct) * 10, 0.8))
|
| 52 |
|
| 53 |
# Bollinger Bands
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
|
|
|
|
| 61 |
|
| 62 |
# Aggregate signals
|
| 63 |
if not signals:
|
|
@@ -90,8 +91,8 @@ class TradingLogic:
|
|
| 90 |
return None, None
|
| 91 |
|
| 92 |
# Use 2x ATR for stop loss, 4x ATR for take profit (1:2 ratio)
|
| 93 |
-
sl_distance = atr * 2
|
| 94 |
-
tp_distance = atr * 4
|
| 95 |
|
| 96 |
if signal == "buy":
|
| 97 |
tp = current_price + tp_distance
|
|
|
|
| 11 |
return "hold", 0.0
|
| 12 |
|
| 13 |
# Get last values
|
| 14 |
+
rsi = df['RSI'].iloc[-1] if 'RSI' in df.columns else 50
|
| 15 |
+
macd = df['MACD'].iloc[-1] if 'MACD' in df.columns else 0
|
| 16 |
+
macd_signal = df['MACD_signal'].iloc[-1] if 'MACD_signal' in df.columns else 0
|
| 17 |
|
| 18 |
# Prediction trend
|
| 19 |
pred_trend = np.polyfit(range(len(predictions)), predictions, 1)[0]
|
| 20 |
|
| 21 |
# Price vs predictions
|
| 22 |
pred_mean = np.mean(predictions)
|
| 23 |
+
price_diff_pct = (pred_mean - current_price) / current_price if current_price != 0 else 0
|
| 24 |
|
| 25 |
# Initialize signals
|
| 26 |
signals = []
|
|
|
|
| 51 |
confidences.append(min(abs(price_diff_pct) * 10, 0.8))
|
| 52 |
|
| 53 |
# Bollinger Bands
|
| 54 |
+
if 'BB_lower' in df.columns and 'BB_upper' in df.columns:
|
| 55 |
+
bb_position = (current_price - df['BB_lower'].iloc[-1]) / (df['BB_upper'].iloc[-1] - df['BB_lower'].iloc[-1])
|
| 56 |
+
if bb_position < 0.2:
|
| 57 |
+
signals.append("buy")
|
| 58 |
+
confidences.append(0.5)
|
| 59 |
+
elif bb_position > 0.8:
|
| 60 |
+
signals.append("sell")
|
| 61 |
+
confidences.append(0.5)
|
| 62 |
|
| 63 |
# Aggregate signals
|
| 64 |
if not signals:
|
|
|
|
| 91 |
return None, None
|
| 92 |
|
| 93 |
# Use 2x ATR for stop loss, 4x ATR for take profit (1:2 ratio)
|
| 94 |
+
sl_distance = atr * 2 if atr else current_price * 0.02
|
| 95 |
+
tp_distance = atr * 4 if atr else current_price * 0.04
|
| 96 |
|
| 97 |
if signal == "buy":
|
| 98 |
tp = current_price + tp_distance
|