# Portfolio and Risk Model

## 1. 목적

백테스트에서 포트폴리오/리스크 모델은 전략보다 덜 중요해 보이지만,
실제로는 결과의 분포와 낙폭을 결정하는 핵심입니다.

Phase 4에서는 아래 3가지를 반드시 반영합니다.

1. **per-trade risk budget**
2. **portfolio-level exposure / concentration limits**
3. **kill-switch style risk guardrails**

## 2. 기본 정책

Phase 0의 risk policy를 그대로 따릅니다.
기본 예시:

- 거래당 계좌 리스크: 0.25% ~ 0.50%
- 하루 총 신규 리스크: 1.0% 이하
- 동시 최대 포지션: 3개
- 같은 섹터 최대 포지션: 2개
- 연속 손실 임계치 도달 시 신규 진입 제한

Phase 4 구현은 이 규칙을 config로 표현하되, default는 위 정책을 사용합니다.

## 3. sizing 모델

### 3.1 Risk-based sizing

기본 공식:

```text
risk_dollars = equity * per_trade_risk_pct
per_share_risk = entry_price - stop_price
shares = floor(risk_dollars / per_share_risk)
```

추가 제약:

- `shares * entry_price <= available_cash`
- `shares <= max_position_value_pct * equity / entry_price`
- `shares`는 최소 lot 이상

### 3.2 Value cap

risk-based sizing이 너무 커질 수 있으므로 별도 상한을 둡니다.

예:
- single position max gross exposure = 20% equity

### 3.3 Liquidity cap

무료 데이터 기반 전략은 시가총액/평균거래대금 필터가 있어도,
개별 거래가 지나치게 큰 비중을 차지하지 않도록 cap을 둡니다.

예:
- position value <= ADV dollar volume의 1% 미만

## 4. portfolio entry gates

신규 포지션 진입은 아래 순서로 판단합니다.

1. global kill switch 확인
2. portfolio max positions 확인
3. sector max positions 확인
4. duplicate symbol / issuer check
5. daily risk budget 확인
6. available cash / margin proxy 확인
7. liquidity cap 확인

하나라도 실패하면 skip하고 이유 코드를 남깁니다.

## 5. stop / target 규칙

### 5.1 Initial stop

v1 기본:

- `min(reaction_day_low breach rule, atr_multiple rule)` 대신
- 구현 단순화를 위해 config에서 하나만 mandatory로 선택
- 기본값: `reaction_day_low` 또는 `entry_price - 1.0 * ATR20`

주의: Phase 4에서 stop 정의는 Phase 3 label 정의와 충돌하면 안 됩니다.

### 5.2 Take-profit

기본값:
- `target_1_r_multiple = 1.5`
- `target_1_fraction = 0.5`

### 5.3 Trailing stop

기본값:
- `previous_day_low_breach`
- daily bar 근사로 구현

### 5.4 Time exit

기본값:
- `max_holding_days = 3 or 5`
- 해당 거래일 종가 청산

## 6. regime filters

포트폴리오 엔진은 레짐이 불리할 때 신규 진입을 줄이거나 막을 수 있어야 합니다.

예시:
- risk_off면 신규 포지션 수 50% 축소
- VIX 급등일에는 신규 진입 금지
- SPY trend down + sector weak면 후보 탈락

이 규칙은 signal ranking 전에 적용할 수도 있고,
portfolio allocation 단계에서 gating rule로 적용할 수도 있습니다.

v1에서는 gating rule로 구현하는 편이 단순합니다.

## 7. drawdown-based controls

백테스트에서도 아래 risk guardrails를 반영합니다.

- strategy drawdown > X%면 신규 진입 중단
- rolling loss streak >= N이면 cooldown days 적용
- daily equity drawdown > Y%면 당일 추가 진입 금지

이 기능은 live paper trading과 동일한 인터페이스로 구현해 두는 것이 좋습니다.

## 8. cash ledger

기본 백테스터는 margin-like 단순 cash ledger로 충분합니다.
하지만 아래 필드는 명시적으로 유지합니다.

- `cash_available`
- `gross_exposure`
- `net_exposure`
- `reserved_risk_budget`
- `unrealized_pnl`
- `realized_pnl`

나중에 cash account 전용 satellite 전략을 넣을 때 재사용할 수 있어야 합니다.

## 9. attribution-friendly logging

모든 진입/거절/청산은 아래 정보를 남겨야 합니다.

- accepted/rejected reason
- sizing inputs
- stop distance
- sector gate result
- regime gate result
- portfolio slot usage

그래야 나중에 “전략이 나빴는지, 포트폴리오 제약이 성과를 깎았는지” 구분할 수 있습니다.

## 10. 추천 config 키

```yaml
risk:
  per_trade_risk_pct: 0.0035
  max_daily_new_risk_pct: 0.01
  max_positions: 3
  max_positions_per_sector: 2
  max_position_value_pct: 0.20
  max_adv_fraction: 0.01
  cooldown_after_loss_streak: 3
  cooldown_days: 2
exits:
  stop_model: reaction_day_low
  atr_multiple: 1.0
  target_1_r: 1.5
  target_1_fraction: 0.5
  trailing_model: previous_day_low
  max_holding_days: 3
regime:
  block_on_vix_spike: true
  reduce_slots_in_risk_off: true
```
