diff options
Diffstat (limited to 'services/portfolio-manager/tests/test_portfolio.py')
| -rw-r--r-- | services/portfolio-manager/tests/test_portfolio.py | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/services/portfolio-manager/tests/test_portfolio.py b/services/portfolio-manager/tests/test_portfolio.py index 92ff6ca..5a7ac64 100644 --- a/services/portfolio-manager/tests/test_portfolio.py +++ b/services/portfolio-manager/tests/test_portfolio.py @@ -56,3 +56,69 @@ def test_portfolio_no_position_returns_none() -> None: tracker = PortfolioTracker() position = tracker.get_position("ETH/USDT") assert position is None + + +def test_realized_pnl_on_sell() -> None: + """Selling should track realized PnL.""" + tracker = PortfolioTracker() + + # Buy at 50000 + tracker.apply_order(Order( + signal_id="s1", symbol="BTCUSDT", side=OrderSide.BUY, + type=OrderType.MARKET, price=Decimal("50000"), + quantity=Decimal("0.1"), status=OrderStatus.FILLED, + )) + assert tracker.realized_pnl == Decimal("0") + + # Sell at 55000 — profit of 500 + tracker.apply_order(Order( + signal_id="s2", symbol="BTCUSDT", side=OrderSide.SELL, + type=OrderType.MARKET, price=Decimal("55000"), + quantity=Decimal("0.1"), status=OrderStatus.FILLED, + )) + assert tracker.realized_pnl == Decimal("500") + + +def test_realized_pnl_on_loss() -> None: + """Selling at a loss should track negative realized PnL.""" + tracker = PortfolioTracker() + + tracker.apply_order(Order( + signal_id="s1", symbol="BTCUSDT", side=OrderSide.BUY, + type=OrderType.MARKET, price=Decimal("50000"), + quantity=Decimal("0.1"), status=OrderStatus.FILLED, + )) + tracker.apply_order(Order( + signal_id="s2", symbol="BTCUSDT", side=OrderSide.SELL, + type=OrderType.MARKET, price=Decimal("45000"), + quantity=Decimal("0.1"), status=OrderStatus.FILLED, + )) + assert tracker.realized_pnl == Decimal("-500") + + +def test_realized_pnl_accumulates() -> None: + """Multiple sells accumulate realized PnL.""" + tracker = PortfolioTracker() + + # Buy 0.2 at 50000 + tracker.apply_order(Order( + signal_id="s1", symbol="BTCUSDT", side=OrderSide.BUY, + type=OrderType.MARKET, price=Decimal("50000"), + quantity=Decimal("0.2"), status=OrderStatus.FILLED, + )) + + # Sell 0.1 at 55000 -> +500 + tracker.apply_order(Order( + signal_id="s2", symbol="BTCUSDT", side=OrderSide.SELL, + type=OrderType.MARKET, price=Decimal("55000"), + quantity=Decimal("0.1"), status=OrderStatus.FILLED, + )) + + # Sell 0.1 at 60000 -> +1000 + tracker.apply_order(Order( + signal_id="s3", symbol="BTCUSDT", side=OrderSide.SELL, + type=OrderType.MARKET, price=Decimal("60000"), + quantity=Decimal("0.1"), status=OrderStatus.FILLED, + )) + + assert tracker.realized_pnl == Decimal("1500") |
