omniverse1 commited on
Commit
4c78965
·
verified ·
1 Parent(s): 2c99719

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +118 -132
app.py CHANGED
@@ -1,11 +1,13 @@
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,86 +15,46 @@ 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
 
 
 
 
 
 
 
85
  signal, confidence = trading_logic.generate_signal(
86
  predictions, current_price, df
87
  )
88
 
89
- # Calculate TP/SL
90
  tp, sl = trading_logic.calculate_tp_sl(
91
  current_price, df['ATR'].iloc[-1], signal
92
  )
93
 
94
  # Create metrics display
95
  metrics = {
 
96
  "Current Price": f"${current_price:.2f}",
97
  "Signal": signal.upper(),
98
  "Confidence": f"{confidence:.1%}",
@@ -103,11 +65,11 @@ def create_chart_analysis(interval):
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
  )
@@ -115,21 +77,22 @@ def create_chart_analysis(interval):
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',
@@ -139,76 +102,84 @@ def create_chart_analysis(interval):
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 = []
195
  for key, value in fundamentals.items():
196
  table_data.append([key, value])
197
 
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
  ))
@@ -229,7 +200,7 @@ def get_fundamentals():
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}
@@ -238,34 +209,47 @@ with gr.Blocks(
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")
@@ -277,7 +261,7 @@ with gr.Blocks(
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",
@@ -285,28 +269,30 @@ with gr.Blocks(
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,
301
  fundamentals_gauge, fundamentals_table
302
  ]
303
  )
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,
311
  fundamentals_gauge, fundamentals_table
312
  ]
 
1
  import gradio as gr
2
  import pandas as pd
3
+ import numpy as np
4
+ # Hapus import plotly.graph_objects
5
  from data_processor import DataProcessor
6
  from sentiment_analyzer import SentimentAnalyzer
7
  from model_handler import ModelHandler
8
  from trading_logic import TradingLogic
9
+ from plotter import create_mplfinance_chart # Impor fungsi plotting baru
10
+ import plotly.graph_objects as go # Tetap dipakai untuk Gauge Charts
11
 
12
  # Global instances
13
  data_processor = DataProcessor()
 
15
  model_handler = ModelHandler()
16
  trading_logic = TradingLogic()
17
 
18
+ # Fungsi utama yang menerima ticker dan interval
19
+ def create_chart_analysis(ticker, interval):
20
+ """Create chart with technical indicators and predictions"""
21
  try:
22
+ # Panggil fungsi data yang sudah diperbarui
23
+ df = data_processor.get_market_data(ticker, interval)
24
  if df.empty:
25
  return "No data available", None, None
26
 
27
+ # Hitung indikator
28
  df = data_processor.calculate_indicators(df)
29
 
30
+ # Prepare data for Chronos
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  prepared_data = data_processor.prepare_for_chronos(df)
32
 
33
+ # Generate predictions (Chronos-2 atau Fallback)
34
  predictions = model_handler.predict(prepared_data, horizon=10)
35
 
36
  current_price = df['Close'].iloc[-1]
37
 
38
+ # Buat chart menggunakan MPLFINANCE (dikembalikan sebagai HTML)
39
+ chart_html = create_mplfinance_chart(
40
+ df,
41
+ ticker=f'{ticker} ({interval})',
42
+ predictions=predictions
43
+ )
44
+
45
+ # Hasilkan sinyal trading
46
  signal, confidence = trading_logic.generate_signal(
47
  predictions, current_price, df
48
  )
49
 
50
+ # Hitung TP/SL
51
  tp, sl = trading_logic.calculate_tp_sl(
52
  current_price, df['ATR'].iloc[-1], signal
53
  )
54
 
55
  # Create metrics display
56
  metrics = {
57
+ "Ticker": ticker,
58
  "Current Price": f"${current_price:.2f}",
59
  "Signal": signal.upper(),
60
  "Confidence": f"{confidence:.1%}",
 
65
  "Volume": f"{df['Volume'].iloc[-1]:,.0f}"
66
  }
67
 
68
+ # Buat prediction chart sederhana (Plotly)
69
  pred_fig = go.Figure()
70
 
 
71
  if predictions.any():
72
+ # Gunakan index datetime asli dari data_processor
73
  future_dates = pd.date_range(
74
  start=df.index[-1], periods=len(predictions), freq='D'
75
  )
 
