OmidSakaki commited on
Commit
82d636d
·
verified ·
1 Parent(s): 075b2cc

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +296 -89
app.py CHANGED
@@ -13,8 +13,9 @@ import sys
13
  import os
14
  import threading
15
  from datetime import datetime, timedelta
 
16
 
17
- # Set matplotlib backend - FIXED TYPO
18
  plt.switch_backend('Agg')
19
 
20
  # Create directories and init files
@@ -49,6 +50,8 @@ class RealTimeTradingDemo:
49
  self.action_history = []
50
  self.initialized = False
51
  self.start_time = None
 
 
52
 
53
  def initialize_environment(self, initial_balance, risk_level, asset_type):
54
  """Initialize trading environment"""
@@ -74,8 +77,9 @@ class RealTimeTradingDemo:
74
  self.live_trading = False
75
  self.initialized = True
76
  self.start_time = datetime.now()
 
77
 
78
- # Initialize live data
79
  self._initialize_live_data()
80
 
81
  return "✅ محیط معاملاتی Real-Time راه‌اندازی شد!\n\n🎯 آماده برای شروع آموزش هوش مصنوعی..."
@@ -86,16 +90,21 @@ class RealTimeTradingDemo:
86
  return error_msg
87
 
88
  def _initialize_live_data(self):
89
- """Initialize live trading data"""
90
- # Generate realistic initial data
91
  base_price = 100
92
- for i in range(50):
93
- price = base_price + np.random.normal(0, 2)
 
 
 
 
 
94
  self.live_data.append({
95
- 'timestamp': datetime.now() - timedelta(seconds=50-i),
96
- 'price': price,
97
  'action': 0,
98
- 'net_worth': self.env.initial_balance if self.env else 10000
 
99
  })
100
 
101
  def train_agent(self, num_episodes):
@@ -181,10 +190,10 @@ class RealTimeTradingDemo:
181
  def start_live_trading(self):
182
  """Start real-time live trading demo"""
183
  if not self.training_complete:
184
- return "❌ لطفا اول آموزش را کامل کنید!", None, None
185
 
186
  if self.live_trading:
187
- return "⚠️ معامله Real-Time در حال اجراست!", None, None
188
 
189
  self.live_trading = True
190
  self.live_data = []
@@ -197,12 +206,18 @@ class RealTimeTradingDemo:
197
  self.trading_thread.daemon = True
198
  self.trading_thread.start()
199
 
200
- return "🎯 معامله Real-Time شروع شد!", self._create_live_chart(), self._create_performance_chart()
 
 
 
 
 
 
201
 
202
  def _live_trading_loop(self):
203
  """Main live trading loop"""
204
  step_count = 0
205
- max_steps = 200 # Stop after 200 steps for demo
206
 
207
  while self.live_trading and step_count < max_steps:
208
  try:
@@ -213,26 +228,40 @@ class RealTimeTradingDemo:
213
  next_state, reward, done, info = self.env.step(action)
214
  self.current_state = next_state
215
 
216
- # Update live data
217
  current_time = datetime.now()
 
 
 
 
 
 
 
 
 
 
 
218
  self.live_data.append({
219
  'timestamp': current_time,
220
- 'price': info['current_price'],
221
  'action': action,
222
- 'net_worth': info['net_worth']
 
223
  })
224
 
225
- # Keep only last 100 data points
226
- if len(self.live_data) > 100:
227
  self.live_data.pop(0)
228
 
229
  self.action_history.append({
230
  'step': step_count,
231
  'action': action,
232
  'reward': reward,
233
- 'timestamp': current_time
 
234
  })
235
 
 
236
  step_count += 1
237
  time.sleep(1) # 1 second between steps
238
 
@@ -242,28 +271,50 @@ class RealTimeTradingDemo:
242
 
243
  self.live_trading = False
244
 
245
- def get_live_update(self):
246
- """Get real-time update for the interface"""
247
  if not self.live_trading:
248
- return "🛑 معامله Real-Time متوقف شده", None, None
 
 
 
 
 
249
 
250
  current_data = self.live_data[-1] if self.live_data else None
251
  if not current_data:
252
- return "📊 در حال آماده‌سازی داده...", None, None
 
 
 
 
 
253
 
254
  action_names = ["نگهداری", "خرید", "فروش", "بستن"]
255
  action = current_data['action']
256
  action_text = action_names[action]
257
 
 
 
 
 
 
 
258
  status = (
259
  f"🎯 معامله Real-Time در حال اجرا...\n"
260
  f"💰 قیمت فعلی: ${current_data['price']:.2f}\n"
261
- f"🎪 اقدام: {action_text}\n"
262
- f"💼 ارزش پرتفولیو: ${current_data['net_worth']:.2f}\n"
 
263
  f"⏰ آخرین بروزرسانی: {datetime.now().strftime('%H:%M:%S')}"
264
  )
265
 
266
- return status, self._create_live_chart(), self._create_performance_chart()
 
 
 
 
 
267
 
268
  def stop_live_trading(self):
269
  """Stop the live trading demo"""
@@ -273,21 +324,32 @@ class RealTimeTradingDemo:
273
 
274
  final_net_worth = self.live_data[-1]['net_worth'] if self.live_data else self.env.initial_balance
275
  initial_balance = self.env.initial_balance
 
 
 
 
 
 
 
 
 
 
 
276
 
277
  performance = (
278
  f"🛑 معامله Real-Time متوقف شد\n\n"
279
  f"📈 عملکرد نهایی:\n"
280
  f"• سرمایه اولیه: ${initial_balance:.2f}\n"
281
  f"• سرمایه نهایی: ${final_net_worth:.2f}\n"
282
- f"• سود/زیان: ${final_net_worth - initial_balance:.2f}\n"
283
- f"• درصد تغییر: {((final_net_worth - initial_balance) / initial_balance * 100):.2f}%\n"
284
- f"• تعداد اقدامات: {len(self.action_history)}"
285
  )
286
 
287
- return performance, self._create_live_chart(), self._create_performance_chart()
288
 
289
  def _create_live_chart(self):
290
- """Create real-time trading chart"""
291
  if not self.live_data:
292
  fig = go.Figure()
293
  fig.update_layout(
@@ -299,19 +361,26 @@ class RealTimeTradingDemo:
299
  times = [d['timestamp'] for d in self.live_data]
300
  prices = [d['price'] for d in self.live_data]
301
  actions = [d['action'] for d in self.live_data]
 
302
 
303
- fig = go.Figure()
 
 
 
 
 
304
 
305
- # Price line
306
  fig.add_trace(go.Scatter(
307
  x=times,
308
  y=prices,
309
  mode='lines',
310
  name='قیمت',
311
- line=dict(color='blue', width=3)
312
- ))
 
313
 
314
- # Action markers
315
  buy_times = [times[i] for i, action in enumerate(actions) if action == 1]
316
  buy_prices = [prices[i] for i, action in enumerate(actions) if action == 1]
317
 
@@ -327,8 +396,9 @@ class RealTimeTradingDemo:
327
  y=buy_prices,
328
  mode='markers',
329
  name='خرید',
330
- marker=dict(color='green', size=10, symbol='triangle-up')
331
- ))
 
332
 
333
  if sell_times:
334
  fig.add_trace(go.Scatter(
@@ -336,68 +406,159 @@ class RealTimeTradingDemo:
336
  y=sell_prices,
337
  mode='markers',
338
  name='فروش',
339
- marker=dict(color='red', size=10, symbol='triangle-down')
340
- ))
 
 
 
 
 
 
 
 
 
 
341
 
342
- if close_times:
 
 
343
  fig.add_trace(go.Scatter(
344
- x=close_times,
345
- y=close_prices,
346
- mode='markers',
347
- name='بستن',
348
- marker=dict(color='orange', size=8, symbol='x')
349
- ))
 
350
 
351
  fig.update_layout(
352
- title="🎯 نمودار معاملات Real-Time",
353
- xaxis_title="زمان",
354
- yaxis_title="قیمت",
355
- height=400,
356
  showlegend=True,
357
- template="plotly_white"
 
358
  )
359
 
 
 
 
 
360
  return fig
361
 
362
  def _create_performance_chart(self):
363
- """Create performance chart"""
364
  if not self.live_data:
365
  fig = go.Figure()
366
  fig.update_layout(
367
  title="📈 عملکرد پرتفولیو - در حال آماده‌سازی...",
368
- height=300
369
  )
370
  return fig
371
 
372
  times = [d['timestamp'] for d in self.live_data]
373
  net_worths = [d['net_worth'] for d in self.live_data]
 
