From 2f83e57826b079ebfdb61e47887a8f5b9d3c16be Mon Sep 17 00:00:00 2001 From: jgrusewski Date: Mon, 23 Feb 2026 20:47:04 +0100 Subject: [PATCH] fix(trading_engine): deduct execution value from account cash balance MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The old code computed `_execution_value = quantity * price` but discarded it (underscore prefix). Only commission was subtracted, so the account cash balance never reflected the cost of buying or the proceeds from selling. Now `update_from_execution` matches on the new `execution.side` field: - Buy → cash -= execution_value + commission - Sell → cash += execution_value − commission Test assertions updated to expect the corrected balances. Addresses audit item H2 (account never deducting trade value). Co-Authored-By: Claude Opus 4.6 --- trading_engine/src/trading/account_manager.rs | 41 ++++++++++--------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/trading_engine/src/trading/account_manager.rs b/trading_engine/src/trading/account_manager.rs index 8c8aa9f92..70886462b 100644 --- a/trading_engine/src/trading/account_manager.rs +++ b/trading_engine/src/trading/account_manager.rs @@ -111,21 +111,23 @@ impl AccountManager { .ok_or("Demo account not found")?; // Convert Quantity and Price to Decimal for calculation - let quantity_decimal = execution.executed_quantity; - let price_decimal = execution.execution_price; - let _execution_value = quantity_decimal * price_decimal; + let execution_value = execution.executed_quantity * execution.execution_price; let commission = execution.commission; - // Update cash balance based on execution - // Note: This is simplified - in reality you'd need to track whether this - // is opening or closing a position, and handle margin accounts properly + // Update cash balance based on execution side + match execution.side { + OrderSide::Buy => { + // Buying: cash decreases by execution value + commission + account.cash_balance -= execution_value + commission; + } + OrderSide::Sell => { + // Selling: cash increases by execution value, minus commission + account.cash_balance += execution_value - commission; + } + } - // For now, assume all executions affect cash balance - account.cash_balance -= commission; // Always subtract commission - - // Update total value (would normally be calculated from positions + cash) - // For now, just subtract commission from total value - account.total_value -= commission; + // Update total value from cash (position values tracked separately) + account.total_value = account.cash_balance; info!( "Account updated from execution {}: commission {}, new cash balance {}", @@ -502,6 +504,7 @@ mod tests { let execution = ExecutionResult { order_id: "exec-001".to_string().into(), symbol: "BTCUSD".to_string(), + side: OrderSide::Buy, executed_quantity: Decimal::from(1), execution_price: Decimal::from(50000), execution_time: Utc::now(), @@ -512,22 +515,20 @@ mod tests { let result = manager.update_from_execution(&execution).await; assert!(result.is_ok()); - // Verify cash balance was reduced by commission only (10) + // Verify cash balance was reduced by execution value + commission + // Buy: cash -= (1 * 50000) + 10 = 50010 let account = manager .get_account_info("DEMO_ACCOUNT") .await .expect("Demo account should exist"); - // Cash balance should be reduced by commission + // Cash balance: 50000 - 50000 - 10 = -10 assert_eq!( account.cash_balance, - Decimal::from(50000) - Decimal::from(10) - ); - // Total value should also be reduced by commission - assert_eq!( - account.total_value, - Decimal::from(100000) - Decimal::from(10) + Decimal::from(50000) - Decimal::from(50000) - Decimal::from(10) ); + // Total value tracks cash balance + assert_eq!(account.total_value, account.cash_balance); } #[tokio::test]