summaryrefslogtreecommitdiff
path: root/services/portfolio-manager/tests/test_portfolio.py
diff options
context:
space:
mode:
Diffstat (limited to 'services/portfolio-manager/tests/test_portfolio.py')
-rw-r--r--services/portfolio-manager/tests/test_portfolio.py66
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")