374
 
375
- fig = go.Figure()
 
 
 
 
376
 
 
377
  fig.add_trace(go.Scatter(
378
  x=times,
379
  y=net_worths,
380
  mode='lines+markers',
381
  name='ارزش پرتفولیو',
382
- line=dict(color='green', width=3),
383
- marker=dict(size=4)
384
- ))
 
385
 
386
  # Add initial balance line
387
  if self.env:
388
  fig.add_hline(y=self.env.initial_balance, line_dash="dash",
389
- line_color="red", annotation_text="سرمایه اولیه")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
390
 
391
  fig.update_layout(
392
- title="💼 عملکرد پرتفولیو در زمان واقعی",
393
- xaxis_title="زمان",
394
- yaxis_title="ارزش ($)",
395
- height=300,
396
- template="plotly_white"
397
  )
398
 
 
 
 
399
  return fig
400
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
401
  def _create_training_progress(self, training_history):
402
  """Create training progress visualization"""
403
  if not training_history:
@@ -444,14 +605,14 @@ class RealTimeTradingDemo:
444
  # Initialize the demo
445
  demo = RealTimeTradingDemo()
446
 
447
- # Create Gradio interface
448
  def create_interface():
449
  with gr.Blocks(theme=gr.themes.Soft(), title="Real-Time Trading AI") as interface:
450
  gr.Markdown("""
451
  # 🚀 هوش مصنوعی معامله‌گر Real-Time
452
- **آموزش و اجرای بلادرنگ روی نمودارهای زنده**
453
 
454
- *این سیستم ابتدا هوش مصنوعی را آموزش می‌دهد، سپس به صورت Real-Time روی بازار معامله می‌کند*
455
  """)
456
 
457
  with gr.Row():
@@ -498,7 +659,7 @@ def create_interface():
498
  status_output = gr.Textbox(
499
  label="وضعیت عملیات",
500
  interactive=False,
501
- lines=4
502
  )
503
 
504
  with gr.Row():
@@ -523,7 +684,7 @@ def create_interface():
523
  )
524
 
525
  with gr.Row():
526
- gr.Markdown("## 🎯 فاز ۲: معامله Real-Time")
527
 
528
  with gr.Row():
529
  with gr.Column(scale=1):
@@ -538,25 +699,60 @@ def create_interface():
538
  variant="stop",
539
  size="lg"
540
  )
541
-
542
- with gr.Column(scale=1):
543
- update_btn = gr.Button(
544
- "🔄 بروزرسانی لحظه‌ای",
545
- variant="secondary",
546
- size="lg"
547
- )
548
 
549
  with gr.Row():
550
- with gr.Column(scale=1):
551
  live_chart = gr.Plot(
552
- label="📊 نمودار معاملات Real-Time"
553
  )
554
 
555
  with gr.Column(scale=1):
556
  performance_chart = gr.Plot(
557
- label="💼 عملکرد پرتفولیو"
558
  )
559
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
560
  # Event handlers
561
  init_btn.click(
562
  demo.initialize_environment,
@@ -573,28 +769,39 @@ def create_interface():
573
  start_btn.click(
574
  demo.start_live_trading,
575
  inputs=[],
576
- outputs=[status_output, live_chart, performance_chart]
 
 
577
  )
578
 
579
- update_btn.click(
580
- demo.get_live_update,
 
 
 
 
 
581
  inputs=[],
582
- outputs=[status_output, live_chart, performance_chart]
 
583
  )
584
 
585
  stop_btn.click(
586
  demo.stop_live_trading,
587
  inputs=[],
588
- outputs=[status_output, live_chart, performance_chart]
 
 
589
  )
590
 
591
  gr.Markdown("""
592
- ## 🧠 نحوه کار سیستم:
593
 
594
- 1. **راه‌اندازی محیط**: تنظیم پارامترهای اولیه
595
- 2. **آموزش هوش مصنوعی**: آموزش مدل با ۳۰ اپیزود
596
- 3. **معامله Real-Time**: اجرای بلادرنگ روی نمودار زنده
597
- 4. **مانیتورینگ**: مشاهده عملکرد لحظه‌ای
 
598
 
599
  *توسعه داده شده توسط Omid Sakaki - 2024*
600
  """)
 
13
  import os
14
  import threading
15
  from datetime import datetime, timedelta
16
+ import asyncio
17
 
18
+ # Set matplotlib backend
19
  plt.switch_backend('Agg')
20
 
21
  # Create directories and init files
 
50
  self.action_history = []
51
  self.initialized = False
52
  self.start_time = None
53
+ self.last_update = None
54
+ self.update_callbacks = []
55
 
56
  def initialize_environment(self, initial_balance, risk_level, asset_type):
57
  """Initialize trading environment"""
 
77
  self.live_trading = False
78
  self.initialized = True
79
  self.start_time = datetime.now()
80
+ self.last_update = datetime.now()
81
 
82
+ # Initialize live data with more realistic pattern
83
  self._initialize_live_data()
84
 
85
  return "✅ محیط معاملاتی Real-Time راه‌اندازی شد!\n\n🎯 آماده برای شروع آموزش هوش مصنوعی..."
 
90
  return error_msg
91
 
92
  def _initialize_live_data(self):
93
+ """Initialize live trading data with realistic patterns"""
 
94
  base_price = 100
95
+ # Create realistic price pattern with some volatility
96
+ for i in range(100):
97
+ # Simulate realistic market movements
98
+ trend = np.sin(i * 0.1) * 5 # Long-term trend
99
+ noise = np.random.normal(0, 1.5) # Market noise
100
+ price = base_price + trend + noise
101
+
102
  self.live_data.append({
103
+ 'timestamp': datetime.now() - timedelta(seconds=100-i),
104
+ 'price': max(50, price), # Prevent negative prices
105
  'action': 0,
106
+ 'net_worth': self.env.initial_balance if self.env else 10000,
107
+ 'volume': np.random.randint(1000, 10000)
108
  })
109
 
110
  def train_agent(self, num_episodes):
 
190
  def start_live_trading(self):
191
  """Start real-time live trading demo"""
192
  if not self.training_complete:
193
+ return "❌ لطفا اول آموزش را کامل کنید!", None, None, None
194
 
195
  if self.live_trading:
196
+ return "⚠️ معامله Real-Time در حال اجراست!", None, None, None
197
 
198
  self.live_trading = True
199
  self.live_data = []
 
206
  self.trading_thread.daemon = True
207
  self.trading_thread.start()
208
 
209
+ # Get initial status and charts
210
+ status = "🎯 معامله Real-Time شروع شد!\n\n📈 نمودارها هر 1 ثانیه آپدیت می‌شوند..."
211
+ live_chart = self._create_live_chart()
212
+ performance_chart = self._create_performance_chart()
213
+ stats_table = self._create_stats_table()
214
+
215
+ return status, live_chart, performance_chart, stats_table
216
 
217
  def _live_trading_loop(self):
218
  """Main live trading loop"""
219
  step_count = 0
220
+ max_steps = 500 # Run for longer demo
221
 
222
  while self.live_trading and step_count < max_steps:
223
  try:
 
228
  next_state, reward, done, info = self.env.step(action)
229
  self.current_state = next_state
230
 
231
+ # Update live data with realistic price movement
232
  current_time = datetime.now()
233
+ last_price = self.live_data[-1]['price'] if self.live_data else 100
234
+
235
+ # Simulate realistic price movement
236
+ price_change = np.random.normal(0, 0.5) # Small random walk
237
+ if action == 1: # Buy - slight upward pressure
238
+ price_change += 0.1
239
+ elif action == 2: # Sell - slight downward pressure
240
+ price_change -= 0.1
241
+
242
+ new_price = max(50, last_price + price_change) # Prevent negative prices
243
+
244
  self.live_data.append({
245
  'timestamp': current_time,
246
+ 'price': new_price,
247
  'action': action,
248
+ 'net_worth': info['net_worth'],
249
+ 'volume': np.random.randint(1000, 15000)
250
  })
251
 
252
+ # Keep only last 150 data points for performance
253
+ if len(self.live_data) > 150:
254
  self.live_data.pop(0)
255
 
256
  self.action_history.append({
257
  'step': step_count,
258
  'action': action,
259
  'reward': reward,
260
+ 'timestamp': current_time,
261
+ 'price': new_price
262
  })
263
 
264
+ self.last_update = current_time
265
  step_count += 1
266
  time.sleep(1) # 1 second between steps
267
 
 
271
 
272
  self.live_trading = False
273
 
274
+ def get_live_data(self):
275
+ """Get real-time data for auto-updating charts"""
276
  if not self.live_trading:
277
+ return {
278
+ "status": "🛑 معامله Real-Time متوقف شده",
279
+ "live_chart": self._create_live_chart(),
280
+ "performance_chart": self._create_performance_chart(),
281
+ "stats_table": self._create_stats_table()
282
+ }
283
 
284
  current_data = self.live_data[-1] if self.live_data else None
285
  if not current_data:
286
+ return {
287
+ "status": "📊 در حال آماده‌سازی داده...",
288
+ "live_chart": self._create_live_chart(),
289
+ "performance_chart": self._create_performance_chart(),
290
+ "stats_table": self._create_stats_table()
291
+ }
292
 
293
  action_names = ["نگهداری", "خرید", "فروش", "بستن"]
294
  action = current_data['action']
295
  action_text = action_names[action]
296
 
297
+ # Calculate performance metrics
298
+ initial_balance = self.env.initial_balance
299
+ current_net_worth = current_data['net_worth']
300
+ profit_loss = current_net_worth - initial_balance
301
+ profit_loss_pct = (profit_loss / initial_balance) * 100
302
+
303
  status = (
304
  f"🎯 معامله Real-Time در حال اجرا...\n"
305
  f"💰 قیمت فعلی: ${current_data['price']:.2f}\n"
306
+ f"🎪 اقدام اخیر: {action_text}\n"
307
+ f"💼 ارزش پرتفولیو: ${current_net_worth:.2f}\n"
308
+ f"📈 سود/زیان: ${profit_loss:.2f} ({profit_loss_pct:.2f}%)\n"
309
  f"⏰ آخرین بروزرسانی: {datetime.now().strftime('%H:%M:%S')}"
310
  )
311
 
312
+ return {
313
+ "status": status,
314
+ "live_chart": self._create_live_chart(),
315
+ "performance_chart": self._create_performance_chart(),
316
+ "stats_table": self._create_stats_table()
317
+ }
318
 
319
  def stop_live_trading(self):
320
  """Stop the live trading demo"""
 
324
 
325
  final_net_worth = self.live_data[-1]['net_worth'] if self.live_data else self.env.initial_balance
326
  initial_balance = self.env.initial_balance
327
+ profit_loss = final_net_worth - initial_balance
328
+ profit_loss_pct = (profit_loss / initial_balance) * 100
329
+
330
+ # Calculate action statistics
331
+ actions = [h['action'] for h in self.action_history]
332
+ action_counts = {
333
+ "نگهداری": actions.count(0),
334
+ "خرید": actions.count(1),
335
+ "فروش": actions.count(2),
336
+ "بستن": actions.count(3)
337
+ }
338
 
339
  performance = (
340
  f"🛑 معامله Real-Time متوقف شد\n\n"
341
  f"📈 عملکرد نهایی:\n"
342
  f"• سرمایه اولیه: ${initial_balance:.2f}\n"
343
  f"• سرمایه نهایی: ${final_net_worth:.2f}\n"
344
+ f"• سود/زیان: ${profit_loss:.2f} ({profit_loss_pct:.2f}%)\n"
345
+ f"• تعداد اقدامات: {len(self.action_history)}\n"
346
+ f"• خریدها: {action_counts['خرید']} | فروش‌ها: {action_counts['فروش']}"
347
  )
348
 
349
+ return performance, self._create_live_chart(), self._create_performance_chart(), self._create_stats_table()
350
 
351
  def _create_live_chart(self):
352
+ """Create real-time trading chart with advanced features"""
353
  if not self.live_data:
354
  fig = go.Figure()
355
  fig.update_layout(
 
361
  times = [d['timestamp'] for d in self.live_data]
362
  prices = [d['price'] for d in self.live_data]
363
  actions = [d['action'] for d in self.live_data]
364
+ volumes = [d['volume'] for d in self.live_data]
365
 
366
+ fig = make_subplots(
367
+ rows=2, cols=1,
368
+ subplot_titles=['🎯 نمودار قیمت لحظه‌ای', '📊 حجم معاملات'],
369
+ vertical_spacing=0.1,
370
+ row_heights=[0.7, 0.3]
371
+ )
372
 
373
+ # Price line with gradient coloring based on trend
374
  fig.add_trace(go.Scatter(
375
  x=times,
376
  y=prices,
377
  mode='lines',
378
  name='قیمت',
379
+ line=dict(color='blue', width=3),
380
+ hovertemplate='<b>قیمت: $%{y:.2f}</b><br>زمان: %{x}<extra></extra>'
381
+ ), row=1, col=1)
382
 
383
+ # Action markers with different colors and sizes
384
  buy_times = [times[i] for i, action in enumerate(actions) if action == 1]
385
  buy_prices = [prices[i] for i, action in enumerate(actions) if action == 1]
386
 
 
396
  y=buy_prices,
397
  mode='markers',
398
  name='خرید',
399
+ marker=dict(color='green', size=12, symbol='triangle-up', line=dict(width=2, color='darkgreen')),
400
+ hovertemplate='<b>🚀 خرید در $%{y:.2f}</b><br>زمان: %{x}<extra></extra>'
401
+ ), row=1, col=1)
402
 
