portfolio-research

전술적 자산배분 재설계 — 설계 문서

2026-08-17 · 상태: 설계 확정, 구현 전


0. 왜 이걸 하는가

이 저장소의 VAA 서브시스템을 재검토하다가 두 가지가 나왔다.

하나는 버그였다. RiskAnalyzer 가 월별 수익률을 일별(252)로 연율화해 Sharpe 가 20.9배, 변동성이 4.58배 부풀어 있었다. 화면에 변동성 40% · 최대낙폭 17% 가 나란히 찍히는데도 오래 남아 있었다. 수정 완료(b9043d7).

다른 하나는 버그가 아니었다. VAA-G4 는 2011~2026 에 CAGR 6.12% 인데, 논문 정의대로 독립 재구현해 대조하니 6.90% 로 근사 오차 안이었다. 구현이 맞다는 뜻이다.

원인은 실측으로 갈렸다.

구간 비중 연율
방어 55.0% 2.41%
공격 45.0% 10.84%

SHY 한 종목에 44개월(24.4%) 동안 연 0.05% 로 묶였다. 같은 기간 SPY 바이앤홀드는 15.68% 다. 논문의 연 16~17% 는 1970~2015 구간 값이고, 그 시절 방어 자산은 8~15% 를 줬다. 구현이 아니라 전제가 이 시대와 안 맞는다.

목표: MDD 한도 안에서 수익을 최대화하는 전술적 배분을 찾되, 찾지 못했다는 결론도 기록으로 남긴다.


1. 왜 VAA 가 오발했는가 — 진단

VAA-G4 의 방어 판정은 “공격 4자산(SPY·EFA·EEM·AGG) 중 하나라도 13612W 가 음수면 전액 방어” 다.

문제는 공격 4자산이 투자 대상이자 동시에 경보기라는 점이다. 2011~2026 에 EEM·EFA 는 만성적으로 약했고, 그래서 살 생각도 없던 자산의 약세가 포트폴리오 전체를 방어로 밀어냈다. 그동안 SPY 는 올랐다.

Keller 본인이 이 문제를 인정하고 두 번 고쳤다.

연도 전략 무엇을 바꿨나
2017 VAA (문제의 원형)
2018 DAA canary universe — 경보기를 투자 대상에서 분리. 논문 목적이 명시적으로 “평균 현금 비중을 낮추되 붕괴 방어는 유지”
2022 BAA canary + 별도 공격군 + 확장 방어군 + 선택 지표 교체
2023 HAA 인플레이션·금리 상승기 대응

DAA 의 존재 자체가 우리 진단의 독립 확인이다.


2. 아키텍처

2.1 위치

CLAUDE.md 의 격리 규칙은 factor/strategies/·analysis/·core/ 를 나눈다. 새 전략은 ETF 배분이라 어느 쪽도 아니고, DSR/PBO 관문은 factor/research/overfitting.py 에 있다.

src/opt_portfolio/taa/
├── data.py        # Sharadar 펀드 벌크 → 가격 패널
├── universe.py    # canary·공격·방어 유니버스 선언
├── signals.py     # 13612W · SMA13 상대모멘텀 · breadth 판정
├── strategy.py    # 전략을 선언적 스펙 객체로
└── backtest.py    # 월별 리밸런싱 엔진

의존은 둘만 허용한다:

격리 규칙에 이 예외를 CLAUDE.md 에 명시 기록한다. 규칙을 조용히 어기지 않는다.

기존 strategies/vaa.py건드리지 않는다. 구현이 논문과 맞는 것을 확인했으므로 기준선 비교 대상으로 남긴다. README 의 틀린 수치만 고친다.

2.2 데이터

yfinance 가 아니라 로컬 Sharadar 펀드 벌크를 쓴다.

선행 검사(생략 불가): 배당조정 여부를 실측 확인한다. closeadj 인지 close 인지 확인하지 않으면 채권 ETF 수익이 통째로 틀린다. yfinance 경로에서 auto_adjust=True 를 확인했던 것과 같은 검사다.

커버리지 실측 (2026-08-14 기준, 19종목 전부 존재):

티커 시작
SPY·EWJ 1997-12-31
QQQ 1999-03-10
IWM 2000-05-26
EFA 2001-08-27
IEF·LQD·TLT 2002-07-30
EEM 2003-04-14
AGG 2003-09-29
TIP 2003-12-05
VNQ 2004-09-29
GLD 2004-11-18
VGK·VWO 2005-03-10
DBC 2006-02-06
BND·HYG 2007-04
BIL 2007-05-30 ← 공통 구간 제약

3. 기준선

DAA 는 구현하지 않는다. 규칙을 정확히 확보하지 못했고(출처 404), VAA→BAA 중간 단계라 기준선으로서 추가 정보가 적다. 명세를 확인하지 못한 것을 구현하지 않는다CLAUDE.md §4 의 연장이다.

3.1 SPY 바이앤홀드 — 참고

CAGR 은 높지만 MDD −34% 로 제약을 위반한다. 채택 후보가 아니라 눈금이다.

3.2 60/40 정적 (SPY/IEF, 연 1회 리밸런싱) — 실질 기준선

MDD 가 −20% 대이고 아무 판단도 하지 않는다. 이걸 못 이기면 전술적 배분은 존재 이유가 없다.

3.3 VAA-G4 — 현행

이미 논문 대조를 마쳤다.

3.4 BAA (Keller 2022)

