From 8c11cae987292421840658585c0667706790c8ca Mon Sep 17 00:00:00 2001 From: TheSiahxyz <164138827+TheSiahxyz@users.noreply.github.com> Date: Wed, 1 Apr 2026 17:15:23 +0900 Subject: feat(portfolio): add periodic portfolio snapshots and daily Telegram summary --- services/portfolio-manager/tests/test_snapshot.py | 67 +++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 services/portfolio-manager/tests/test_snapshot.py (limited to 'services/portfolio-manager/tests/test_snapshot.py') 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() -- cgit v1.2.3