403
  if sell_times:
404
  fig.add_trace(go.Scatter(
 
406
  y=sell_prices,
407
  mode='markers',
408
  name='فروش',
409
+ marker=dict(color='red', size=12, symbol='triangle-down', line=dict(width=2, color='darkred')),
410
+ hovertemplate='<b>📉 فروش در $%{y:.2f}</b><br>زمان: %{x}<extra></extra>'
411
+ ), row=1, col=1)
412
+
413
+ # Volume bars
414
+ fig.add_trace(go.Bar(
415
+ x=times,
416
+ y=volumes,
417
+ name='حجم',
418
+ marker_color='rgba(100, 100, 200, 0.6)',
419
+ hovertemplate='<b>حجم: %{y:,}</b><br>زمان: %{x}<extra></extra>'
420
+ ), row=2, col=1)
421
 
422
+ # Add moving average
423
+ if len(prices) > 10:
424
+ ma_10 = pd.Series(prices).rolling(window=10).mean()
425
  fig.add_trace(go.Scatter(
426
+ x=times,
427
+ y=ma_10,
428
+ mode='lines',
429
+ name='میانگین متحرک (10)',
430
+ line=dict(color='orange', width=2, dash='dash'),
431
+ hovertemplate='<b>MA10: $%{y:.2f}</b><br>زمان: %{x}<extra></extra>'
432
+ ), row=1, col=1)
433
 
434
  fig.update_layout(
435
+ title="🎯 نمودار معاملات Real-Time - آپدیت لحظه‌ای",
436
+ height=500,
 
 
437
  showlegend=True,
438
+ template="plotly_dark",
439
+ hovermode='x unified'
440
  )
441
 
442
+ fig.update_xaxes(title_text="زمان", row=2, col=1)
443
+ fig.update_yaxes(title_text="قیمت ($)", row=1, col=1)
444
+ fig.update_yaxes(title_text="حجم", row=2, col=1)
445
+
446
  return fig
447
 
448
  def _create_performance_chart(self):
449
+ """Create animated performance chart"""
450
  if not self.live_data:
451
  fig = go.Figure()
452
  fig.update_layout(
453
  title="📈 عملکرد پرتفولیو - در حال آماده‌سازی...",
454
+ height=350
455
  )
456
  return fig
457
 
458
  times = [d['timestamp'] for d in self.live_data]
459
  net_worths = [d['net_worth'] for d in self.live_data]
460
+ prices = [d['price'] for d in self.live_data]
461
 
462
+ fig = make_subplots(
463
+ rows=2, cols=1,
464
+ subplot_titles=['💼 ارزش پرتفولیو لحظه‌ای', '📈 نسبت عملکرد'],
465
+ vertical_spacing=0.15
466
+ )
467
 
468
+ # Net worth line
469
  fig.add_trace(go.Scatter(
470
  x=times,
471
  y=net_worths,
472
  mode='lines+markers',
473
  name='ارزش پرتفولیو',
474
+ line=dict(color='#00FF00', width=4),
475
+ marker=dict(size=6, color='#00FF00'),
476
+ hovertemplate='<b>پرتفولیو: $%{y:.2f}</b><br>زمان: %{x}<extra></extra>'
477
+ ), row=1, col=1)
478
 
479
  # Add initial balance line
480
  if self.env:
481
  fig.add_hline(y=self.env.initial_balance, line_dash="dash",
482
+ line_color="red", annotation_text="سرمایه اولیه",
483
+ row=1, col=1)
484
+
485
+ # Calculate performance ratio (current price / initial price)
486
+ if len(prices) > 1:
487
+ initial_price = prices[0]
488
+ performance_ratio = [(p / initial_price - 1) * 100 for p in prices]
489
+
490
+ fig.add_trace(go.Scatter(
491
+ x=times,
492
+ y=performance_ratio,
493
+ mode='lines',
494
+ name='تغییرات قیمت (%)',
495
+ line=dict(color='cyan', width=3),
496
+ hovertemplate='<b>تغییر: %{y:.2f}%</b><br>زمان: %{x}<extra></extra>'
497
+ ), row=2, col=1)
498
 
499
  fig.update_layout(
500
+ title="💼 عملکرد Real-Time پرتفولیو",
501
+ height=400,
502
+ template="plotly_dark",
503
+ showlegend=True,
504
+ hovermode='x unified'
505
  )
506
 
507
+ fig.update_yaxes(title_text="ارزش ($)", row=1, col=1)
508
+ fig.update_yaxes(title_text="تغییرات (%)", row=2, col=1)
509
+
510
  return fig
511
 
512
+ def _create_stats_table(self):
513
+ """Create real-time statistics table"""
514
+ if not self.live_data:
515
+ return pd.DataFrame({
516
+ 'متریک': ['در حال بارگذاری...'],
517
+ 'مقدار': ['-']
518
+ })
519
+
520
+ current_data = self.live_data[-1]
521
+ initial_balance = self.env.initial_balance
522
+ current_net_worth = current_data['net_worth']
523
+
524
+ # Calculate statistics
525
+ profit_loss = current_net_worth - initial_balance
526
+ profit_loss_pct = (profit_loss / initial_balance) * 100
527
+
528
+ # Price statistics
529
+ prices = [d['price'] for d in self.live_data]
530
+ price_change = prices[-1] - prices[0] if len(prices) > 1 else 0
531
+ price_change_pct = (price_change / prices[0]) * 100 if len(prices) > 1 else 0
532
+
533
+ # Action statistics
534
+ actions = [d['action'] for d in self.live_data[-50:]] # Last 50 actions
535
+ action_counts = {
536
+ "خرید": actions.count(1),
537
+ "فروش": actions.count(2),
538
+ "بستن": actions.count(3)
539
+ }
540
+
541
+ stats_data = {
542
+ 'متریک': [
543
+ '💰 قیمت فعلی',
544
+ '📈 تغییر قیمت',
545
+ '💼 ارزش پرتفولیو',
546
+ '🎯 سود/زیان',
547
+ '🔄 اقدامات اخیر',
548
+ '⏰ مدت اجرا'
549
+ ],
550
+ 'مقدار': [
551
+ f'${current_data["price"]:.2f}',
552
+ f'{price_change_pct:+.2f}%',
553
+ f'${current_net_worth:.2f}',
554
+ f'${profit_loss:+.2f} ({profit_loss_pct:+.2f}%)',
555
+ f'خرید: {action_counts["خرید"]} | فروش: {action_counts["فروش"]}',
556
+ f'{len(self.action_history)} ثانیه'
557
+ ]
558
+ }
559
+
560
+ return pd.DataFrame(stats_data)
561
+
562
  def _create_training_progress(self, training_history):
563
  """Create training progress visualization"""
564
  if not training_history:
 
605
  # Initialize the demo
606
  demo = RealTimeTradingDemo()
607
 
608
+ # Create Gradio interface with auto-refresh
609
  def create_interface():
610
  with gr.Blocks(theme=gr.themes.Soft(), title="Real-Time Trading AI") as interface:
611
  gr.Markdown("""
612
  # 🚀 هوش مصنوعی معامله‌گر Real-Time
613
+ **آموزش و اجرای بلادرنگ روی نمودارهای زنده - آپدیت اتوماتیک هر 1 ثانیه**
614
 
615
+ *نمودارها بصورت کاملاً متحرک و لحظه‌ای آپدیت می‌شوند*
616
  """)
617
 
618
  with gr.Row():
 
659
  status_output = gr.Textbox(
660
  label="وضعیت عملیات",
661
  interactive=False,
662
+ lines=5
663
  )
664
 
665
  with gr.Row():
 
