# Phase Segmentation: Bull/Bear/Sideways/Volatility Analysis (AGENTS.md v16.0) ## 1. SOURCE (Requirements) **From README.md:** - "복수 국면 OOS" (Multiple market phase out-of-sample validation) **From research/K-ArtSell_12_2_quant_review_ko.md:** - Strategy performance varies by market regime - Bull/Bear/Sideways/Volatility phases require separate analysis - Robustness proof: positive returns across all phases **From CLAUDE.md:** - § "Validation Gates": Phase breakdown with separate metrics - § "Shadow Run Design": PhaseBreakdown record with Bull/Bear/Sideways/HighVolatility **Business Logic:** - Strategy must work across **all market conditions** - Failure in any phase → production rejection - PBO/DSR must hold in **each phase independently** --- ## 2. SLICE SPEC (Vertical Slice) ### Goal Segment shadow run portfolio returns by market regime; compute phase-specific metrics. ### Non-Goal - Real-time regime detection (historical only) - Regime switching strategy (static classification) - Multi-period lookahead (single-period PIT) ### Workflow 1. **Input:** Daily returns + trading sessions (shadow run replay result) 2. **Detect regimes:** Classify each day into Bull/Bear/Sideways/Volatility - Bull: 30-day MA trending up - Bear: 30-day MA trending down - Sideways: 30-day MA flat (±5% band) - Volatility: Realized volatility > 2σ 3. **Aggregate:** Group returns by regime 4. **Calculate:** Per-regime metrics (Sharpe, Calmar, Max DD, Win Rate) 5. **Output:** PhaseMetrics{TradingDays, Return%, Sharpe, WinRate, MaxDD} --- ## 3. CONTRACT (Input/Output/Status) ### Input ```csharp ReplayResult { DailyReturns: List<(DateOnly, decimal)>, PortfolioHistory: List } OHLCV Bars { Date, Ticker, Close, Volume } ``` ### Output ```csharp PhaseBreakdown { BullMarket: PhaseMetrics, BearMarket: PhaseMetrics, Sideways: PhaseMetrics, HighVolatility: PhaseMetrics } PhaseMetrics { TradingDays: int, Return: decimal, Sharpe: decimal, WinRate: decimal, MaxDrawdown: decimal } ``` ### Idempotency - **Same input** → same regime classification (deterministic) - **PIT safety:** No lookahead bias (classify using data available at time t only) ### Error Handling | Scenario | Action | |----------|--------| | No bull days | PhaseMetrics with TradingDays=0 | | Insufficient data for Sharpe | Return default 0m | | Single-day regime | Skip (Sharpe undefined) | --- ## 4. DATA (Schema + Calculation) ### Regime Classification Logic ``` For each trading day t: price_30d_ma = EMA(close[t-30:t], span=30) IF price_30d_ma trending up (slope > 0 for last 5 days) CLASSIFY: Bull ELSE IF price_30d_ma trending down (slope < 0 for last 5 days) CLASSIFY: Bear ELSE IF ABS(price - price_30d_ma) / price_30d_ma < 0.05 CLASSIFY: Sideways ELSE IF realized_vol[t] > mean_vol + 2*std_vol CLASSIFY: HighVolatility ELSE CLASSIFY: Sideways (default) ``` ### Metrics Calculation (Per Phase) ```sql -- Phase 1: Collect returns by regime phase_returns = filter(daily_returns, regime == phase) -- Phase 2: Calculate metrics total_return = (product(1 + r for r in phase_returns) - 1) sharpe = mean(phase_returns) / std(phase_returns) * sqrt(252) win_rate = count(r > 0) / len(phase_returns) max_dd = calculate_max_drawdown(cumulative_returns) calmar = total_return / max_dd ``` ### Storage - No database persistence (computed on-demand) - Included in `ShadowRunResult.phase_analysis_json` - Immutable after shadow run completion --- ## 5. TESTS (Verification) ### Unit Tests | Test | Scenario | Expected | |------|----------|----------| | Regime_BullTrend | 30-day MA rising consistently | All days → Bull | | Regime_BearTrend | 30-day MA falling consistently | All days → Bear | | Regime_Sideways | Price oscillates ±5% around MA | All days → Sideways | | Regime_HighVolatility | Realized vol > mean + 2σ | All days → HighVolatility | | Metrics_SinglePhase | All returns in Bull phase | Sharpe ≤ 5, WinRate [0,1] | | Metrics_MultiPhase | Mixed returns across phases | Each phase computed separately | | Metrics_EmptyPhase | No returns in Bear phase | TradingDays=0, Return=0 | ### Integration Tests | Test | Scenario | Expected | |------|----------|----------| | PhaseBreakdown_SumsDays | Sum(TradingDays across phases) | = Total trading days | | PhaseBreakdown_Consistency | Bull + Bear + Sideways + Vol days | = Portfolio history length | | PhaseBreakdown_NoLookahead | Regime known only from t-30 data | Classification deterministic | ### Data Tests | Test | Scenario | Expected | |------|----------|----------| | Sharpe_Calculation | Known returns + vol | Matches manual calculation | | MaxDD_Calculation | Simulated drawdown sequence | Matches cumulative peak-to-trough | --- ## 6. OPS (Deployment + Monitoring) ### Startup - Phase segmentation runs **after replay** (inside ShadowRunJob) - No external dependencies (uses replay results + OHLCV bars from backfill) - Deterministic: No randomness, no API calls ### Monitoring - Alert if any phase has 0 trading days (data gap) - Alert if Sharpe calculation fails (log error, use default 0) - Metrics validation: WinRate ∈ [0,1], Sharpe ∈ [-5,5] ### Rollback - Phase segmentation is read-only compute (no state changes) - If calculation fails: return zeros for that phase - Job continues (non-blocking) --- ## 7. OUTPUT RULE (Deliverables) **Changed files:** ``` src/KArtSell.Modules.ModelOperations/ ShadowRun/ PhaseSegmentation.cs (Main calculator) RegimeClassifier.cs (Bull/Bear/Sideways/Vol logic) PhaseMetricsCalculator.cs (Sharpe, Calmar, etc.) tests/KArtSell.Integration.Tests/ PhaseSegmentationTests.cs (Unit tests) PhaseSegmentationIntegrationTests.cs (Integration tests) ``` **Verification:** ```bash dotnet test --filter "PhaseSegmentation" -c Release # Expected: All tests green ``` --- ## 8. AGENTS.md v16.0 CHECKLIST | Criterion | Status | Evidence | |-----------|--------|----------| | **SOLID** | ✅ Design | RegimeClassifier (single responsibility), DI ready | | **Complexity** | ✅ Design | Regime logic cyclomatic < 10, metrics calc < 10 | | **Audit** | ✅ Design | PIT safety: classify using only historical data | | **Necessity** | ✅ Sourced | README.md: "복수 국면 OOS" requirement | | **Normalization** | ✅ Design | Read-only compute, immutable output in JSONB | | **Simplicity** | ✅ Design | Clear regime rules, deterministic classification | | **Pattern** | ✅ Design | Vertical component (Segmenter → Classifier → Metrics) | | **Guardrails** | ✅ Design | No lookahead, error handling (empty phases), bounds checking | | **Traceability** | ✅ Design | Regime per-day logged, metrics tagged with phase name | | **Safety** | ✅ Design | Idempotent (same input = same regime), read-only | | **Maturity** | ✅ Design | Contract → Test → Implementation sequencing | | **Right Way** | ✅ Design | PIT-safe classification, no shortcuts | | **Debt** | ✅ Design | Zero new tech debt, uses existing infrastructure | --- ## NEXT STEPS (Sequenced) ### Step 1: RegimeClassifier - Implement regime detection logic (Bull/Bear/Sideways/Vol) - Unit tests: Each regime type ### Step 2: PhaseMetricsCalculator - Calculate Sharpe, Calmar, Max DD, Win Rate per phase - Unit tests: Metric calculations ### Step 3: PhaseSegmentation (Orchestrator) - Integrate classifier + metrics calculator - Integration tests: Full phase breakdown ### Step 4: ShadowRunJob Integration - Call PhaseSegmentation after MetricsCalculator - Populate result.PhaseAnalysis - Tests: End-to-end shadow run with phase breakdown ### Step 5: Validation - Build passes, tests 100% green - Commit & push