#!/usr/bin/env python3 """ Position Sync Enhancement - Fix P&L and Win Rate Calculation This script enhances the position synchronization and P&L calculation to properly account for leverage in the trading system. """ import os import sys import logging from pathlib import Path from datetime import datetime # Add project root to path project_root = Path(__file__).parent sys.path.insert(0, str(project_root)) from core.config import get_config, setup_logging from core.trading_executor import TradingExecutor, TradeRecord # Setup logging setup_logging() logger = logging.getLogger(__name__) def analyze_trade_records(): """Analyze trade records for P&L calculation issues""" logger.info("Analyzing trade records for P&L calculation issues...") # Initialize trading executor trading_executor = TradingExecutor() # Get trade records trade_records = trading_executor.trade_records if not trade_records: logger.warning("No trade records found.") return logger.info(f"Found {len(trade_records)} trade records.") # Analyze P&L calculation total_pnl = 0.0 total_gross_pnl = 0.0 total_fees = 0.0 winning_trades = 0 losing_trades = 0 breakeven_trades = 0 for trade in trade_records: # Calculate correct P&L with leverage entry_value = trade.entry_price * trade.quantity exit_value = trade.exit_price * trade.quantity if trade.side == 'LONG': gross_pnl = (exit_value - entry_value) * trade.leverage else: # SHORT gross_pnl = (entry_value - exit_value) * trade.leverage # Calculate fees fees = (entry_value + exit_value) * 0.001 # 0.1% fee on both entry and exit # Calculate net P&L net_pnl = gross_pnl - fees # Compare with stored values pnl_diff = abs(net_pnl - trade.pnl) if pnl_diff > 0.01: # More than 1 cent difference logger.warning(f"P&L calculation issue detected for trade {trade.entry_time}:") logger.warning(f" Stored P&L: ${trade.pnl:.2f}") logger.warning(f" Calculated P&L: ${net_pnl:.2f}") logger.warning(f" Difference: ${pnl_diff:.2f}") logger.warning(f" Leverage used: {trade.leverage}x") # Update statistics total_pnl += net_pnl total_gross_pnl += gross_pnl total_fees += fees if net_pnl > 0.01: # More than 1 cent profit winning_trades += 1 elif net_pnl < -0.01: # More than 1 cent loss losing_trades += 1 else: breakeven_trades += 1 # Calculate win rate total_trades = winning_trades + losing_trades + breakeven_trades win_rate = (winning_trades / total_trades * 100) if total_trades > 0 else 0.0 logger.info("\nTrade Analysis Results:") logger.info(f" Total trades: {total_trades}") logger.info(f" Winning trades: {winning_trades}") logger.info(f" Losing trades: {losing_trades}") logger.info(f" Breakeven trades: {breakeven_trades}") logger.info(f" Win rate: {win_rate:.1f}%") logger.info(f" Total P&L: ${total_pnl:.2f}") logger.info(f" Total gross P&L: ${total_gross_pnl:.2f}") logger.info(f" Total fees: ${total_fees:.2f}") # Check for leverage issues leverage_issues = False for trade in trade_records: if trade.leverage <= 1.0: leverage_issues = True logger.warning(f"Low leverage detected: {trade.leverage}x for trade at {trade.entry_time}") if leverage_issues: logger.warning("\nLeverage issues detected. Consider fixing the leverage calculation.") logger.info("Recommended fix: Ensure leverage is properly set in the trading executor.") else: logger.info("\nNo leverage issues detected.") def fix_leverage_calculation(): """Fix leverage calculation in the trading executor""" logger.info("Fixing leverage calculation in the trading executor...") # Initialize trading executor trading_executor = TradingExecutor() # Get current leverage current_leverage = trading_executor.current_leverage logger.info(f"Current leverage setting: {current_leverage}x") # Check if leverage is properly set if current_leverage <= 1: logger.warning("Leverage is set too low. Updating to 20x...") trading_executor.current_leverage = 20 logger.info(f"Updated leverage to {trading_executor.current_leverage}x") else: logger.info("Leverage is already set correctly.") # Update trade records with correct leverage updated_count = 0 for i, trade in enumerate(trading_executor.trade_records): if trade.leverage <= 1.0: # Create updated trade record updated_trade = TradeRecord( symbol=trade.symbol, side=trade.side, quantity=trade.quantity, entry_price=trade.entry_price, exit_price=trade.exit_price, entry_time=trade.entry_time, exit_time=trade.exit_time, pnl=trade.pnl, fees=trade.fees, confidence=trade.confidence, hold_time_seconds=trade.hold_time_seconds, leverage=trading_executor.current_leverage, # Use current leverage setting position_size_usd=trade.position_size_usd, gross_pnl=trade.gross_pnl, net_pnl=trade.net_pnl ) # Recalculate P&L with correct leverage entry_value = updated_trade.entry_price * updated_trade.quantity exit_value = updated_trade.exit_price * updated_trade.quantity if updated_trade.side == 'LONG': updated_trade.gross_pnl = (exit_value - entry_value) * updated_trade.leverage else: # SHORT updated_trade.gross_pnl = (entry_value - exit_value) * updated_trade.leverage # Recalculate fees updated_trade.fees = (entry_value + exit_value) * 0.001 # 0.1% fee on both entry and exit # Recalculate net P&L updated_trade.net_pnl = updated_trade.gross_pnl - updated_trade.fees updated_trade.pnl = updated_trade.net_pnl # Update trade record trading_executor.trade_records[i] = updated_trade updated_count += 1 logger.info(f"Updated {updated_count} trade records with correct leverage.") # Save updated trade records # Note: This is a placeholder. In a real implementation, you would need to # persist the updated trade records to storage. logger.info("Changes will take effect on next dashboard restart.") return updated_count > 0 if __name__ == "__main__": logger.info("=" * 70) logger.info("POSITION SYNC ENHANCEMENT") logger.info("=" * 70) if len(sys.argv) > 1 and sys.argv[1] == 'fix': fix_leverage_calculation() else: analyze_trade_records()