- Add WalkForwardResult model with train/test window metrics
- Create WalkForwardEngine that reuses existing BacktestEngine
with rolling train/test window splits
- Add POST/GET /api/backtest/{id}/walkforward endpoints
- Add Walk-forward tab to backtest detail page with parameter
controls, cumulative return chart, and window results table
- Add Alembic migration for walkforward_results table
- Add 8 unit tests for window generation logic (100 total passed)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add dc_only parameter to all strategy endpoints. When true, filters
results to include only tickers present in the ETF table, supporting
DC pension investment constraints where only ETFs are allowed.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add min_trade_amount parameter (default 10,000 KRW) to rebalance/calculate
endpoint. Trades below this threshold are converted to hold actions to avoid
inefficient micro-trades during rebalancing.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add realized_pnl column to transactions table with alembic migration
- Calculate realized PnL on sell transactions: (sell_price - avg_price) * quantity
- Show total realized/unrealized PnL in portfolio detail summary cards
- Show per-transaction realized PnL in transaction history table
- Add position sizing API endpoint (GET /portfolios/{id}/position-size)
- Show position sizing guide in signal execution modal for buy signals
- 8 new E2E tests, all 88 tests passing
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Phase 1 (Critical):
- Add bulk rebalance apply API + UI with confirmation modal
- Add strategy results to portfolio targets flow (shared component)
Phase 2 (Important):
- Show current holdings in signal execute modal with auto-fill
- Add DC pension risk asset ratio warning (70% limit)
- Add KOSPI benchmark comparison to portfolio returns
- Track signal execution details (price, quantity, timestamp)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Allow users to execute active KJB signals by selecting a portfolio,
entering quantity and price, then creating the corresponding transaction
and updating holdings. Signal status changes to 'executed' after completion.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The portfolio API was returning only ticker symbols (e.g., "095570")
without stock names. The Stock table already has Korean names
(e.g., "AJ네트웍스") from data collection.
Backend: Add name field to HoldingWithValue schema, fetch stock names
via RebalanceService.get_stock_names() in the portfolio detail endpoint.
Frontend: Show Korean stock name as primary label with ticker as
subtitle in portfolio detail, donut charts, and target vs actual
comparison. Dashboard donut chart also shows names.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Pydantic v2's model_dump(mode="json") serializes Decimal as strings (e.g.,
"33.33" instead of 33.33), causing frontend crashes when calling .toFixed()
on string values. Introduced FloatDecimal type alias with PlainSerializer
to ensure Decimal fields are serialized as floats in JSON responses.
Also fixed frontend Transaction interface to match backend field names
(created_at → executed_at, transaction_type → tx_type).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>