=== 1. Position::calculateProfit() === [PASS] BUY profit positive [PASS] BUY profit negative [PASS] BUY break-even [PASS] SELL profit positive [PASS] SELL profit negative [PASS] SELL break-even [PASS] buy (lowercase) same as BUY === 2. PositionService validation (no DB) === [PASS] blank symbol rejected [PASS] 6-char symbol rejected [PASS] digit in symbol rejected [PASS] zero quantity rejected [PASS] negative quantity rejected [PASS] invalid direction rejected [PASS] lowercase symbol normalised (fails on price not symbol format) === 3. Database integration === [PASS] openPosition returns array [PASS] position has correct trader_id [PASS] position symbol is GOOGL [PASS] position direction is BUY [PASS] position quantity is 5 [PASS] position entry_price is 25000 [PASS] position status is open [PASS] open trade record inserted [PASS] open trade action = open [PASS] open trade entry_price = 25000 [PASS] open trade exit_price is null [PASS] open trade profit is null [PASS] open trade trader_id matches [PASS] getPositionsByTrader returns array [PASS] getPositionsByTrader has >= 1 row [PASS] getOpenPositions returns array [PASS] getOpenPositions includes new position [PASS] stale price causes "Unable to fetch" on openPosition [PASS] closePosition returns true [PASS] position status is closed [PASS] exit_price is 27000 [PASS] profit is 10000 (BUY) [PASS] closed_at is set [PASS] close trade record inserted [PASS] close trade exit_price = 27000 [PASS] close trade profit = 10000 [PASS] close trade action = close [PASS] close trade entry_price = 25000 [PASS] closing already-closed position returns false === 4. Position::open() / Position::close() static methods === [PASS] Position::open() returns array [PASS] Position::open() direction is SELL [PASS] Position::open() entry_price is 40000 [PASS] Position::open() inserts open trade record [PASS] Position::close() returns true [PASS] Position::close() status = closed [PASS] Position::close() exit_price = 38000 [PASS] Position::close() profit = 4000 (SELL) [PASS] Position::close() inserts close trade record [PASS] Position::close() trade exit_price = 38000 [PASS] Position::close() trade profit = 4000 [PASS] Position::close() trade action = close === Summary === Passed: 55 Failed: 0