OmidSakaki commited on
Commit
db2e29b
·
verified ·
1 Parent(s): 0f853b8

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +477 -1
app.py CHANGED
@@ -267,4 +267,480 @@ class TradingAIDemo:
267
  except Exception as e:
268
  self.is_training = False
269
  error_msg = f"❌ Training error: {str(e)}"
270
- print(f"Training error
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
267
  except Exception as e:
268
  self.is_training = False
269
  error_msg = f"❌ Training error: {str(e)}"
270
+ print(f"Training error details: {e}")
271
+ yield None, error_msg
272
+
273
+ def create_price_chart(self, info):
274
+ """Create price chart with actions"""
275
+ if not self.episode_history:
276
+ # Return empty chart with message
277
+ fig = go.Figure()
278
+ fig.update_layout(
279
+ title="Price Chart - No Data Available",
280
+ xaxis_title="Time Step",
281
+ yaxis_title="Price",
282
+ height=300,
283
+ template="plotly_white"
284
+ )
285
+ return fig
286
+
287
+ prices = [h['price'] for h in self.episode_history]
288
+ actions = [h['action'] for h in self.episode_history]
289
+
290
+ fig = go.Figure()
291
+
292
+ # Price line
293
+ fig.add_trace(go.Scatter(
294
+ x=list(range(len(prices))),
295
+ y=prices,
296
+ mode='lines',
297
+ name='Price',
298
+ line=dict(color='blue', width=3)
299
+ ))
300
+
301
+ # Action markers
302
+ buy_indices = [i for i, action in enumerate(actions) if action == 1]
303
+ sell_indices = [i for i, action in enumerate(actions) if action == 2]
304
+ close_indices = [i for i, action in enumerate(actions) if action == 3]
305
+
306
+ if buy_indices:
307
+ fig.add_trace(go.Scatter(
308
+ x=buy_indices,
309
+ y=[prices[i] for i in buy_indices],
310
+ mode='markers',
311
+ name='Buy',
312
+ marker=dict(color='green', size=12, symbol='triangle-up',
313
+ line=dict(width=2, color='darkgreen'))
314
+ ))
315
+
316
+ if sell_indices:
317
+ fig.add_trace(go.Scatter(
318
+ x=sell_indices,
319
+ y=[prices[i] for i in sell_indices],
320
+ mode='markers',
321
+ name='Sell',
322
+ marker=dict(color='red', size=12, symbol='triangle-down',
323
+ line=dict(width=2, color='darkred'))
324
+ ))
325
+
326
+ if close_indices:
327
+ fig.add_trace(go.Scatter(
328
+ x=close_indices,
329
+ y=[prices[i] for i in close_indices],
330
+ mode='markers',
331
+ name='Close',
332
+ marker=dict(color='orange', size=10, symbol='x',
333
+ line=dict(width=2, color='darkorange'))
334
+ ))
335
+
336
+ fig.update_layout(
337
+ title="Price Chart with Trading Actions",
338
+ xaxis_title="Step",
339
+ yaxis_title="Price",
340
+ height=350,
341
+ showlegend=True,
342
+ template="plotly_white"
343
+ )
344
+
345
+ return fig
346
+
347
+ def create_performance_chart(self):
348
+ """Create portfolio performance chart"""
349
+ if not self.episode_history:
350
+ fig = go.Figure()
351
+ fig.update_layout(
352
+ title="Portfolio Performance - No Data Available",
353
+ height=400
354
+ )
355
+ return fig
356
+
357
+ net_worth = [h['net_worth'] for h in self.episode_history]
358
+ rewards = [h['reward'] for h in self.episode_history]
359
+
360
+ fig = make_subplots(
361
+ rows=2, cols=1,
362
+ subplot_titles=['Portfolio Value Over Time', 'Step Rewards'],
363
+ vertical_spacing=0.15
364
+ )
365
+
366
+ # Portfolio value
367
+ fig.add_trace(go.Scatter(
368
+ x=list(range(len(net_worth))),
369
+ y=net_worth,
370
+ mode='lines+markers',
371
+ name='Net Worth',
372
+ line=dict(color='green', width=3),
373
+ marker=dict(size=4)
374
+ ), row=1, col=1)
375
+
376
+ # Add initial balance reference line
377
+ if self.env:
378
+ fig.add_hline(y=self.env.initial_balance, line_dash="dash",
379
+ line_color="red", annotation_text="Initial Balance",
380
+ row=1, col=1)
381
+
382
+ # Rewards as bar chart
383
+ if rewards:
384
+ fig.add_trace(go.Bar(
385
+ x=list(range(len(rewards))),
386
+ y=rewards,
387
+ name='Reward',
388
+ marker_color=['green' if r >= 0 else 'red' for r in rewards],
389
+ opacity=0.7
390
+ ), row=2, col=1)
391
+
392
+ fig.update_layout(height=500, showlegend=False, template="plotly_white")
393
+ fig.update_yaxes(title_text="Value ($)", row=1, col=1)
394
+ fig.update_yaxes(title_text="Reward", row=2, col=1)
395
+ fig.update_xaxes(title_text="Step", row=2, col=1)
396
+
397
+ return fig
398
+
399
+ def create_action_chart(self):
400
+ """Create action distribution chart"""
401
+ if not self.episode_history:
402
+ fig = go.Figure()
403
+ fig.update_layout(
404
+ title="Action Distribution - No Data Available",
405
+ height=300
406
+ )
407
+ return fig
408
+
409
+ actions = [h['action'] for h in self.episode_history]
410
+ action_names = ['Hold', 'Buy', 'Sell', 'Close']
411
+ action_counts = [actions.count(i) for i in range(4)]
412
+
413
+ colors = ['blue', 'green', 'red', 'orange']
414
+
415
+ fig = go.Figure(data=[go.Pie(
416
+ labels=action_names,
417
+ values=action_counts,
418
+ hole=.4,
419
+ marker_colors=colors,
420
+ textinfo='label+percent+value',
421
+ hoverinfo='label+percent+value'
422
+ )])
423
+
424
+ fig.update_layout(
425
+ title="Action Distribution",
426
+ height=350,
427
+ annotations=[dict(text='Actions', x=0.5, y=0.5, font_size=16, showarrow=False)],
428
+ template="plotly_white"
429
+ )
430
+
431
+ return fig
432
+
433
+ def create_training_progress(self, training_history):
434
+ """Create training progress visualization"""
435
+ if not training_history:
436
+ fig = go.Figure()
437
+ fig.update_layout(
438
+ title="Training Progress - No Data Available",
439
+ height=500
440
+ )
441
+ return fig
442
+
443
+ episodes = [h['episode'] for h in training_history]
444
+ rewards = [h['reward'] for h in training_history]
445
+ net_worths = [h['net_worth'] for h in training_history]
446
+ losses = [h.get('loss', 0) for h in training_history]
447
+
448
+ fig = make_subplots(
449
+ rows=2, cols=2,
450
+ subplot_titles=['Episode Rewards', 'Portfolio Value',
451
+ 'Training Loss', 'Moving Average Reward (5)'],
452
+ specs=[[{}, {}], [{}, {}]]
453
+ )
454
+
455
+ # Rewards
456
+ fig.add_trace(go.Scatter(
457
+ x=episodes, y=rewards, mode='lines+markers',
458
+ name='Reward', line=dict(color='blue', width=2),
459
+ marker=dict(size=4)
460
+ ), row=1, col=1)
461
+
462
+ # Portfolio value
463
+ fig.add_trace(go.Scatter(
464
+ x=episodes, y=net_worths, mode='lines+markers',
465
+ name='Net Worth', line=dict(color='green', width=2),
466
+ marker=dict(size=4)
467
+ ), row=1, col=2)
468
+
469
+ # Loss
470
+ if any(loss > 0 for loss in losses):
471
+ fig.add_trace(go.Scatter(
472
+ x=episodes, y=losses, mode='lines+markers',
473
+ name='Loss', line=dict(color='red', width=2),
474
+ marker=dict(size=4)
475
+ ), row=2, col=1)
476
+
477
+ # Moving average reward
478
+ if len(rewards) > 5:
479
+ ma_rewards = []
480
+ for i in range(len(rewards)):
481
+ start_idx = max(0, i - 4)
482
+ ma = np.mean(rewards[start_idx:i+1])
483
+ ma_rewards.append(ma)
484
+
485
+ fig.add_trace(go.Scatter(
486
+ x=episodes, y=ma_rewards, mode='lines',
487
+ name='MA Reward (5)', line=dict(color='orange', width=3, dash='dash')
488
+ ), row=2, col=2)
489
+
490
+ fig.update_layout(
491
+ height=600,
492
+ showlegend=True,
493
+ title_text="Training Progress Over Episodes",
494
+ template="plotly_white"
495
+ )
496
+
497
+ return fig
498
+
499
+ # Initialize the demo
500
+ demo = TradingAIDemo()
501
+
502
+ # Create Gradio interface
503
+ def create_interface():
504
+ with gr.Blocks(theme=gr.themes.Soft(), title="Visual Trading AI") as interface:
505
+ gr.Markdown("""
506
+ # 🚀 Visual Trading AI
507
+ **هوش مصنوعی معامله‌گر بصری - تحلیل چارت‌های قیمت با یادگیری تقویتی عمیق**
508
+
509
+ *این پروژه از شبکه‌های عصبی کانولوشن برای تحلیل بصری نمودارهای قیمت و یادگیری تقویتی برای تصمیم‌گیری معاملاتی استفاده می‌کند.*
510
+ """)
511
+
512
+ with gr.Row():
513
+ with gr.Column(scale=1):
514
+ # Configuration section
515
+ gr.Markdown("## ⚙️ پیکربندی محیط")
516
+
517
+ with gr.Row():
518
+ initial_balance = gr.Slider(
519
+ minimum=1000, maximum=50000, value=10000, step=1000,
520
+ label="موجودی اولیه ($)", info="میزان سرمایه اولیه برای معامله"
521
+ )
522
+
523
+ with gr.Row():
524
+ risk_level = gr.Radio(
525
+ ["Low", "Medium", "High"],
526
+ value="Medium",
527
+ label="سطح ریسک",
528
+ info="سطح ریسک پذیری در معاملات"
529
+ )
530
+
531
+ with gr.Row():
532
+ asset_type = gr.Radio(
533
+ ["Stock", "Crypto", "Forex"],
534
+ value="Stock",
535
+ label="نوع دارایی",
536
+ info="نوع بازار مالی برای شبیه‌سازی"
537
+ )
538
+
539
+ with gr.Row():
540
+ init_btn = gr.Button(
541
+ "🚀 راه‌اندازی محیط معاملاتی",
542
+ variant="primary",
543
+ size="lg"
544
+ )
545
+
546
+ with gr.Row():
547
+ init_status = gr.Textbox(
548
+ label="وضعیت راه‌اندازی",
549
+ interactive=False,
550
+ placeholder="برای شروع، محیط را راه‌اندازی کنید...",
551
+ lines=2
552
+ )
553
+
554
+ with gr.Column(scale=2):
555
+ # Status output
556
+ gr.Markdown("## 📊 وضعیت معاملات")
557
+ status_output = gr.Textbox(
558
+ label="وضعیت اجرا",
559
+ interactive=False,
560
+ placeholder="وضعیت معاملات اینجا نمایش داده می‌شود...",
561
+ lines=4
562
+ )
563
+
564
+ with gr.Row():
565
+ gr.Markdown("## 🎮 کنترل معاملات")
566
+
567
+ with gr.Row():
568
+ # Action controls
569
+ action_choice = gr.Radio(
570
+ ["AI Decision", "Buy", "Sell", "Hold", "Close"],
571
+ value="AI Decision",
572
+ label="انتخاب اقدام",
573
+ info="AI Decision: تصمیم خودکار هوش مصنوعی"
574
+ )
575
+
576
+ with gr.Row():
577
+ with gr.Column(scale=1):
578
+ step_btn = gr.Button(
579
+ "▶️ اجرای یک قدم",
580
+ variant="secondary",
581
+ size="lg"
582
+ )
583
+
584
+ with gr.Column(scale=1):
585
+ episode_btn = gr.Button(
586
+ "🎯 اجرای یک اپیزود (20 قدم)",
587
+ variant="secondary",
588
+ size="lg"
589
+ )
590
+
591
+ with gr.Row():
592
+ # Visualization outputs
593
+ with gr.Column(scale=1):
594
+ price_chart = gr.Plot(
595
+ label="📈 نمودار قیمت و اقدامات"
596
+ )
597
+
598
+ with gr.Column(scale=1):
599
+ performance_chart = gr.Plot(
600
+ label="💰 عملکرد پرتفولیو"
601
+ )
602
+
603
+ with gr.Row():
604
+ with gr.Column(scale=1):
605
+ action_chart = gr.Plot(
606
+ label="🎯 توزیع اقدامات"
607
+ )
608
+
609
+ with gr.Row():
610
+ gr.Markdown("## 🎓 آموزش هوش مصنوعی")
611
+
612
+ with gr.Row():
613
+ with gr.Column(scale=1):
614
+ num_episodes = gr.Slider(
615
+ minimum=10, maximum=200, value=50, step=10,
616
+ label="تعداد اپیزودهای آموزش",
617
+ info="تعداد دوره‌های آموزشی"
618
+ )
619
+
620
+ learning_rate = gr.Slider(
621
+ minimum=0.0001, maximum=0.01, value=0.001, step=0.0001,
622
+ label="نرخ یادگیری",
623
+ info="سرعت یادگیری الگوریتم"
624
+ )
625
+
626
+ train_btn = gr.Button(
627
+ "🤖 شروع آموزش",
628
+ variant="primary",
629
+ size="lg"
630
+ )
631
+
632
+ with gr.Column(scale=2):
633
+ training_plot = gr.Plot(
634
+ label="📊 پیشرفت آموزش"
635
+ )
636
+
637
+ training_status = gr.Textbox(
638
+ label="وضعیت آموزش",
639
+ interactive=False,
640
+ placeholder="وضعیت آموزش اینجا نمایش داده می‌شود...",
641
+ lines=3
642
+ )
643
+
644
+ with gr.Row():
645
+ gr.Markdown("## ℹ️ راهنمای استفاده")
646
+
647
+ with gr.Row():
648
+ with gr.Column(scale=1):
649
+ gr.Markdown("""
650
+ **🎯 اقدامات ممکن:**
651
+ - **Hold (0)**: حفظ وضعیت فعلی
652
+ - **Buy (1)**: باز کردن پوزیشن خرید
653
+ - **Sell (2)**: افزایش سایز پوزیشن
654
+ - **Close (3)**: بستن پوزیشن فعلی
655
+
656
+ **📈 معیارهای عملکرد:**
657
+ - **Reward**: امتیاز دریافتی از محیط
658
+ - **Net Worth**: ارزش کل پرتفولیو
659
+ - **Balance**: موجودی نقدی
660
+ - **Position**: سایز پوزیشن فعلی
661
+ """)
662
+
663
+ with gr.Column(scale=1):
664
+ gr.Markdown("""
665
+ **🔧 نحوه استفاده:**
666
+ 1. محیط ��ا راه‌اندازی کنید
667
+ 2. اقدامات تکی یا اپیزودها را اجرا کنید
668
+ 3. عملکرد را در نمودارها مشاهده کنید
669
+ 4. هوش مصنوعی را آموزش دهید
670
+ 5. نتایج را تحلیل کنید
671
+
672
+ **⚠️ توجه:**
673
+ این یک شبیه‌ساز آموزشی است و برای معاملات واقعی طراحی نشده است.
674
+ """)
675
+
676
+ # Event handlers
677
+ init_btn.click(
678
+ demo.initialize_environment,
679
+ inputs=[initial_balance, risk_level, asset_type],
680
+ outputs=[init_status]
681
+ )
682
+
683
+ step_btn.click(
684
+ demo.run_single_step,
685
+ inputs=[action_choice],
686
+ outputs=[price_chart, performance_chart, action_chart, status_output]
687
+ )
688
+
689
+ episode_btn.click(
690
+ demo.run_episode,
691
+ inputs=[],
692
+ outputs=[price_chart, performance_chart, action_chart, status_output]
693
+ )
694
+
695
+ train_btn.click(
696
+ demo.train_agent,
697
+ inputs=[num_episodes, learning_rate],
698
+ outputs=[training_plot, training_status]
699
+ )
700
+
701
+ gr.Markdown("""
702
+ ## 🏗 معماری فنی
703
+
704
+ **🎯 هسته هوش مصنوعی:**
705
+ - **پردازش بصری**: شبکه عصبی کانولوشن (CNN) برای تحلیل نمودارهای قیمت
706
+ - **یادگیری تقویتی**: الگوریتم Deep Q-Network (DQN) برای تصمیم‌گیری
707
+ - **تجربه replay**: ذخیره و بازیابی تجربیات برای یادگیری پایدار
708
+
709
+ **🛠 فناوری‌ها:**
710
+ - **یادگیری عمیق**: PyTorch
711
+ - **محیط شبیه‌سازی**: محیط اختصاصی معاملاتی
712
+ - **رابط کاربری**: Gradio
713
+ - **ویژوالیزیشن**: Plotly, Matplotlib
714
+ - **پردازش داده**: NumPy, Pandas
715
+
716
+ **📊 ویژگی‌های کلیدی:**
717
+ - تحلیل بصری نمودارهای قیمت
718
+ - یادگیری خودکار استراتژی‌های معاملاتی
719
+ - نمایش زنده عملکرد و تصمیم‌ها
720
+ - کنترل دستی و خودکار
721
+ - آنالیز جامع عملکرد
722
+
723
+ *توسعه داده شده توسط Omid Sakaki - 2024*
724
+ """)
725
+
726
+ return interface
727
+
728
+ # Create and launch interface
729
+ if __name__ == "__main__":
730
+ print("🚀 Starting Visual Trading AI Application...")
731
+ print("📊 Initializing components...")
732
+
733
+ interface = create_interface()
734
+
735
+ print("✅ Application initialized successfully!")
736
+ print("🌐 Starting server on http://0.0.0.0:7860")
737
+ print("📱 You can now access the application in your browser")
738
+
739
+ # Launch with better configuration
740
+ interface.launch(
741
+ server_name="0.0.0.0",
742
+ server_port=7860,
743
+ share=False,
744
+ show_error=True,
745
+ debug=True
746
+ )