요소 내용
카나리아 SPY · EFA · EEM · AGG — 13612W
판정 카나리아 전부 양수 → 공격, 하나라도 음수 → 방어
공격군 aggressive: QQQ·EEM·EFA·AGG 중 1종목 / balanced: SPY·QQQ·IWM·VGK·EWJ·EEM·VNQ·DBC·GLD·TLT·HYG·LQD 중 6종목
방어군 TIP·DBC·BIL·IEF·TLT·LQD·AGG 중 3종목
선택 지표 p0 / SMA13 (13개월 이동평균 대비) — 13612W 가 아니다
방어 시 BIL 을 못 이기는 자산은 제외하고 현금 (dual momentum)
비중·주기 균등가중 · 월말 리밸런싱

두 가지 분리가 핵심이다. ① 경보기와 투자 대상의 분리 — EEM·EFA 약세가 더 이상 포트폴리오를 끌어내리지 않는다. ② 경보는 빠르게(13612W), 선택은 느리게(SMA13). 그리고 BIL 대비 dual momentum 이 “SHY 를 연 0.05% 로 26.7% 보유” 문제를 직접 겨냥한다.


4. 사전 등록 — 총 9개 구성

이 목록을 구현 전에 커밋하고, 이후 늘리지 않는다. 늘리면 DSR 에 정산되지 않는 탐색이 되고, 그것이 이 저장소가 이미 지고 있는 부채다 (07-experiment-log.md §6 — “124개를 훑어 고른 행위 자체는 정산되지 않았다”).

# 구성 성격
1 SPY 바이앤홀드 참고 (제약 위반)
2 60/40 정적 실질 기준선
3 VAA-G4 현행
4 BAA-aggressive 논문
5 BAA-balanced 논문
6 BAA-agg + 200일 이평 개선안
7 BAA-bal + 200일 이평 개선안
8 BAA-bal + 리밸런싱 트랜치 개선안
9 BAA-bal + 이평 + 트랜치 개선안

n_trials = 9.

개선안을 둘로 제한한 이유

근거가 우리 실측이거나 문서화된 약점인 것만 넣었다.

카나리아 구성 변경, 모멘텀 가중치 조정, 보유 종목 수 탐색은 넣지 않는다. 근거가 없고 낚시다.


5. 검증 프로토콜

walk-forward 를 쓰지 않는다. 팩터 엔진이 그것을 쓰는 이유는 학습 구간 안에서 파라미터를 고르기 때문인데, VAA·BAA 는 명세가 주어지면 맞출 파라미터가 없다. 여기서의 탐색은 9개 구성 중 하나를 고르는 것이고, 다른 도구가 다룬다.

관문 역할
PBO (CSCV) — 주 관문 조합적 분할로 “인샘플 1등이 아웃샘플에서 중간 이하로 떨어질 확률” 을 잰다. 구성 선택이 곧 탐색인 상황에 정확히 대응한다
DSR (n_trials=9) 선택된 것의 Sharpe 를 시도 횟수로 할인
구간별 분해 2008 · 2020 · 2022 — 방어가 필요할 때 실제로 작동했는가
timing luck 리밸런싱일을 월중 1~21일로 바꿔가며 성과 분산 측정. 같은 전략의 강건성 검사라 시도 횟수에 넣지 않는다
비용 민감도 왕복 10bps 기본, 30bps 재확인. ETF 라 초소형주보다 작지만 0 으로 두지 않는다

도구 실측 확인 (2026-08-17)

스펙이 코드보다 앞서가지 않도록 두 함수를 직접 확인했다.

두 번째 항목은 함정이다. 이 저장소는 연율화 주기를 두 번 틀렸다 (§2.1 DSR 단위 버그, 그리고 이번 RiskAnalyzer). 구현할 때 세 번째를 만들지 않는다.

측정 구간

  구간 개월
공통 (전 구성 비교) 2007-06 ~ 2026-08 230
VAA-G4 보조 2003-10 ~ 2026-08 275

공통 구간에 2008 · 2020 · 2022 세 번의 하락이 전부 들어간다. 현행 15년 백테스트에는 피할 붕괴가 없었다.


6. 채택 기준 — 미리 확정

MDD ≤ 20%
AND DSR ≥ 0.95 (n_trials = 9)
AND Calmar > 60/40 의 Calmar   (부트스트랩 신뢰구간이 0 을 포함하지 않을 것)

셋 중 하나라도 못 넘으면 채택 없음으로 끝낸다. 그 결론도 기록한다.


7. 결과 전 예상

이 저장소 규율대로 미리 못 박는다. 결과를 보고 기준을 정하지 않기 위해서다.

  1. BAA > VAA — 카나리아 분리가 오발을 줄일 것. 비교적 확신한다.
  2. 200일 이평은 효과가 없거나 마이너스 — BAA 의 카나리아가 이미 추세를 판정한다. 필터를 이중으로 걸면 더 방어적이 되어 VAA 의 병을 재발시킬 수 있다.
  3. 트랜치는 CAGR 을 거의 안 바꾸고 Calmar 를 조금 올린다.
  4. 어느 것도 CAGR 로 SPY 를 못 이긴다. 승부는 MDD 제약 하의 Calmar 에서 난다.
  5. 60/40 을 이기는 것이 진짜 관문이다. 못 이기면 전부 기각.

8. 알려진 한계 — 결과와 함께 적는다

표본이 얇다. 공통 구간 230개월이고 그 안의 하락은 세 번뿐이다.

“붕괴 방어가 작동한다”는 주장은 사건 3개에 근거하게 된다. 월별 전략에서 230개 관측은 DSR·PBO 를 태우기에 넉넉하지 않다.

이것을 결과 뒤에 각주로 붙이지 않고 결과와 같은 자리에 적는다. 표제 숫자가 방어 장치를 끈 산물이었던 일을 겪었으므로, 한계를 분리해 두지 않는다.

그 밖에: