# VS-05: Risk Metrics — Vertical Slice Specification **Domain:** Risk & Portfolio Management **Capability:** Calculate VAR, Sharpe, Sortino, concentration metrics; publish to dashboard **User Goal:** "I need real-time risk metrics to monitor portfolio health and trigger alerts" --- ## Non-Goals - Stress testing scenarios (VS-06) - Risk alerts & notifications (VS-07) - Factor decomposition (future) - Machine-learning risk modeling (future) --- ## Requirements ### Functional | Req ID | Description | RBAC | SLA | Evidence | |--------|-------------|------|-----|----------| | **RISK-001** | GET /api/portfolio/{id}/risk | DataReader | <200ms | JSON w/ VAR/Sharpe/Sortino | | **RISK-002** | Calculate VAR (95% confidence, 1-day horizon) | System | <5s | Daily batch job | | **RISK-003** | Calculate Sharpe ratio (252-day rolling) | System | <5s | Daily batch job | | **RISK-004** | Concentration metrics (top-N holdings %) | System | <1s | Cache-friendly calculation | | **RISK-005** | Publish metrics to outbox for downstream | System | <100ms | PortfolioMetricsCalculated event | ### Non-Functional - **Accuracy:** VAR model validated against historical data - **Latency:** Batch calculations <5min, GET response <200ms - **Caching:** Results cached <1hr (metrics refresh daily) - **Audit:** All metric changes traced via CorrelationId --- ## State Transitions ``` Portfolio (Current) — from VS-04 ↓ DailyRiskCalculationJob (9:30 KST, after market open) Risk Metrics Calculated (VAR, Sharpe, Sortino, concentration) ↓ event PortfolioMetricsCalculated event published to outbox ↓ inbox consumer Risk dashboard updated, alerts evaluated (VS-07) ``` **Frequency:** Daily after market open (9:30 KST) **Idempotency:** Same `{portfolio_id, calculation_date, correlation_id}` → no re-run --- ## Data & API Contracts ### GET /api/portfolio/{portfolioId}/risk **Response (200 OK):** ```json { "portfolioId": "550e8400-e29b-41d4-a716-446655440001", "calculationDate": "2026-08-05", "metrics": { "valueAtRisk95": { "amount": 15250.00, "percent": 5.2, "horizon": "1-day", "confidence": 0.95 }, "sharpeRatio": { "ratio": 1.85, "riskFreeRate": 0.045, "rollingDays": 252 }, "sortinoRatio": { "ratio": 2.45, "downsideDeviation": 0.082 }, "concentration": { "topFivePercent": 52.3, "hirschman": 0.18, "maxSinglePosition": 40.0 }, "volatility": { "annualized": 0.185, "rollingDays": 30 } }, "lastUpdate": "2026-08-05T09:30:00Z", "dataQuality": "Complete" } ``` ### Events **PortfolioMetricsCalculated:** ```json { "eventId": "550e8400-e29b-41d4-a716-446655440004", "eventType": "PortfolioMetricsCalculated", "portfolioId": "550e8400-e29b-41d4-a716-446655440001", "calculatedAt": "2026-08-05T09:30:00Z", "metrics": { "var95": 15250.00, "sharpe": 1.85, "sortino": 2.45, "concentration": 52.3 }, "correlationId": "risk-2026-08-05-001" } ``` --- ## RBAC & Authorization | Operation | Role | Condition | |-----------|------|-----------| | VIEW metrics | DataReader | Own portfolio only | | TRIGGER calculation | RiskAnalyst | Manual override (unusual) | | APPROVE metrics | RiskCommittee | For reporting purposes | --- ## Testing Strategy 1. **Unit:** Metric calculations (15 tests) - VAR computation (95% confidence) - Sharpe ratio (rolling 252-day) - Sortino ratio (downside deviation) - Concentration detection 2. **Integration:** DB persistence (4 tests) - Insert risk metrics snapshot - Historical metric queries - Event published to outbox - Idempotency check 3. **E2E:** API flow (2 tests) - GET /risk returns current metrics - Daily job execution completes 4. **Golden:** Metric accuracy (3 tests) - Known portfolio → expected VAR/Sharpe - High concentration → concentration flag - Low volatility → low Sharpe --- ## Assumptions - Historical price data available (from VS-03) - Risk-free rate 4.5% (configurable) - 252 trading days per year - No intraday rebalancing (EOD snapshot only) - VAR model: Parametric (assumes normal distribution) --- ## Vertical Slice Boundary ✅ **In Scope:** Metric calculations + API endpoint + daily batch job + event publishing ❌ **Out of Scope:** Stress testing (VS-06), alerts (VS-07), risk approval workflows **Rationale:** Metrics feed downstream systems (dashboard, alerts); published asynchronously via events