fix broken merge

This commit is contained in:
Dobromir Popov
2025-10-08 20:02:41 +03:00
parent a468c75c47
commit 270ba2e52b
12 changed files with 493 additions and 86 deletions

View File

@@ -221,6 +221,7 @@ class TradingExecutor:
# Connect to exchange - skip connection check in simulation mode
if self.trading_enabled:
if self.simulation_mode:
logger.info("TRADING EXECUTOR: Running in simulation mode - no exchange connection needed")
else:
logger.info("TRADING EXECUTOR: Attempting to connect to exchange...")
if not self._connect_exchange():
@@ -533,8 +534,8 @@ class TradingExecutor:
# For simplicity, assume required capital is the full position value in USD
required_capital = self._calculate_position_size(confidence, current_price)
else:
available_balance = self.exchange.get_balance(quote_asset)
# Get available balance
available_balance = self.exchange.get_balance(quote_asset)
logger.info(f"BALANCE CHECK: Symbol: {symbol}, Action: {action}, Required: ${required_capital:.2f} {quote_asset}, Available: ${available_balance:.2f} {quote_asset}")
@@ -1401,9 +1402,26 @@ class TradingExecutor:
if self.simulation_mode:
logger.info(f"SIMULATION MODE ({self.trading_mode.upper()}) - Short close logged but not executed")
# Calculate simulated fees in simulation mode
trading_fees = self.exchange_config.get('trading_fees', {})
taker_fee_rate = trading_fees.get('taker_fee', trading_fees.get('default_fee', 0.0006))
simulated_fees = position.quantity * current_price * taker_fee_rate
# Get current leverage setting
leverage = self.get_leverage()
# Calculate position size in USD
position_size_usd = position.quantity * position.entry_price
# Calculate gross PnL (before fees) with leverage - SHORT profits when price falls
gross_pnl = (position.entry_price - current_price) * position.quantity * leverage
# Calculate net PnL (after fees)
net_pnl = gross_pnl - simulated_fees
# Calculate hold time
exit_time = datetime.now()
hold_time_seconds = (exit_time - position.entry_time).total_seconds()
# Create trade record with corrected PnL calculations
trade_record = TradeRecord(
symbol=symbol,
@@ -1413,12 +1431,37 @@ class TradingExecutor:
exit_price=current_price,
entry_time=position.entry_time,
exit_time=exit_time,
pnl=net_pnl, # Store net PnL as the main PnL value
fees=simulated_fees,
confidence=confidence,
hold_time_seconds=hold_time_seconds,
leverage=leverage,
position_size_usd=position_size_usd,
gross_pnl=gross_pnl,
net_pnl=net_pnl
)
self.trade_history.append(trade_record)
self.trade_records.append(trade_record)
self.daily_loss += max(0, -net_pnl) # Use net_pnl instead of pnl
# Adjust profitability reward multiplier based on recent performance
self._adjust_profitability_reward_multiplier()
# Update consecutive losses using net_pnl
if net_pnl < -0.001: # A losing trade
self.consecutive_losses += 1
elif net_pnl > 0.001: # A winning trade
self.consecutive_losses = 0
else: # Breakeven trade
self.consecutive_losses = 0
# Remove position
del self.positions[symbol]
self.last_trade_time[symbol] = datetime.now()
self.daily_trades += 1
logger.info(f"SHORT position closed - Gross P&L: ${gross_pnl:.2f}, Net P&L: ${net_pnl:.2f}, Fees: ${simulated_fees:.3f}")
return True
try:
@@ -2002,8 +2045,29 @@ class TradingExecutor:
return self.trade_history.copy()
def get_balance(self) -> Dict[str, float]:
"""TODO(Guideline: expose real account state) Return actual account balances instead of raising."""
raise NotImplementedError("Implement TradingExecutor.get_balance to supply real balance data; stubs are forbidden.")
"""Get account balances from the primary exchange.
Returns:
Dict[str, float]: Asset balances in format {'USDT': 100.0, 'ETH': 0.5, ...}
"""
try:
# Use the existing get_account_balance method to get real exchange data
account_balances = self.get_account_balance()
# Convert to simple format: asset -> free balance
simple_balances = {}
for asset, balance_data in account_balances.items():
if isinstance(balance_data, dict):
simple_balances[asset] = balance_data.get('free', 0.0)
else:
simple_balances[asset] = float(balance_data) if balance_data else 0.0
logger.debug(f"Retrieved balances for {len(simple_balances)} assets")
return simple_balances
except Exception as e:
logger.error(f"Error getting balance: {e}")
return {}
def export_trades_to_csv(self, filename: Optional[str] = None) -> str:
"""Export trade history to CSV file with comprehensive analysis"""