307 lines
9.9 KiB
Python
307 lines
9.9 KiB
Python
#!/usr/bin/env python3
|
|||
|
|
"""
|
||
|
|
Integration Script: Add P&L Tracking to Notebook
|
||
|
|
Adds 6 new cells for comprehensive P&L tracking and dashboard
|
||
|
|
"""
|
||
|
|
|
||
|
|
import nbformat
|
||
|
|
from pathlib import Path
|
||
|
|
import sys
|
||
|
|
|
||
|
|
def integrate_pnl_tracker(notebook_path):
|
||
|
|
"""Add P&L tracking cells to notebook"""
|
||
|
|
|
||
|
|
# Read notebook
|
||
|
|
with open(notebook_path, 'r', encoding='utf-8') as f:
|
||
|
|
nb = nbformat.read(f, as_version=4)
|
||
|
|
|
||
|
|
print(f"📖 Loaded notebook: {Path(notebook_path).name}")
|
||
|
|
print(f" Current cells: {len(nb.cells)}")
|
||
|
|
|
||
|
|
# Define new cells
|
||
|
|
new_cells = []
|
||
|
|
|
||
|
|
# ==========================================
|
||
|
|
# Cell 1: Section Header (Markdown)
|
||
|
|
# ==========================================
|
||
|
|
new_cells.append(nbformat.v4.new_markdown_cell("""# 💰 P&L TRACKING & PERFORMANCE ANALYTICS (V1.9)
|
||
|
|
|
||
|
|
**Automatic MT5 History Import & Real-Time P&L Dashboard**
|
||
|
|
|
||
|
|
Features:
|
||
|
|
- 📥 **Automatic MT5 History Import** - Syncs closed trades from MT5
|
||
|
|
- 💰 **Real P&L Calculation** - Matches Entry+Exit deals for accurate P&L
|
||
|
|
- 📊 **Win Rate Analysis** - Real Win Rate from closed MT5 trades
|
||
|
|
- 📈 **Performance Metrics** - Profit Factor, Max Drawdown, Avg Win/Loss
|
||
|
|
- 🎯 **Session Analysis** - Compare Asian vs NY performance
|
||
|
|
- 📅 **Time-based Reports** - Today, Week, Month, All-Time
|
||
|
|
- 🔄 **Automatic Sync** - Scheduled hourly updates
|
||
|
|
|
||
|
|
**Status:** ✅ READY TO USE
|
||
|
|
"""))
|
||
|
|
|
||
|
|
# ==========================================
|
||
|
|
# Cell 2: Setup P&L Tracker (Code)
|
||
|
|
# ==========================================
|
||
|
|
new_cells.append(nbformat.v4.new_code_cell("""# ==========================================
|
||
|
|
# SETUP P&L TRACKER
|
||
|
|
# ==========================================
|
||
|
|
|
||
|
|
from mt5_pnl_tracker import MT5PnLTracker, scheduled_pnl_sync
|
||
|
|
|
||
|
|
print("=" * 80)
|
||
|
|
print("🚀 INITIALIZING P&L TRACKER...")
|
||
|
|
print("=" * 80)
|
||
|
|
|
||
|
|
# Initialize tracker
|
||
|
|
pnl_tracker = MT5PnLTracker(
|
||
|
|
db_path="trading_bot.db",
|
||
|
|
magic_number=None # None = all trades, or specify your EA magic number
|
||
|
|
)
|
||
|
|
|
||
|
|
# Connect to database
|
||
|
|
pnl_tracker.connect_db()
|
||
|
|
|
||
|
|
print("\\n✅ P&L Tracker initialized successfully!")
|
||
|
|
print(" Database: trading_bot.db")
|
||
|
|
print(" Tables: mt5_deals, matched_positions, pnl_summary")
|
||
|
|
print("=" * 80)
|
||
|
|
"""))
|
||
|
|
|
||
|
|
# ==========================================
|
||
|
|
# Cell 3: Initial Sync (Code)
|
||
|
|
# ==========================================
|
||
|
|
new_cells.append(nbformat.v4.new_code_cell("""# ==========================================
|
||
|
|
# INITIAL SYNC: IMPORT MT5 HISTORY
|
||
|
|
# ==========================================
|
||
|
|
|
||
|
|
print("\\n📥 Importing MT5 history...")
|
||
|
|
print(" This will import last 30 days of trades from MT5")
|
||
|
|
print(" Please wait...\\n")
|
||
|
|
|
||
|
|
# Perform initial sync
|
||
|
|
sync_results = pnl_tracker.sync_and_update(days_back=30)
|
||
|
|
|
||
|
|
if sync_results['success']:
|
||
|
|
summary = sync_results['summary']
|
||
|
|
|
||
|
|
print("=" * 80)
|
||
|
|
print("✅ SYNC SUCCESSFUL!")
|
||
|
|
print("=" * 80)
|
||
|
|
print(f"\\n📥 Import Results:")
|
||
|
|
print(f" New Deals: {summary['new_deals']}")
|
||
|
|
print(f" Matched Positions: {summary['matched_positions']}")
|
||
|
|
print(f"\\n📊 Current Performance:")
|
||
|
|
print(f" Total Trades: {summary['total_trades']}")
|
||
|
|
print(f" Win Rate: {summary['win_rate']:.1f}%")
|
||
|
|
print(f" Net P&L: ${summary['net_profit']:.2f}")
|
||
|
|
print("=" * 80)
|
||
|
|
|
||
|
|
if summary['new_deals'] == 0:
|
||
|
|
print("\\n💡 No new deals found. This means:")
|
||
|
|
print(" • History already imported, OR")
|
||
|
|
print(" • No trades in last 30 days")
|
||
|
|
else:
|
||
|
|
print("=" * 80)
|
||
|
|
print("❌ SYNC FAILED")
|
||
|
|
print("=" * 80)
|
||
|
|
print(f"Error: {sync_results.get('error', 'Unknown error')}")
|
||
|
|
print("\\n💡 Troubleshooting:")
|
||
|
|
print(" • Check MT5 is running")
|
||
|
|
print(" • Verify MT5 connection")
|
||
|
|
print(" • Check trading history exists")
|
||
|
|
"""))
|
||
|
|
|
||
|
|
# ==========================================
|
||
|
|
# Cell 4: Add to Scheduler (Code)
|
||
|
|
# ==========================================
|
||
|
|
new_cells.append(nbformat.v4.new_code_cell("""# ==========================================
|
||
|
|
# ADD P&L SYNC TO SCHEDULER
|
||
|
|
# ==========================================
|
||
|
|
|
||
|
|
from apscheduler.triggers.interval import IntervalTrigger
|
||
|
|
|
||
|
|
print("\\n🔄 Adding P&L sync to scheduler...")
|
||
|
|
|
||
|
|
# Remove old job if exists
|
||
|
|
try:
|
||
|
|
scheduler.remove_job('pnl_sync')
|
||
|
|
print(" Removed old P&L sync job")
|
||
|
|
except:
|
||
|
|
pass
|
||
|
|
|
||
|
|
# Add hourly P&L sync
|
||
|
|
scheduler.add_job(
|
||
|
|
scheduled_pnl_sync,
|
||
|
|
trigger=IntervalTrigger(hours=1),
|
||
|
|
args=[pnl_tracker, 7], # Sync last 7 days
|
||
|
|
id='pnl_sync',
|
||
|
|
name='P&L Sync',
|
||
|
|
replace_existing=True,
|
||
|
|
max_instances=1
|
||
|
|
)
|
||
|
|
|
||
|
|
print("✅ P&L sync scheduled (every 1 hour)")
|
||
|
|
print(" Syncs last 7 days from MT5")
|
||
|
|
|
||
|
|
# Show all scheduler jobs
|
||
|
|
print("\\n📋 Active Scheduler Jobs:")
|
||
|
|
for job in scheduler.get_jobs():
|
||
|
|
print(f" • {job.id}: {job.trigger}")
|
||
|
|
|
||
|
|
print("\\n✅ Scheduler updated successfully!")
|
||
|
|
print("=" * 80)
|
||
|
|
"""))
|
||
|
|
|
||
|
|
# ==========================================
|
||
|
|
# Cell 5: Markdown - Usage Instructions
|
||
|
|
# ==========================================
|
||
|
|
new_cells.append(nbformat.v4.new_markdown_cell("""## 📖 How to Use P&L Tracker
|
||
|
|
|
||
|
|
### 📊 View Dashboard
|
||
|
|
Run the dashboard cell to see:
|
||
|
|
- All-time performance
|
||
|
|
- Monthly performance
|
||
|
|
- Weekly performance
|
||
|
|
- Today's performance
|
||
|
|
|
||
|
|
### 📜 View Recent Trades
|
||
|
|
See last 10 closed trades with:
|
||
|
|
- Entry/Exit prices
|
||
|
|
- P&L per trade
|
||
|
|
- Duration
|
||
|
|
- Win/Loss status
|
||
|
|
|
||
|
|
### 🔄 Manual Sync
|
||
|
|
If you want to manually sync MT5 history:
|
||
|
|
```python
|
||
|
|
sync_results = pnl_tracker.sync_and_update(days_back=30)
|
||
|
|
print(sync_results)
|
||
|
|
```
|
||
|
|
|
||
|
|
### 📊 Get Specific Period Metrics
|
||
|
|
```python
|
||
|
|
# Get metrics for specific period
|
||
|
|
all_time = pnl_tracker.calculate_pnl_metrics('all')
|
||
|
|
month = pnl_tracker.calculate_pnl_metrics('month')
|
||
|
|
week = pnl_tracker.calculate_pnl_metrics('week')
|
||
|
|
today = pnl_tracker.calculate_pnl_metrics('today')
|
||
|
|
```
|
||
|
|
|
||
|
|
### 🎯 Integration with Dynamic Thresholds
|
||
|
|
The P&L tracker data can be used by the Dynamic Threshold Optimizer to better calibrate optimal confidence thresholds based on real MT5 performance!
|
||
|
|
"""))
|
||
|
|
|
||
|
|
# ==========================================
|
||
|
|
# Cell 6: Dashboard Display (Code)
|
||
|
|
# ==========================================
|
||
|
|
new_cells.append(nbformat.v4.new_code_cell("""# ==========================================
|
||
|
|
# 💰 P&L PERFORMANCE DASHBOARD
|
||
|
|
# ==========================================
|
||
|
|
|
||
|
|
# Generate and display dashboard
|
||
|
|
dashboard = pnl_tracker.generate_dashboard()
|
||
|
|
print(dashboard)
|
||
|
|
|
||
|
|
# Show recent trades
|
||
|
|
print("\\n" + "=" * 80)
|
||
|
|
print("📜 RECENT TRADES (Last 10)")
|
||
|
|
print("=" * 80)
|
||
|
|
|
||
|
|
recent_trades = pnl_tracker.get_recent_trades(limit=10)
|
||
|
|
|
||
|
|
if not recent_trades.empty:
|
||
|
|
# Format for display
|
||
|
|
recent_trades['entry_time'] = pd.to_datetime(recent_trades['entry_time']).dt.strftime('%Y-%m-%d %H:%M')
|
||
|
|
recent_trades['exit_time'] = pd.to_datetime(recent_trades['exit_time']).dt.strftime('%Y-%m-%d %H:%M')
|
||
|
|
recent_trades['net_profit'] = recent_trades['net_profit'].round(2)
|
||
|
|
recent_trades['pips'] = recent_trades['pips'].round(1)
|
||
|
|
recent_trades['duration_hours'] = recent_trades['duration_hours'].round(1)
|
||
|
|
recent_trades['status'] = recent_trades['is_win'].apply(lambda x: '✅ WIN' if x else '❌ LOSS')
|
||
|
|
|
||
|
|
# Select columns to display
|
||
|
|
display_cols = ['position_id', 'symbol', 'type', 'entry_time', 'exit_time',
|
||
|
|
'net_profit', 'pips', 'duration_hours', 'status']
|
||
|
|
|
||
|
|
print("\\n" + recent_trades[display_cols].to_string(index=False))
|
||
|
|
else:
|
||
|
|
print("\\n❌ No recent trades found")
|
||
|
|
|
||
|
|
print("\\n" + "=" * 80)
|
||
|
|
print("✅ Dashboard refresh complete!")
|
||
|
|
print(f"Last updated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
|
||
|
|
print("=" * 80)
|
||
|
|
"""))
|
||
|
|
|
||
|
|
# ==========================================
|
||
|
|
# Add cells to notebook
|
||
|
|
# ==========================================
|
||
|
|
|
||
|
|
# Find position to insert (after last cell)
|
||
|
|
insert_position = len(nb.cells)
|
||
|
|
|
||
|
|
print(f"\n📝 Adding {len(new_cells)} new cells at position {insert_position}...")
|
||
|
|
|
||
|
|
for i, cell in enumerate(new_cells, start=insert_position):
|
||
|
|
nb.cells.insert(i, cell)
|
||
|
|
cell_type = "Markdown" if cell.cell_type == "markdown" else "Code"
|
||
|
|
print(f" ✅ Cell {i}: {cell_type}")
|
||
|
|
|
||
|
|
# Save notebook
|
||
|
|
with open(notebook_path, 'w', encoding='utf-8') as f:
|
||
|
|
nbformat.write(nb, f)
|
||
|
|
|
||
|
|
print(f"\n✅ Integration complete!")
|
||
|
|
print(f" Total cells now: {len(nb.cells)}")
|
||
|
|
print(f" New cells: {insert_position} - {len(nb.cells)-1}")
|
||
|
|
|
||
|
|
return {
|
||
|
|
'success': True,
|
||
|
|
'notebook': notebook_path,
|
||
|
|
'cells_added': len(new_cells),
|
||
|
|
'total_cells': len(nb.cells),
|
||
|
|
'new_cell_range': f"{insert_position}-{len(nb.cells)-1}"
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
if __name__ == "__main__":
|
||
|
|
notebook_path = "TradingBot_V1.6_Adaptive_Complete_CORRECTED.ipynb"
|
||
|
|
|
||
|
|
if not Path(notebook_path).exists():
|
||
|
|
print(f"❌ Error: Notebook not found: {notebook_path}")
|
||
|
|
sys.exit(1)
|
||
|
|
|
||
|
|
print("=" * 80)
|
||
|
|
print("🚀 P&L TRACKER INTEGRATION")
|
||
|
|
print("=" * 80)
|
||
|
|
print(f"\nNotebook: {notebook_path}")
|
||
|
|
print("Adding: 6 new cells for P&L tracking")
|
||
|
|
|
||
|
|
result = integrate_pnl_tracker(notebook_path)
|
||
|
|
|
||
|
|
if result['success']:
|
||
|
|
print("\n" + "=" * 80)
|
||
|
|
print("🎉 SUCCESS!")
|
||
|
|
print("=" * 80)
|
||
|
|
print(f"\n✅ Added {result['cells_added']} cells to notebook")
|
||
|
|
print(f" Total cells: {result['total_cells']}")
|
||
|
|
print(f" New cells: {result['new_cell_range']}")
|
||
|
|
|
||
|
|
print("\n📋 Next Steps:")
|
||
|
|
print(" 1. Open Jupyter Notebook")
|
||
|
|
print(" 2. Restart Kernel (Kernel → Restart & Clear Output)")
|
||
|
|
print(" 3. Run All Cells (Cell → Run All)")
|
||
|
|
print(" 4. Verify P&L sync in new cells")
|
||
|
|
print(" 5. Check dashboard display")
|
||
|
|
|
||
|
|
print("\n💡 The P&L tracker will now:")
|
||
|
|
print(" • Automatically sync MT5 history every hour")
|
||
|
|
print(" • Calculate real Win Rate from closed trades")
|
||
|
|
print(" • Track profit/loss accurately")
|
||
|
|
print(" • Generate performance reports")
|
||
|
|
|
||
|
|
print("\n" + "=" * 80)
|
||
|
|
else:
|
||
|
|
print(f"\n❌ Integration failed!")
|
||
|
|
sys.exit(1)
|