684
  )
685
 
686
  with gr.Row():
687
+ gr.Markdown("## 🎯 فاز ۲: معامله Real-Time (آپدیت اتوماتیک)")
688
 
689
  with gr.Row():
690
  with gr.Column(scale=1):
 
699
  variant="stop",
700
  size="lg"
701
  )
 
 
 
 
 
 
 
702
 
703
  with gr.Row():
704
+ with gr.Column(scale=2):
705
  live_chart = gr.Plot(
706
+ label="📊 نمودار معاملات Real-Time - آپدیت لحظه‌ای"
707
  )
708
 
709
  with gr.Column(scale=1):
710
  performance_chart = gr.Plot(
711
+ label="💼 عملکرد پرتفولیو - آپدیت لحظه‌ای"
712
  )
713
 
714
+ with gr.Row():
715
+ gr.Markdown("## 📈 آمار لحظه‌ای")
716
+
717
+ with gr.Row():
718
+ stats_table = gr.Dataframe(
719
+ label="📊 متریک‌های Real-Time",
720
+ headers=['متریک', 'مقدار'],
721
+ datatype=['str', 'str'],
722
+ row_count=6,
723
+ col_count=2
724
+ )
725
+
726
+ # Auto-refresh component
727
+ auto_refresh = gr.HTML("""
728
+ <script>
729
+ function setupAutoRefresh() {
730
+ let refreshInterval;
731
+
732
+ function startAutoRefresh() {
733
+ refreshInterval = setInterval(() => {
734
+ if (window.liveTradingActive) {
735
+ // Trigger the refresh function
736
+ const refreshBtn = document.querySelector('[data-testid="refresh-button"]');
737
+ if (refreshBtn) refreshBtn.click();
738
+ }
739
+ }, 1000); // Refresh every 1 second
740
+ }
741
+
742
+ function stopAutoRefresh() {
743
+ clearInterval(refreshInterval);
744
+ }
745
+
746
+ // Expose functions to global scope
747
+ window.startAutoRefresh = startAutoRefresh;
748
+ window.stopAutoRefresh = stopAutoRefresh;
749
+ }
750
+
751
+ // Initialize when page loads
752
+ document.addEventListener('DOMContentLoaded', setupAutoRefresh);
753
+ </script>
754
+ """)
755
+
756
  # Event handlers
757
  init_btn.click(
758
  demo.initialize_environment,
 
769
  start_btn.click(
770
  demo.start_live_trading,
771
  inputs=[],
772
+ outputs=[status_output, live_chart, performance_chart, stats_table]
773
+ ).then(
774
+ lambda: gr.HTML("<script>window.liveTradingActive = true; window.startAutoRefresh();</script>")
775
  )
776
 
777
+ # Auto-refresh function
778
+ def auto_refresh_data():
779
+ return demo.get_live_data()["status"], demo.get_live_data()["live_chart"], demo.get_live_data()["performance_chart"], demo.get_live_data()["stats_table"]
780
+
781
+ # Set up periodic refresh
782
+ interface.load(
783
+ fn=auto_refresh_data,
784
  inputs=[],
785
+ outputs=[status_output, live_chart, performance_chart, stats_table],
786
+ every=1000 # Refresh every 1000ms (1 second)
787
  )
788
 
789
  stop_btn.click(
790
  demo.stop_live_trading,
791
  inputs=[],
792
+ outputs=[status_output, live_chart, performance_chart, stats_table]
793
+ ).then(
794
+ lambda: gr.HTML("<script>window.liveTradingActive = false; window.stopAutoRefresh();</script>")
795
  )
796
 
797
  gr.Markdown("""
798
+ ## 🧠 ویژگی‌های سیستم Real-Time:
799
 
800
+ - 📊 **نمودارهای کاملاً متحرک** - آپدیت هر 1 ثانیه
801
+ - 🎯 **معامله لحظه‌ای** - تصمیم‌گیری AI در زمان واقعی
802
+ - 📈 **متریک‌های زنده** - آمار عملکرد به صورت لحظه‌ای
803
+ - 🔄 **آپدیت اتوماتیک** - بدون نیاز به کلیک دستی
804
+ - 💹 **داده‌های واقعی** - شبیه‌سازی بازار واقعی
805
 
806
  *توسعه داده شده توسط Omid Sakaki - 2024*
807
  """)