77
  pred_fig.add_trace(go.Scatter(
78
  x=future_dates, y=predictions,
79
  mode='lines+markers',
80
+ line=dict(color='blue', width=3),
81
  marker=dict(size=6),
82
  name='Predictions'
83
  ))
84
 
85
+ # Garis putus-putus dari harga terakhir ke prediksi pertama
86
  pred_fig.add_trace(go.Scatter(
87
  x=[df.index[-1], future_dates[0]],
88
  y=[current_price, predictions[0]],
89
  mode='lines',
90
+ line=dict(color='rgba(0,0,255,0.5)', width=2, dash='dash'),
91
  showlegend=False
92
  ))
93
 
94
  pred_fig.update_layout(
95
+ title=f'{ticker} Price Prediction (Next 10 Periods)',
96
  yaxis_title='Price (USD)',
97
  xaxis_title='Date',
98
  template='plotly_dark',
 
102
  font=dict(color='white')
103
  )
104
 
105
+ return chart_html, metrics, pred_fig
106
 
107
  except Exception as e:
108
+ return f"Error creating chart: {str(e)}", None, None
109
 
110
+ def analyze_sentiment(ticker):
111
+ """Analyze gold/crypto market sentiment"""
112
+ # NOTE: Menggunakan sentiment_analyzer.py lama yang mock, tetapi sekarang berdasarkan ticker
113
+ sentiment_score, news_summary = sentiment_analyzer.analyze_gold_sentiment() # Fungsi ini masih mock, tidak menerima ticker
114
+
115
+ # ... (Logika Gauge Chart, tetap sama)
116
+ fig = go.Figure(go.Indicator(
117
+ mode="gauge+number+delta",
118
+ value=sentiment_score,
119
+ domain={'x': [0, 1], 'y': [0, 1]},
120
+ title={'text': f"{ticker} Market Sentiment (Mocked)"},
121
+ delta={'reference': 0},
122
+ gauge={
123
+ 'axis': {'range': [-1, 1]},
124
+ 'bar': {'color': "#FFD700"},
125
+ 'steps': [
126
+ {'range': [-1, -0.5], 'color': "rgba(255,0,0,0.5)"},
127
+ {'range': [-0.5, 0.5], 'color': "rgba(255,255,255,0.3)"},
128
+ {'range': [0.5, 1], 'color': "rgba(0,255,0,0.5)"}
129
+ ],
130
+ 'threshold': {
131
+ 'line': {'color': "white", 'width': 4},
132
+ 'thickness': 0.75,
133
+ 'value': 0
 
134
  }
135
+ }
136
+ ))
137
+
138
+ fig.update_layout(
139
+ template='plotly_dark',
140
+ height=300,
141
+ paper_bgcolor='rgba(0,0,0,0)',
142
+ plot_bgcolor='rgba(0,0,0,0)',
143
+ font=dict(color='white')
144
+ )
145
+
146
+ return fig, news_summary
 
 
147
 
148
+ def get_fundamentals(ticker):
149
  """Get fundamental analysis data"""
150
  try:
151
+ # Panggil fungsi fundamental data yang sudah diperbarui
152
+ fundamentals = data_processor.get_fundamental_data(ticker)
153
 
154
+ # Buat fundamentals table
155
  table_data = []
156
  for key, value in fundamentals.items():
157
  table_data.append([key, value])
158
 
159
  df = pd.DataFrame(table_data, columns=['Metric', 'Value'])
160
 
161
+ # Ambil nilai kunci untuk gauge
162
+ if ticker == "BTC-USD":
163
+ gauge_title = "Crypto Volatility Index"
164
+ gauge_value = fundamentals.get(gauge_title, 100)
165
+ gauge_range = [0, 200]
166
+ else:
167
+ gauge_title = "Gold Strength Index"
168
+ gauge_value = fundamentals.get(gauge_title, 50)
169
+ gauge_range = [0, 100]
170
+
171
  # Create fundamentals gauge chart
172
  fig = go.Figure(go.Indicator(
173
  mode="gauge+number",
174
+ value=gauge_value,
175
+ title={'text': gauge_title},
176
  gauge={
177
+ 'axis': {'range': gauge_range},
178
  'bar': {'color': "#FFD700"},
179
  'steps': [
180
+ {'range': [gauge_range[0], gauge_range[1] * 0.3], 'color': "rgba(255,0,0,0.5)"},
181
+ {'range': [gauge_range[1] * 0.3, gauge_range[1] * 0.7], 'color': "rgba(255,255,255,0.3)"},
182
+ {'range': [gauge_range[1] * 0.7, gauge_range[1]], 'color': "rgba(0,255,0,0.5)"}
183
  ]
184
  }
185
  ))
 
