"""Integration test: order -> portfolio tracker -> position state.""" import sys from pathlib import Path sys.path.insert( 0, str(Path(__file__).resolve().parents[2] / "services" / "portfolio-manager" / "src") ) from decimal import Decimal from portfolio_manager.portfolio import PortfolioTracker from shared.models import Order, OrderSide, OrderStatus, OrderType def test_portfolio_tracks_buy_sell_cycle(): """Buy then sell should update position and reset on full sell.""" tracker = PortfolioTracker() buy_order = Order( signal_id="sig-1", symbol="AAPL", side=OrderSide.BUY, type=OrderType.MARKET, price=Decimal("50000"), quantity=Decimal("0.1"), status=OrderStatus.FILLED, ) tracker.apply_order(buy_order) pos = tracker.get_position("AAPL") assert pos is not None assert pos.quantity == Decimal("0.1") assert pos.avg_entry_price == Decimal("50000") sell_order = Order( signal_id="sig-2", symbol="AAPL", side=OrderSide.SELL, type=OrderType.MARKET, price=Decimal("55000"), quantity=Decimal("0.1"), status=OrderStatus.FILLED, ) tracker.apply_order(sell_order) pos = tracker.get_position("AAPL") assert pos is None # Fully sold def test_portfolio_weighted_average_on_multiple_buys(): """Multiple buys at different prices should compute weighted average.""" tracker = PortfolioTracker() tracker.apply_order( Order( signal_id="s1", symbol="AAPL", side=OrderSide.BUY, type=OrderType.MARKET, price=Decimal("50000"), quantity=Decimal("0.1"), status=OrderStatus.FILLED, ) ) tracker.apply_order( Order( signal_id="s2", symbol="AAPL", side=OrderSide.BUY, type=OrderType.MARKET, price=Decimal("60000"), quantity=Decimal("0.1"), status=OrderStatus.FILLED, ) ) pos = tracker.get_position("AAPL") assert pos.quantity == Decimal("0.2") assert pos.avg_entry_price == Decimal("55000") # weighted avg