summaryrefslogtreecommitdiff
path: root/services/portfolio-manager/tests/test_snapshot.py
diff options
context:
space:
mode:
authorTheSiahxyz <164138827+TheSiahxyz@users.noreply.github.com>2026-04-01 17:15:23 +0900
committerTheSiahxyz <164138827+TheSiahxyz@users.noreply.github.com>2026-04-01 17:15:23 +0900
commit8c11cae987292421840658585c0667706790c8ca (patch)
tree5ab5571bf1bdc36e3ae3a09c0c29f49ca74c1135 /services/portfolio-manager/tests/test_snapshot.py
parenta6bf0057d32df7ed0a1d6ec6d19daf74a0de5c0f (diff)
feat(portfolio): add periodic portfolio snapshots and daily Telegram summary
Diffstat (limited to 'services/portfolio-manager/tests/test_snapshot.py')
-rw-r--r--services/portfolio-manager/tests/test_snapshot.py67
1 files changed, 67 insertions, 0 deletions
diff --git a/services/portfolio-manager/tests/test_snapshot.py b/services/portfolio-manager/tests/test_snapshot.py
new file mode 100644
index 0000000..89d23d7
--- /dev/null
+++ b/services/portfolio-manager/tests/test_snapshot.py
@@ -0,0 +1,67 @@
+"""Tests for save_snapshot in portfolio-manager."""
+
+import pytest
+from decimal import Decimal
+from unittest.mock import AsyncMock, MagicMock
+
+from shared.models import Position
+
+
+class TestSaveSnapshot:
+ @pytest.mark.asyncio
+ async def test_save_snapshot_saves_to_db_and_notifies(self):
+ from portfolio_manager.main import save_snapshot
+
+ pos = Position(
+ symbol="BTCUSDT",
+ quantity=Decimal("0.5"),
+ avg_entry_price=Decimal("50000"),
+ current_price=Decimal("52000"),
+ )
+
+ tracker = MagicMock()
+ tracker.get_all_positions.return_value = [pos]
+
+ db = AsyncMock()
+ notifier = AsyncMock()
+ log = MagicMock()
+
+ await save_snapshot(db, tracker, notifier, log)
+
+ expected_total = Decimal("0.5") * Decimal("52000") # 26000
+ expected_unrealized = Decimal("0.5") * (Decimal("52000") - Decimal("50000")) # 1000
+
+ db.insert_portfolio_snapshot.assert_awaited_once_with(
+ total_value=expected_total,
+ realized_pnl=Decimal("0"),
+ unrealized_pnl=expected_unrealized,
+ )
+ notifier.send_daily_summary.assert_awaited_once_with(
+ [pos], expected_total, expected_unrealized
+ )
+ log.info.assert_called_once_with(
+ "snapshot_saved",
+ total_value=str(expected_total),
+ positions=1,
+ )
+
+ @pytest.mark.asyncio
+ async def test_save_snapshot_empty_positions(self):
+ from portfolio_manager.main import save_snapshot
+
+ tracker = MagicMock()
+ tracker.get_all_positions.return_value = []
+
+ db = AsyncMock()
+ notifier = AsyncMock()
+ log = MagicMock()
+
+ await save_snapshot(db, tracker, notifier, log)
+
+ db.insert_portfolio_snapshot.assert_awaited_once_with(
+ total_value=Decimal("0"),
+ realized_pnl=Decimal("0"),
+ unrealized_pnl=Decimal("0"),
+ )
+ notifier.send_daily_summary.assert_awaited_once()
+ log.info.assert_called_once()