193 lines
7.0 KiB
Python
193 lines
7.0 KiB
Python
#!/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() |