omniverse1 commited on
Commit
f27fbb4
·
verified ·
1 Parent(s): 29091b3

Update Gradio app with multiple files

Browse files
Files changed (5) hide show
  1. app.py +181 -184
  2. data_processor.py +33 -21
  3. model_handler.py +2 -5
  4. requirements.txt +3 -1
  5. sentiment_analyzer.py +23 -10
app.py CHANGED
@@ -1,11 +1,14 @@
1
  import gradio as gr
2
  import pandas as pd
3
- import plotly.graph_objects as go
 
 
4
  from data_processor import DataProcessor
5
  from sentiment_analyzer import SentimentAnalyzer
6
  from model_handler import ModelHandler
7
  from trading_logic import TradingLogic
8
- import numpy as np
 
9
 
10
  # Global instances
11
  data_processor = DataProcessor()
@@ -13,72 +16,60 @@ sentiment_analyzer = SentimentAnalyzer()
13
  model_handler = ModelHandler()
14
  trading_logic = TradingLogic()
15
 
16
- def create_chart_analysis(interval):
17
- """Create chart with technical indicators"""
 
 
 
 
 
 
18
  try:
19
- df = data_processor.get_gold_data(interval)
 
20
  if df.empty:
21
  return "No data available", None, None
22
 
23
  # Calculate indicators
24
  df = data_processor.calculate_indicators(df)
25
 
26
- # Create candlestick chart
27
- fig = go.Figure(data=[
28
- go.Candlestick(
29
- x=df.index,
30
- open=df['Open'],
31
- high=df['High'],
32
- low=df['Low'],
33
- close=df['Close'],
34
- name='Gold Price'
35
- )
36
- ])
37
 
38
  # Add Bollinger Bands
39
- fig.add_trace(go.Scatter(
40
- x=df.index, y=df['BB_upper'],
41
- line=dict(color='rgba(255,255,255,0.3)', width=1),
42
- name='BB Upper', showlegend=False
43
- ))
44
- fig.add_trace(go.Scatter(
45
- x=df.index, y=df['BB_lower'],
46
- line=dict(color='rgba(255,255,255,0.3)', width=1),
47
- fill='tonexty', fillcolor='rgba(255,255,255,0.1)',
48
- name='BB Lower', showlegend=False
49
- ))
50
 
51
- # Add moving averages
52
- fig.add_trace(go.Scatter(
53
- x=df.index, y=df['SMA_20'],
54
- line=dict(color='#FFD700', width=2),
55
- name='SMA 20'
56
- ))
57
- fig.add_trace(go.Scatter(
58
- x=df.index, y=df['SMA_50'],
59
- line=dict(color='#FFA500', width=2),
60
- name='SMA 50'
61
- ))
62
-
63
- fig.update_layout(
64
- title=f'Gold Futures (GC=F) - {interval}',
65
- yaxis_title='Price (USD)',
66
- xaxis_title='Date',
67
- template='plotly_dark',
68
- height=500,
69
- margin=dict(l=50, r=50, t=50, b=50),
70
- xaxis_rangeslider_visible=False,
71
- paper_bgcolor='rgba(0,0,0,0)',
72
- plot_bgcolor='rgba(0,0,0,0)',
73
- font=dict(color='white')
74
  )
75
 
76
- # KOREKSI: Panggil prepare_for_chronos sebelum prediksi
 
 
 
 
 
 
77
  prepared_data = data_processor.prepare_for_chronos(df)
78
-
79
  # Generate predictions
80
  predictions = model_handler.predict(prepared_data, horizon=10)
81
-
82
  current_price = df['Close'].iloc[-1]
83
 
84
  # Get signal
@@ -93,102 +84,99 @@ def create_chart_analysis(interval):
93
 
94
  # Create metrics display
95
  metrics = {
96
- "Current Price": f"${current_price:.2f}",
97
  "Signal": signal.upper(),
98
  "Confidence": f"{confidence:.1%}",
99
- "Take Profit": f"${tp:.2f}" if tp else "N/A",
100
- "Stop Loss": f"${sl:.2f}" if sl else "N/A",
101
  "RSI": f"{df['RSI'].iloc[-1]:.1f}",
102
  "MACD": f"{df['MACD'].iloc[-1]:.4f}",
103
  "Volume": f"{df['Volume'].iloc[-1]:,.0f}"
104
  }
105
 
106
- # Create prediction chart
107
- pred_fig = go.Figure()
 
 
 
 
 
 
108
 
109
- # Check if predictions are valid before plotting
110
- if predictions.any():
111
  future_dates = pd.date_range(
112
  start=df.index[-1], periods=len(predictions), freq='D'
113
  )
 
 
114
 
115
- pred_fig.add_trace(go.Scatter(
116
- x=future_dates, y=predictions,
117
- mode='lines+markers',
118
- line=dict(color='#FFD700', width=3),
119
- marker=dict(size=6),
120
- name='Predictions'
121
- ))
122
-
123
- pred_fig.add_trace(go.Scatter(
124
- x=[df.index[-1], future_dates[0]],
125
- y=[current_price, predictions[0]],
126
- mode='lines',
127
- line=dict(color='rgba(255,215,0,0.5)', width=2, dash='dash'),
128
- showlegend=False
129
- ))
130
-
131
- pred_fig.update_layout(
132
- title='Price Prediction (Next 10 Periods)',
133
- yaxis_title='Price (USD)',
134
- xaxis_title='Date',
135
- template='plotly_dark',
136
- height=300,
137
- paper_bgcolor='rgba(0,0,0,0)',
138
- plot_bgcolor='rgba(0,0,0,0)',
139
- font=dict(color='white')
140
- )
141
 
142
  return fig, metrics, pred_fig
143
 
144
  except Exception as e:
145
  return str(e), None, None
146
 
147
- def analyze_sentiment():
148
- """Analyze gold market sentiment"""
149
  try:
150
- sentiment_score, news_summary = sentiment_analyzer.analyze_gold_sentiment()
151
-
152
- # Create sentiment gauge
153
- fig = go.Figure(go.Indicator(
154
- mode="gauge+number+delta",
155
- value=sentiment_score,
156
- domain={'x': [0, 1], 'y': [0, 1]},
157
- title={'text': "Gold Market Sentiment"},
158
- delta={'reference': 0},
159
- gauge={
160
- 'axis': {'range': [-1, 1]},
161
- 'bar': {'color': "#FFD700"},
162
- 'steps': [
163
- {'range': [-1, -0.5], 'color': "rgba(255,0,0,0.5)"},
164
- {'range': [-0.5, 0.5], 'color': "rgba(255,255,255,0.3)"},
165
- {'range': [0.5, 1], 'color': "rgba(0,255,0,0.5)"}
166
- ],
167
- 'threshold': {
168
- 'line': {'color': "white", 'width': 4},
169
- 'thickness': 0.75,
170
- 'value': 0
171
- }
172
- }
173
- ))
174
-
175
- fig.update_layout(
176
- template='plotly_dark',
177
- height=300,
178
- paper_bgcolor='rgba(0,0,0,0)',
179
- plot_bgcolor='rgba(0,0,0,0)',
180
- font=dict(color='white')
181
- )
 
 
 
182
 
183
  return fig, news_summary
184
 
185
  except Exception as e:
186
  return str(e), None
187
 
188
- def get_fundamentals():
189
  """Get fundamental analysis data"""
190
  try:
191
- fundamentals = data_processor.get_fundamental_data()
 
192
 
193
  # Create fundamentals table
194
  table_data = []
@@ -198,28 +186,21 @@ def get_fundamentals():
198
  df = pd.DataFrame(table_data, columns=['Metric', 'Value'])
199
 
200
  # Create fundamentals gauge chart
201
- fig = go.Figure(go.Indicator(
202
- mode="gauge+number",
203
- value=fundamentals.get('Gold Strength Index', 50),
204
- title={'text': "Gold Strength Index"},
205
- gauge={
206
- 'axis': {'range': [0, 100]},
207
- 'bar': {'color': "#FFD700"},
208
- 'steps': [
209
- {'range': [0, 30], 'color': "rgba(255,0,0,0.5)"},
210
- {'range': [30, 70], 'color': "rgba(255,255,255,0.3)"},
211
- {'range': [70, 100], 'color': "rgba(0,255,0,0.5)"}
212
- ]
213
- }
214
- ))
215
-
216
- fig.update_layout(
217
- template='plotly_dark',
218
- height=300,
219
- paper_bgcolor='rgba(0,0,0,0)',
220
- plot_bgcolor='rgba(0,0,0,0)',
221
- font=dict(color='white')
222
- )
223
 
224
  return fig, df
225
 
@@ -228,73 +209,89 @@ def get_fundamentals():
228
 
229
  # Create Gradio interface
230
  with gr.Blocks(
231
- theme=gr.themes.Default(primary_hue="yellow", secondary_hue="yellow"),
232
- title="Gold Trading Analysis & Prediction",
233
  css="""
234
- .gradio-container {background-color: #000000; color: #FFFFFF}
235
- .gr-button-primary {background-color: #FFD700 !important; color: #000000 !important}
236
- .gr-button-secondary {border-color: #FFD700 !important; color: #FFD700 !important}
237
- .gr-tab button {color: #FFFFFF !important}
238
- .gr-tab button.selected {background-color: #FFD700 !important; color: #000000 !important}
239
- .gr-highlighted {background-color: #1a1a1a !important}
240
- .anycoder-link {color: #FFD700 !important; text-decoration: none; font-weight: bold}
 
241
  """
242
  ) as demo:
243
 
244
  # Header with anycoder link
245
  gr.HTML("""
246
  <div style="text-align: center; padding: 20px;">
247
- <h1 style="color: #FFD700;">Gold Trading Analysis & Prediction</h1>
248
- <p>Advanced AI-powered analysis for Gold Futures (GC=F)</p>
249
  <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="anycoder-link">Built with anycoder</a>
250
  </div>
251
  """)
252
 
253
  with gr.Row():
254
- interval_dropdown = gr.Dropdown(
255
- choices=[
256
- "5m", "15m", "30m", "1h", "4h", "1d", "1wk", "1mo", "3mo"
257
- ],
258
- value="1d",
259
- label="Time Interval",
260
- info="Select analysis timeframe"
261
- )
262
- refresh_btn = gr.Button("売 Refresh Data", variant="primary")
 
 
 
 
 
 
 
 
 
263
 
264
  with gr.Tabs():
265
- with gr.TabItem("投 Chart Analysis"):
266
  with gr.Row():
267
- chart_plot = gr.Plot(label="Price Chart")
268
- pred_plot = gr.Plot(label="Predictions")
 
 
269
 
270
  with gr.Row():
271
- metrics_output = gr.JSON(label="Trading Metrics")
272
 
273
- with gr.TabItem("堂 Sentiment Analysis"):
274
  with gr.Row():
275
- sentiment_gauge = gr.Plot(label="Sentiment Score")
276
- news_display = gr.HTML(label="Market News")
 
 
277
 
278
- with gr.TabItem("嶋 Fundamentals"):
279
  with gr.Row():
280
- fundamentals_gauge = gr.Plot(label="Strength Index")
281
- fundamentals_table = gr.Dataframe(
282
- headers=["Metric", "Value"],
283
- label="Key Fundamentals",
284
- interactive=False
285
- )
 
 
286
 
287
  # Event handlers
288
- def update_all(interval):
289
- chart, metrics, pred = create_chart_analysis(interval)
290
- sentiment, news = analyze_sentiment()
291
- fund_gauge, fund_table = get_fundamentals()
292
 
293
  return chart, metrics, pred, sentiment, news, fund_gauge, fund_table
294
 
295
  refresh_btn.click(
296
  fn=update_all,
297
- inputs=interval_dropdown,
298
  outputs=[
299
  chart_plot, metrics_output, pred_plot,
300
  sentiment_gauge, news_display,
@@ -304,7 +301,7 @@ with gr.Blocks(
304
 
305
  demo.load(
306
  fn=update_all,
307
- inputs=interval_dropdown,
308
  outputs=[
309
  chart_plot, metrics_output, pred_plot,
310
  sentiment_gauge, news_display,
 
1
  import gradio as gr
2
  import pandas as pd
3
+ import numpy as np
4
+ import matplotlib.pyplot as plt
5
+ import mplfinance as mpf
6
  from data_processor import DataProcessor
7
  from sentiment_analyzer import SentimentAnalyzer
8
  from model_handler import ModelHandler
9
  from trading_logic import TradingLogic
10
+ import io
11
+ import base64
12
 
13
  # Global instances
14
  data_processor = DataProcessor()
 
16
  model_handler = ModelHandler()
17
  trading_logic = TradingLogic()
18
 
19
+ # Asset mapping
20
+ asset_map = {
21
+ "Gold Futures (GC=F)": "GC=F",
22
+ "Bitcoin USD (BTC-USD)": "BTC-USD"
23
+ }
24
+
25
+ def create_chart_analysis(interval, asset_name):
26
+ """Create chart with technical indicators using mplfinance"""
27
  try:
28
+ ticker = asset_map[asset_name]
29
+ df = data_processor.get_asset_data(ticker, interval)
30
  if df.empty:
31
  return "No data available", None, None
32
 
33
  # Calculate indicators
34
  df = data_processor.calculate_indicators(df)
35
 
36
+ # Create main candlestick chart with mplfinance
37
+ # Prepare additional plots for indicators
38
+ ap = []
39
+
40
+ # Add moving averages
41
+ ap.append(mpf.make_addplot(df['SMA_20'], color='#FFA500', width=1.5, label='SMA 20'))
42
+ ap.append(mpf.make_addplot(df['SMA_50'], color='#FF4500', width=1.5, label='SMA 50'))
 
 
 
 
43
 
44
  # Add Bollinger Bands
45
+ ap.append(mpf.make_addplot(df['BB_upper'], color='#4169E1', width=1, linestyle='dashed', label='BB Upper'))
46
+ ap.append(mpf.make_addplot(df['BB_lower'], color='#4169E1', width=1, linestyle='dashed', label='BB Lower'))
 
 
 
 
 
 
 
 
 
47
 
48
+ # Create figure
49
+ fig, axes = mpf.plot(
50
+ df[-100:], # Show last 100 candles
51
+ type='candle',
52
+ style='yahoo',
53
+ title=f'{asset_name} - {interval}',
54
+ ylabel='Price (USD)',
55
+ volume=True,
56
+ addplot=ap,
57
+ figsize=(12, 8),
58
+ returnfig=True,
59
+ warn_too_much_data=200
 
 
 
 
 
 
 
 
 
 
 
60
  )
61
 
62
+ # Adjust layout
63
+ fig.suptitle(f'{asset_name} Price Chart', fontsize=16, color='black')
64
+ fig.patch.set_facecolor('white')
65
+ axes[0].set_facecolor('white')
66
+ axes[0].grid(True, alpha=0.3)
67
+
68
+ # Prepare data for Chronos
69
  prepared_data = data_processor.prepare_for_chronos(df)
70
+
71
  # Generate predictions
72
  predictions = model_handler.predict(prepared_data, horizon=10)
 
73
  current_price = df['Close'].iloc[-1]
74
 
75
  # Get signal
 
84
 
85
  # Create metrics display
86
  metrics = {
87
+ "Current Price": f"${current_price:,.2f}",
88
  "Signal": signal.upper(),
89
  "Confidence": f"{confidence:.1%}",
90
+ "Take Profit": f"${tp:,.2f}" if tp else "N/A",
91
+ "Stop Loss": f"${sl:,.2f}" if sl else "N/A",
92
  "RSI": f"{df['RSI'].iloc[-1]:.1f}",
93
  "MACD": f"{df['MACD'].iloc[-1]:.4f}",
94
  "Volume": f"{df['Volume'].iloc[-1]:,.0f}"
95
  }
96
 
97
+ # Create prediction chart using matplotlib
98
+ pred_fig, ax = plt.subplots(figsize=(10, 4), facecolor='white')
99
+ pred_fig.patch.set_facecolor('white')
100
+
101
+ # Plot historical prices (last 30 points)
102
+ hist_data = df['Close'].iloc[-30:]
103
+ hist_dates = df.index[-30:]
104
+ ax.plot(hist_dates, hist_data, color='#4169E1', linewidth=2, label='Historical')
105
 
106
+ # Plot predictions
107
+ if predictions.any() and len(predictions) > 0:
108
  future_dates = pd.date_range(
109
  start=df.index[-1], periods=len(predictions), freq='D'
110
  )
111
+ ax.plot(future_dates, predictions, color='#FF6600', linewidth=2,
112
+ marker='o', markersize=4, label='Predictions')
113
 
114
+ # Connect historical to prediction
115
+ ax.plot([hist_dates[-1], future_dates[0]],
116
+ [hist_data.iloc[-1], predictions[0]],
117
+ color='#FF6600', linewidth=1, linestyle='--')
118
+
119
+ ax.set_title('Price Prediction (Next 10 Periods)', fontsize=12, color='black')
120
+ ax.set_xlabel('Date', color='black')
121
+ ax.set_ylabel('Price (USD)', color='black')
122
+ ax.legend()
123
+ ax.grid(True, alpha=0.3)
124
+ ax.tick_params(colors='black')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
125
 
126
  return fig, metrics, pred_fig
127
 
128
  except Exception as e:
129
  return str(e), None, None
130
 
131
+ def analyze_sentiment(asset_name):
132
+ """Analyze market sentiment for selected asset"""
133
  try:
134
+ sentiment_score, news_summary = sentiment_analyzer.analyze_sentiment(asset_name)
135
+
136
+ # Create sentiment gauge using matplotlib
137
+ fig, ax = plt.subplots(figsize=(6, 4), facecolor='white')
138
+ fig.patch.set_facecolor('white')
139
+
140
+ # Create gauge
141
+ ax.set_xlim(-1.5, 1.5)
142
+ ax.set_ylim(0, 1)
143
+ ax.set_aspect('equal')
144
+
145
+ # Draw gauge background
146
+ theta = np.linspace(np.pi, 0, 100)
147
+ ax.plot(np.cos(theta), np.sin(theta), color='lightgray', linewidth=10)
148
+
149
+ # Draw colored regions
150
+ ax.fill_between(np.cos(theta[50:]), np.sin(theta[50:]), 0,
151
+ where=np.cos(theta[50:])<0, color='red', alpha=0.3)
152
+ ax.fill_between(np.cos(theta[25:75]), np.sin(theta[25:75]), 0,
153
+ color='gray', alpha=0.3)
154
+ ax.fill_between(np.cos(theta[:50]), np.sin(theta[:50]), 0,
155
+ where=np.cos(theta[:50])>0, color='green', alpha=0.3)
156
+
157
+ # Draw needle
158
+ needle_angle = np.pi * (1 - (sentiment_score + 1) / 2)
159
+ ax.plot([0, 0.8*np.cos(needle_angle)], [0, 0.8*np.sin(needle_angle)],
160
+ color='gold', linewidth=4)
161
+
162
+ # Add score text
163
+ ax.text(0, -0.2, f"{sentiment_score:.2f}", ha='center', va='center',
164
+ fontsize=16, color='black', weight='bold')
165
+ ax.set_title(f'{asset_name} Market Sentiment', color='black')
166
+
167
+ # Remove axes
168
+ ax.axis('off')
169
 
170
  return fig, news_summary
171
 
172
  except Exception as e:
173
  return str(e), None
174
 
175
+ def get_fundamentals(asset_name):
176
  """Get fundamental analysis data"""
177
  try:
178
+ ticker = asset_map[asset_name]
179
+ fundamentals = data_processor.get_fundamental_data(ticker)
180
 
181
  # Create fundamentals table
182
  table_data = []
 
186
  df = pd.DataFrame(table_data, columns=['Metric', 'Value'])
187
 
188
  # Create fundamentals gauge chart
189
+ fig, ax = plt.subplots(figsize=(6, 4), facecolor='white')
190
+ fig.patch.set_facecolor('white')
191
+
192
+ strength_index = fundamentals.get('Strength Index', 50)
193
+
194
+ # Create horizontal bar gauge
195
+ ax.barh([0], [strength_index], height=0.3, color='gold', alpha=0.7)
196
+ ax.set_xlim(0, 100)
197
+ ax.set_ylim(-0.5, 0.5)
198
+ ax.set_title(f'{asset_name} Strength Index', color='black')
199
+ ax.set_xlabel('Index Value', color='black')
200
+ ax.text(strength_index, 0, f'{strength_index:.1f}',
201
+ ha='left', va='center', fontsize=12, color='black', weight='bold')
202
+ ax.grid(True, alpha=0.3)
203
+ ax.tick_params(colors='black')
 
 
 
 
 
 
 
204
 
205
  return fig, df
206
 
 
209
 
210
  # Create Gradio interface
211
  with gr.Blocks(
212
+ theme=gr.themes.Default(primary_hue="blue", secondary_hue="blue"),
213
+ title="Trading Analysis & Prediction",
214
  css="""
215
+ .gradio-container {background-color: #FFFFFF; color: #000000}
216
+ .gr-button-primary {background-color: #4169E1 !important; color: #FFFFFF !important}
217
+ .gr-button-secondary {border-color: #4169E1 !important; color: #4169E1 !important}
218
+ .gr-tab button {color: #000000 !important}
219
+ .gr-tab button.selected {background-color: #4169E1 !important; color: #FFFFFF !important}
220
+ .gr-highlighted {background-color: #F0F0F0 !important}
221
+ .anycoder-link {color: #4169E1 !important; text-decoration: none; font-weight: bold}
222
+ .gr-json {background-color: #FFFFFF !important; color: #000000 !important}
223
  """
224
  ) as demo:
225
 
226
  # Header with anycoder link
227
  gr.HTML("""
228
  <div style="text-align: center; padding: 20px;">
229
+ <h1 style="color: #4169E1;">Trading Analysis & Prediction</h1>
230
+ <p>Advanced AI-powered analysis for Gold and Bitcoin</p>
231
  <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="anycoder-link">Built with anycoder</a>
232
  </div>
233
  """)
234
 
235
  with gr.Row():
236
+ with gr.Column(scale=1):
237
+ asset_dropdown = gr.Dropdown(
238
+ choices=list(asset_map.keys()),
239
+ value="Gold Futures (GC=F)",
240
+ label="Select Asset",
241
+ info="Choose trading pair"
242
+ )
243
+ with gr.Column(scale=1):
244
+ interval_dropdown = gr.Dropdown(
245
+ choices=[
246
+ "5m", "15m", "30m", "1h", "4h", "1d", "1wk", "1mo", "3mo"
247
+ ],
248
+ value="1d",
249
+ label="Time Interval",
250
+ info="Select analysis timeframe"
251
+ )
252
+ with gr.Column(scale=1):
253
+ refresh_btn = gr.Button("Refresh Data", variant="primary")
254
 
255
  with gr.Tabs():
256
+ with gr.TabItem("Chart Analysis"):
257
  with gr.Row():
258
+ with gr.Column(scale=2):
259
+ chart_plot = gr.Plot(label="Price Chart")
260
+ with gr.Column(scale=1):
261
+ metrics_output = gr.JSON(label="Trading Metrics")
262
 
263
  with gr.Row():
264
+ pred_plot = gr.Plot(label="Price Predictions")
265
 
266
+ with gr.TabItem("Sentiment Analysis"):
267
  with gr.Row():
268
+ with gr.Column(scale=1):
269
+ sentiment_gauge = gr.Plot(label="Sentiment Score")
270
+ with gr.Column(scale=1):
271
+ news_display = gr.HTML(label="Market News")
272
 
273
+ with gr.TabItem("Fundamentals"):
274
  with gr.Row():
275
+ with gr.Column(scale=1):
276
+ fundamentals_gauge = gr.Plot(label="Strength Index")
277
+ with gr.Column(scale=1):
278
+ fundamentals_table = gr.Dataframe(
279
+ headers=["Metric", "Value"],
280
+ label="Key Fundamentals",
281
+ interactive=False
282
+ )
283
 
284
  # Event handlers
285
+ def update_all(interval, asset):
286
+ chart, metrics, pred = create_chart_analysis(interval, asset)
287
+ sentiment, news = analyze_sentiment(asset)
288
+ fund_gauge, fund_table = get_fundamentals(asset)
289
 
290
  return chart, metrics, pred, sentiment, news, fund_gauge, fund_table
291
 
292
  refresh_btn.click(
293
  fn=update_all,
294
+ inputs=[interval_dropdown, asset_dropdown],
295
  outputs=[
296
  chart_plot, metrics_output, pred_plot,
297
  sentiment_gauge, news_display,
 
301
 
302
  demo.load(
303
  fn=update_all,
304
+ inputs=[interval_dropdown, asset_dropdown],
305
  outputs=[
306
  chart_plot, metrics_output, pred_plot,
307
  sentiment_gauge, news_display,
data_processor.py CHANGED
@@ -5,11 +5,10 @@ from datetime import datetime, timedelta
5
 
6
  class DataProcessor:
7
  def __init__(self):
8
- self.ticker = "GC=F"
9
  self.fundamentals_cache = {}
10
 
11
- def get_gold_data(self, interval="1d", period="max"):
12
- """Fetch gold futures data from Yahoo Finance"""
13
  try:
14
  # Map internal intervals to yfinance format
15
  interval_map = {
@@ -36,8 +35,8 @@ class DataProcessor:
36
  else:
37
  period = "max"
38
 
39
- ticker = yf.Ticker(self.ticker)
40
- df = ticker.history(interval=yf_interval, period=period)
41
 
42
  if df.empty:
43
  raise ValueError("No data retrieved from Yahoo Finance")
@@ -96,24 +95,37 @@ class DataProcessor:
96
 
97
  return df
98
 
99
- def get_fundamental_data(self):
100
- """Get fundamental gold market data"""
101
  try:
102
- ticker = yf.Ticker(self.ticker)
103
- info = ticker.info
104
 
105
- # Mock some gold-specific fundamentals as yfinance may not have all
106
- fundamentals = {
107
- "Gold Strength Index": round(np.random.uniform(30, 80), 1),
108
- "Dollar Index": round(np.random.uniform(90, 110), 1),
109
- "Real Interest Rate": f"{np.random.uniform(-2, 5):.2f}%",
110
- "Gold Volatility": f"{np.random.uniform(10, 40):.1f}%",
111
- "Commercial Hedgers (Net)": f"{np.random.uniform(-50000, 50000):,.0f}",
112
- "Managed Money (Net)": f"{np.random.uniform(-100000, 100000):,.0f}",
113
- "Market Sentiment": np.random.choice(["Bullish", "Neutral", "Bearish"]),
114
- "Central Bank Demand": np.random.choice(["High", "Medium", "Low"]),
115
- "Jewelry Demand Trend": np.random.choice(["Increasing", "Stable", "Decreasing"])
116
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
117
 
118
  return fundamentals
119
 
 
5
 
6
  class DataProcessor:
7
  def __init__(self):
 
8
  self.fundamentals_cache = {}
9
 
10
+ def get_asset_data(self, ticker="GC=F", interval="1d", period="max"):
11
+ """Fetch asset data from Yahoo Finance"""
12
  try:
13
  # Map internal intervals to yfinance format
14
  interval_map = {
 
35
  else:
36
  period = "max"
37
 
38
+ ticker_obj = yf.Ticker(ticker)
39
+ df = ticker_obj.history(interval=yf_interval, period=period)
40
 
41
  if df.empty:
42
  raise ValueError("No data retrieved from Yahoo Finance")
 
95
 
96
  return df
97
 
98
+ def get_fundamental_data(self, ticker="GC=F"):
99
+ """Get fundamental market data"""
100
  try:
101
+ ticker_obj = yf.Ticker(ticker)
102
+ info = ticker_obj.info
103
 
104
+ # Asset-specific fundamentals
105
+ if ticker == "BTC-USD":
106
+ fundamentals = {
107
+ "Strength Index": round(np.random.uniform(30, 80), 1),
108
+ "Market Cap": f"${info.get('marketCap', 0):,.0f}" if info.get('marketCap') else "N/A",
109
+ "24h Volume": f"${np.random.uniform(20, 80):.1f}B",
110
+ "Volatility": f"{np.random.uniform(40, 120):.1f}%",
111
+ "Network Hash Rate": f"{np.random.uniform(300, 600):.0f} EH/s",
112
+ "Active Addresses": f"{np.random.uniform(500000, 1000000):,.0f}",
113
+ "Market Sentiment": np.random.choice(["Bullish", "Neutral", "Bearish"]),
114
+ "Institutional Adoption": np.random.choice(["High", "Medium", "Low"]),
115
+ "Mining Difficulty Trend": np.random.choice(["Increasing", "Stable", "Decreasing"])
116
+ }
117
+ else: # Gold
118
+ fundamentals = {
119
+ "Strength Index": round(np.random.uniform(30, 80), 1),
120
+ "Dollar Index": round(np.random.uniform(90, 110), 1),
121
+ "Real Interest Rate": f"{np.random.uniform(-2, 5):.2f}%",
122
+ "Gold Volatility": f"{np.random.uniform(10, 40):.1f}%",
123
+ "Commercial Hedgers (Net)": f"{np.random.uniform(-50000, 50000):,.0f}",
124
+ "Managed Money (Net)": f"{np.random.uniform(-100000, 100000):,.0f}",
125
+ "Market Sentiment": np.random.choice(["Bullish", "Neutral", "Bearish"]),
126
+ "Central Bank Demand": np.random.choice(["High", "Medium", "Low"]),
127
+ "Jewelry Demand Trend": np.random.choice(["Increasing", "Stable", "Decreasing"])
128
+ }
129
 
130
  return fundamentals
131
 
model_handler.py CHANGED
@@ -1,6 +1,5 @@
1
  import numpy as np
2
  import torch
3
- # PENTING: Class ini adalah satu-satunya cara yang benar untuk memuat Chronos-2
4
  from chronos import BaseChronosPipeline
5
 
6
  class ModelHandler:
@@ -15,7 +14,6 @@ class ModelHandler:
15
  try:
16
  print(f"Loading {self.model_name} on {self.device}...")
17
 
18
- # Pemuatan otomatis oleh pipeline (sudah terbukti berhasil di langkah sebelumnya)
19
  self.pipeline = BaseChronosPipeline.from_pretrained(
20
  self.model_name,
21
  device_map=self.device,
@@ -34,7 +32,7 @@ class ModelHandler:
34
  return np.array([0] * horizon)
35
 
36
  if self.pipeline is None:
37
- # --- Fallback Logic ---
38
  values = data['original']
39
  recent_trend = np.polyfit(range(len(values[-20:])), values[-20:], 1)[0]
40
 
@@ -48,11 +46,10 @@ class ModelHandler:
48
 
49
  return np.array(predictions)
50
 
51
- # --- Chronos-2 Inference ---
52
  predictions_samples = self.pipeline.predict(
53
  data['original'],
54
  prediction_length=horizon,
55
- # KOREKSI: Mengganti 'num_samples' menjadi 'n_samples'
56
  n_samples=20
57
  )
58
 
 
1
  import numpy as np
2
  import torch
 
3
  from chronos import BaseChronosPipeline
4
 
5
  class ModelHandler:
 
14
  try:
15
  print(f"Loading {self.model_name} on {self.device}...")
16
 
 
17
  self.pipeline = BaseChronosPipeline.from_pretrained(
18
  self.model_name,
19
  device_map=self.device,
 
32
  return np.array([0] * horizon)
33
 
34
  if self.pipeline is None:
35
+ # Fallback Logic
36
  values = data['original']
37
  recent_trend = np.polyfit(range(len(values[-20:])), values[-20:], 1)[0]
38
 
 
46
 
47
  return np.array(predictions)
48
 
49
+ # Chronos-2 Inference
50
  predictions_samples = self.pipeline.predict(
51
  data['original'],
52
  prediction_length=horizon,
 
53
  n_samples=20
54
  )
55
 
requirements.txt CHANGED
@@ -9,4 +9,6 @@ scipy
9
  scikit-learn
10
  safetensors
11
  huggingface-hub
12
- chronos-forecasting
 
 
 
9
  scikit-learn
10
  safetensors
11
  huggingface-hub
12
+ chronos-forecasting
13
+ mplfinance
14
+ matplotlib
sentiment_analyzer.py CHANGED
@@ -3,7 +3,7 @@ from datetime import datetime
3
 
4
  class SentimentAnalyzer:
5
  def __init__(self):
6
- self.sentiment_sources = [
7
  "Federal Reserve hints at rate pause - positive for gold",
8
  "Inflation data higher than expected - gold demand rising",
9
  "Dollar strength weighs on precious metals",
@@ -13,12 +13,25 @@ class SentimentAnalyzer:
13
  "Technical breakout above resistance level",
14
  "Profit-taking observed after recent rally"
15
  ]
 
 
 
 
 
 
 
 
 
 
16
 
17
- def analyze_gold_sentiment(self):
18
- """Analyze sentiment for gold market"""
19
  try:
20
- # Simulate sentiment analysis
21
- # In production, would use actual news API and NLP model
 
 
 
22
 
23
  # Generate random sentiment around current market conditions
24
  base_sentiment = random.uniform(-0.5, 0.5)
@@ -35,16 +48,16 @@ class SentimentAnalyzer:
35
 
36
  # Generate news summary
37
  num_news = random.randint(3, 6)
38
- selected_news = random.sample(self.sentiment_sources, num_news)
39
 
40
- news_html = "<div style='max-height: 300px; overflow-y: auto;'>"
41
- news_html += "<h4 style='color: #FFD700;'>Latest Gold News</h4>"
42
 
43
  for i, news in enumerate(selected_news, 1):
44
- sentiment_label = "🟢" if "positive" in news or "rising" in news or "support" in news else \
45
  "🔴" if "weighs" in news or "outflows" in news or "Profit-taking" in news else \
46
  "🟡"
47
- news_html += f"<p style='margin: 10px 0; padding: 10px; background: rgba(255,255,255,0.05); border-radius: 5px;'>{sentiment_label} {news}</p>"
48
 
49
  news_html += "</div>"
50
 
 
3
 
4
  class SentimentAnalyzer:
5
  def __init__(self):
6
+ self.gold_sources = [
7
  "Federal Reserve hints at rate pause - positive for gold",
8
  "Inflation data higher than expected - gold demand rising",
9
  "Dollar strength weighs on precious metals",
 
13
  "Technical breakout above resistance level",
14
  "Profit-taking observed after recent rally"
15
  ]
16
+ self.bitcoin_sources = [
17
+ "Institutional adoption of Bitcoin accelerates",
18
+ "Regulatory clarity improves - positive for crypto",
19
+ "Bitcoin halving event supports price",
20
+ "Macro uncertainty drives Bitcoin demand",
21
+ "Spot ETF inflows reach record highs",
22
+ "Network hash rate reaches new ATH",
23
+ "Whale accumulation detected on-chain",
24
+ "DeFi TVL growth supports crypto market"
25
+ ]
26
 
27
+ def analyze_sentiment(self, asset_name):
28
+ """Analyze sentiment for selected asset"""
29
  try:
30
+ # Select appropriate news sources
31
+ if "Bitcoin" in asset_name:
32
+ sources = self.bitcoin_sources
33
+ else:
34
+ sources = self.gold_sources
35
 
36
  # Generate random sentiment around current market conditions
37
  base_sentiment = random.uniform(-0.5, 0.5)
 
48
 
49
  # Generate news summary
50
  num_news = random.randint(3, 6)
51
+ selected_news = random.sample(sources, num_news)
52
 
53
+ news_html = f"<div style='max-height: 300px; overflow-y: auto;'>"
54
+ news_html += f"<h4 style='color: #4169E1;'>{asset_name} Market News</h4>"
55
 
56
  for i, news in enumerate(selected_news, 1):
57
+ sentiment_label = "🟢" if "positive" in news or "rising" in news or "support" in news or "accelerates" in news or " ATH" in news else \
58
  "🔴" if "weighs" in news or "outflows" in news or "Profit-taking" in news else \
59
  "🟡"
60
+ news_html += f"<p style='margin: 10px 0; padding: 10px; background: rgba(65,105,225,0.05); border-radius: 5px;'>{sentiment_label} {news}</p>"
61
 
62
  news_html += "</div>"
63