feat(pnl): trade history + realized PnL API (WAC) — BAT-017, REQ-039~042 Implemented

- GET /v1/portfolios/{id}/trades and GET /v1/portfolios/{id}/pnl/realized endpoints
- Weighted Average Cost (WAC) realized PnL calculation in app/domain/pnl.py
- cost_basis and data_completeness_warning returned in pnl API response
- Test coverage: 50 passed (WAC 20 + trades 12 + pnl 18), full 427 passed regression ✓
- WAC validated against 199,300 unit e2e test cases
- DB migration: none required
- QC: qc-reviewer PASS-WITH-NOTES; team lead confirm-batch-verification → release-candidate
- Remaining non-blocking: symbol filter edge case testing, HTTP_422 deprecation

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VHtM5Ws1HKCKQ4JGi6GRb5
This commit is contained in:
2026-06-18 16:45:01 +09:00
co-authored by Claude Opus 4.8
parent f37ef87c8c
commit bd34450ee9
19 changed files with 2034 additions and 10 deletions
+16
View File
@@ -250,6 +250,22 @@ class PortfolioRepository(Protocol):
def list_recent_trades(self, portfolio_id: str, limit: int = 5) -> list[LedgerEntry]: ...
def list_trades_by_date(
self,
portfolio_id: str,
*,
date: datetime | None = None,
from_: datetime | None = None,
to_: datetime | None = None,
) -> list[LedgerEntry]: ...
def get_all_trades_for_pnl(
self,
portfolio_id: str,
*,
symbol: str | None = None,
) -> list[LedgerEntry]: ...
def insert_ledger_trade(
self,
*,