200
  # Create Gradio interface
201
  with gr.Blocks(
202
  theme=gr.themes.Default(primary_hue="yellow", secondary_hue="yellow"),
203
+ title="Ultimate Market Analysis & Prediction",
204
  css="""
205
  .gradio-container {background-color: #000000; color: #FFFFFF}
206
  .gr-button-primary {background-color: #FFD700 !important; color: #000000 !important}
 
209
  .gr-tab button.selected {background-color: #FFD700 !important; color: #000000 !important}
210
  .gr-highlighted {background-color: #1a1a1a !important}
211
  .anycoder-link {color: #FFD700 !important; text-decoration: none; font-weight: bold}
212
+ /* Custom CSS to handle the mplfinance image block (since it returns HTML) */
213
+ .mpl-chart-container {
214
+ border: 1px solid #333333;
215
+ border-radius: 5px;
216
+ overflow: hidden;
217
+ background: white; /* Ensure mplfinance chart background is visible */
218
+ }
219
  """
220
  ) as demo:
221
 
 
222
  gr.HTML("""
223
  <div style="text-align: center; padding: 20px;">
224
+ <h1 style="color: #FFD700;">Ultimate Market Analysis & Prediction (Chronos-2)</h1>
225
+ <p>AI-powered analysis for Gold Futures (GC=F) and Bitcoin (BTC-USD)</p>
226
  <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="anycoder-link">Built with anycoder</a>
227
  </div>
228
  """)
229
 
230
  with gr.Row():
231
+ ticker_dropdown = gr.Dropdown(
232
+ choices=["GC=F", "BTC-USD"],
233
+ value="GC=F",
234
+ label="Market Ticker",
235
+ info="Select asset for analysis"
236
+ )
237
  interval_dropdown = gr.Dropdown(
238
  choices=[
239
+ "1d", "1wk", "1mo", "3mo"
240
  ],
241
  value="1d",
242
  label="Time Interval",
243
  info="Select analysis timeframe"
244
  )
245
+ refresh_btn = gr.Button("売 Refresh Data & Predict", variant="primary")
246
 
247
  with gr.Tabs():
248
  with gr.TabItem("投 Chart Analysis"):
249
  with gr.Row():
250
+ # Ganti gr.Plot dengan gr.HTML untuk menampilkan chart mplfinance
251
+ chart_html = gr.HTML(label="Price Chart & Indicators", elem_classes=["mpl-chart-container"])
252
+ pred_plot = gr.Plot(label="Price Predictions (Next 10 Periods)")
253
 
254
  with gr.Row():
255
  metrics_output = gr.JSON(label="Trading Metrics")
 
261
 
262
  with gr.TabItem("嶋 Fundamentals"):
263
  with gr.Row():
264
+ fundamentals_gauge = gr.Plot(label="Strength Index Gauge")
265
  fundamentals_table = gr.Dataframe(
266
  headers=["Metric", "Value"],
267
  label="Key Fundamentals",
 
269
  )
270
 
271
  # Event handlers
272
+ def update_all(ticker, interval):
273
+ chart, metrics, pred = create_chart_analysis(ticker, interval)
274
+ sentiment, news = analyze_sentiment(ticker)
275
+ fund_gauge, fund_table = get_fundamentals(ticker)
276
 
277
  return chart, metrics, pred, sentiment, news, fund_gauge, fund_table
278
 
279
+ # Tambahkan ticker_dropdown ke inputs
280
  refresh_btn.click(
281
  fn=update_all,
282
+ inputs=[ticker_dropdown, interval_dropdown],
283
  outputs=[
284
+ chart_html, metrics_output, pred_plot,
285
  sentiment_gauge, news_display,
286
  fundamentals_gauge, fundamentals_table
287
  ]
288
  )
289
 
290
+ # Tambahkan ticker_dropdown ke inputs
291
  demo.load(
292
  fn=update_all,
293
+ inputs=[ticker_dropdown, interval_dropdown],
294
  outputs=[
295
+ chart_html, metrics_output, pred_plot,
296
  sentiment_gauge, news_display,
297
  fundamentals_gauge, fundamentals_table
298
  ]