S313 — 3축 결합 backtest (퀀트 × 차트 × 테마 RS)¶
작성: 2026-05-25 (Mon)
진입 명세: docs/topics/_index.md L43~81 (S313)
결론 한 줄: PM 질문 "차트+퀀트 다 사용했을 때 알파 없는건가?"에 대해, 1시점·81종목·강상승장 환경에서는 quant 단독이 단순 z-score 가산/곱셈 결합보다 우월. 4축 중 시장환경은 단일 cell로 제외 → 실제 3축 결합.
1. 설정¶
| 항목 | 값 | 비고 |
|---|---|---|
| 진입 시점 t0 | 2026-04-06 | EA_QoQ 2025Q4 cutoff (S312v2) |
| Universe | 81 stocks | EA_QoQ 가용 + ohlcv 보유 |
| Forward horizon | D+5 / D+10 / D+20 / D+30 | KOSPI-adjusted alpha |
| 시장 cell | HIGH_HIGH (단일) | L_UP_S_UP_BULL · cross-section 분산 0 → 제외 |
| 결합 산식 | S_sum = z_Q + z_C + z_T, S_prod = z_Q × z_C × z_T | 단일 종목 z-score 표준화 후 |
입력 데이터 (모두 가용 확인)¶
- 퀀트 EA_QoQ z:
data/backtest/e1/decile_stocks.parquet(composite_z 컬럼) - 차트 score:
data/backtest/chart_state/stock_chart_state_2026-04-06.parquet(신규 —scripts/quant/charts/chart_state_score.py) - 테마 RS:
data/backtest/theme_rs/stock_theme_rs_2026-04-06.parquet(신규 —scripts/quant/themes/theme_rs.py) - KOSPI 일봉:
data/dart_cache/kospi_daily.parquet(2026-05-22까지) - 시장 cell map:
data/backtest/lxs_v4c/merged_3axis.parquet(2026-04-06 row)
2. 축별 산출¶
2-1. 퀀트 (Q) — composite_z¶
S312v2 EA_QoQ 결과 그대로. universe 81 내 mean 0 / std 1 재표준화하여 z_Q 사용.
2-2. 차트 (C) — chart_score¶
discovery/state_classifier.classify_state() 호출 → _resolution_direction() 내부 raw score 산식 재구현:
chart_score = phase_bias + net_event_bias × 0.5 + supply_demand × 0.5
+ (bvc_20d - 0.5) × 1.0 + cvd_slope_z × 0.2
+ vsa_net_bias × 0.3 + exhaustion_flags + divergence
2-3. 테마 RS (T) — theme_rs¶
산식:
KOSPI_ret60 (2026-01-06 → 2026-04-06) = +20.44%
theme_avg_ret60 = mean(소속 종목 ret60), cover ≥ 3 종목만 산출
theme_rs = theme_avg_ret60 - KOSPI_ret60
stock_theme_rs_j = mean(j 소속 테마들의 theme_rs)
24종 NaN 원인 (ats_main.json 데이터 결함): | 코드 | 종목 | 사유 | |---|---|---| | 207940 | 삼성바이오로직스 | themes=[] | | 011200 | HMM | themes=[] | | 267250 | HD현대 | themes=[] | | 033780 | KT&G | themes=[] | | 402340 | SK스퀘어 | themes=[] | | 068270 | 셀트리온 | themes=[] | | 003550 | LG | themes=[] | | 196170 | 알테오젠 | themes=[] | | ... (18종 빈 리스트, 6종 단일 테마지만 cover<3) | | |
대상 종목 중 시총 상위 다수가 빠지는 본질적 제약. ats_main.json 테마 매핑 보강이 후속 과제.
2-4. 시장환경 (M, 제외)¶
2026-04-06 시점 cell = HIGH_HIGH 단일. 81 종목 모두 동일 multiplier → cross-section 결합 정보 없음. 명세 4축 중 본 축은 메타만 기록.
3. 결합 backtest 결과¶
3-1. TOP(G8) vs BOTTOM(G1) D+N alpha spread (pp)¶
| 축 | n | d5 | d10 | d20 | d30 |
|---|---|---|---|---|---|
| Q only — full 81 | 81 | +0.80 | -2.67 | +5.65 | +18.15 |
| C only — full 81 | 81 | -2.52 | -1.39 | +10.51 | -1.50 |
| T only — valid 57 | 57 | +3.99 | -0.54 | -6.24 | -6.03 |
| S_sum (Q+C+T) | 57 | +0.54 | -3.57 | -20.62 | -5.93 |
| S_prod (Q×C×T) | 57 | +0.97 | +5.33 | -8.19 | -4.99 |
| Q only — valid 57 (공정비교) | 57 | -2.60 | -8.33 | -13.69 | +7.75 |
| C only — valid 57 (공정비교) | 57 | -2.80 | +4.63 | +18.15 | +15.41 |
3-2. S_sum / S_prod 종목 단위 표본¶
S_sum TOP 5 (이론상 가장 매력적): | 코드 | z_Q | z_C | z_T | S_sum | 실현 D+30 α | |---|---:|---:|---:|---:|---:| | 000720 | +0.19 | +0.80 | +4.66 | 5.65 | -42.6% | | 272210 | +1.31 | +1.28 | +0.57 | 3.16 | -52.6% | | 079550 | +0.69 | +1.35 | +0.22 | 2.27 | -29.4% | | 047040 | -1.76 | -0.38 | +4.34 | 2.20 | +21.7% | | 010950 | +1.49 | +0.94 | -0.32 | 2.11 | -38.4% |
S_sum BOTTOM 5 (이론상 회피): | 코드 | z_Q | z_C | z_T | S_sum | 실현 D+30 α | |---|---:|---:|---:|---:|---:| | 062040 | -0.26 | -0.90 | -0.69 | -1.84 | +46.3% | | 009830 | -5.29 | +0.98 | -0.00 | -4.31 | -27.5% | | 035720 | -0.04 | -1.64 | -1.83 | -3.51 | -42.7% |
TOP 5 평균 D+30 α ≈ -29.3%, BOTTOM 5 ≈ -21.1% → TOP이 오히려 더 떨어짐. 신호 반전.
3-3. 핵심 해석¶
-
퀀트 단독 (full 81) D+30 +18.15pp — 신호 방향성은 살아있음. S312v2 보고 +9.11pp (top/bottom decile) 대비 본 backtest는 8분위 G1/G8 기준이라 더 양 극단 → 큰 폭. 퀀트 축 자체는 작동.
-
단순 결합(sum/prod)이 quant 단독을 깬다 — 거짓. D+30 sum -5.93 / prod -4.99 < quant +18.15. PM 질문 "알파 없나"에 대한 답은: 본 1시점 단순 z-score 결합은 quant 단독 신호를 희석/왜곡한다.
-
테마 RS는 추격 신호 — 강상승장에서 역효과. 60일 RS lookback이 forward 30일에는 평균회귀 발생. T 단독 모든 horizon 음수.
-
24종 시총 상위 누락이 결합 backtest의 실질 표본을 valid 57로 줄임. valid 57 한정으로 다시 보면 Q 단독도 D+30 +7.75로 절반 가까이 떨어지고, 오히려 C 단독이 D+30 +15.41pp로 가장 우월. 즉 결합이 quant를 희석한 게 아니라, 결합 universe로 좁히면 차트가 quant를 능가한다는 별도 발견.
-
S_prod의 부호 모호성 — 명시적 결함. TOP 5 중 047040은 z_Q -1.76 (퀀트 약), z_C -0.38 (차트 약), z_T +4.34 (테마 강) → S_prod = (-)(-)(+) = +2.88로 TOP. 그러나 두 음수가 곱해져 양수가 된 것이라 "세 축 모두 강세"라는 본래 의미와 다름. 결합 산식으로 prod 부적합.
4. 한계 및 후속¶
본 backtest의 본질적 한계¶
- 표본 1시점: 통계 유의성 불가, 모두 trend 방향성 시사만.
- forward 1개월: D+30이 KOSPI 2026-05-22 한계까지의 최대 horizon.
- 강상승장 일방: KOSPI 60d +20%, forward 30d +32% — drawdown / bear regime 미검증.
- 시장환경 cell 단일: 4축 명세의 3번 축 결합 측정 불가.
- ats_main 테마 매핑 24종 결손: 시총 상위 종목 누락 → 결합 universe 편향.
다음 세션 제안 (PM 결정 대기)¶
A. 시점 확장 — EA_QoQ 산식이 5분기 시계열만 요구하므로, 2025Q1~Q4 4시점으로 cross-section 누적해 224 obs (4 × valid 56) 수준으로 표본 확보. 단 forward window는 시점별로 다르므로 stale data 처리 필요.
B. ats_main.json 24종 테마 보강 — 결합 universe를 80~81로 확장하고 재실행. ats_main 자체가 데이터 결함이므로 인접 테마 추론 또는 산업분류 차용.
C. 결합 산식 재설계 — 단순 z-score 가산은 본 결과에서 quant 희석 확인. 대안: - Gate 방식: Q ≥ percentile 70 AND C ≥ percentile 50 AND T ≥ percentile 50 (S310 hybrid gating 원안) - 가중 회귀: forward alpha를 종속, 각 축 z를 독립으로 회귀 계수 추정 - 비선형 결합: tree-based ranker
D. 차트 단독축 우위 추적 — valid 57 한정 C only D+30 +15.41pp는 본 backtest의 가장 강한 단일 신호. 다른 시점에서도 재현되는지 확인.
5. 산출물¶
- 코드:
scripts/quant/themes/theme_rs.py(신규)scripts/quant/charts/chart_state_score.py(신규)scripts/backtest/e2_3axis_combined.py(신규)- 데이터:
data/backtest/theme_rs/{theme_rs_2026-04-06, stock_theme_rs_2026-04-06}.parquet+ metadata/backtest/chart_state/stock_chart_state_2026-04-06.parquet+ metadata/backtest/e2_3axis/{combined_panel, decile_summary}.parquet+results.json- 문서: 본 파일
6. PM 질문 직답 모음¶
| 질문 | 답 |
|---|---|
| "차트+퀀트 다 사용했을 때 알파 없는건가?" | 본 1시점 단순 z-score 결합으로는 quant 단독을 못 이김 (D+30 sum -5.93 vs Q only +18.15). 단, 결합 universe 한정으로는 C 단독이 +15.41로 최고. 결합 산식 재설계 + 시점 확장 후 재측정 필요. |
| "4축인데 왜 3축?" | 2026-04-06 시점 시장 cell이 HIGH_HIGH 단일이라 81종 모두 같은 multiplier — cross-section 분산 0 → 결합 정보 0. 메타만 기록. |
| "S_sum TOP 5가 왜 다 음수 alpha?" | TOP에 들어온 종목들이 강상승장에 이미 많이 올라 평균회귀. 특히 47040(테마 강 + 퀀트 약)처럼 부호 부정합 종목이 sum으로 통과. Gate 방식 도입 시 차단 가능. |
| "통계 유의한가?" | 아니오. n=57 (또는 81) 1시점, p-value 산정 불가. 모두 방향성 단서. |