콘텐츠로 이동

S316 — 종목 풀 동적 재정의 + OF 사용 정정 walk-forward

작성: 2026-05-25 (Mon) 기간: 2026-02-20 ~ 2026-05-22 (63 거래일) 선행: S315 (시총 100 정적 풀 + OF 4축 AND) NAV -10.76% / KOSPI -45.87pp 결함 결론 한 줄: 동적 풀(강한 테마 × 강한 종목) + OF 정정(추가 상승 동력 확인) → NAV +58.10% / KOSPI +22.98pp 알파.


1. PM 정정 2건

정정 #10 — 종목 풀 재정의

  • before: 시총 상위 100 정적 풀
  • after: 각 거래일에서 강한 테마 top 3 × 각 테마 leader top 3 동적 풀 (universe 100 범위 제한)
  • 평균 풀 크기: 8.3종 (7~9, PM 의도 "10~20개 이내" 정합)

정정 #9 — OF 사용 정정

  • before: 4축 AND (buy_intent + not_exhausted + near_support + cvd_alive)
  • PM 가르침 (21:13): "오른 종목 = 더 오를 가능성, 쉬는 종목 = 다시 오를 가능성. 50% 떨어지면 사자가 아님."
  • after: 상황 B (state=IMBALANCE_UP, 오른 종목) → not_exhausted AND cvd_alive (추가 상승 동력 확인). 상황 A (state=BALANCE, br60>0, 쉬는 종목) → not_exhausted AND cvd_alive (눌림 끝나가는가).
  • near_support 폐기 (PM 가르침에 없는 임의 추가였음). buy_intent 폐기 (state=IMBALANCE_UP 자체가 매수 우위).

2. 수치 (NAV 시작 1.0)

전략 Final NAV Total Return KOSPI 대비
포트폴리오 (S316) 1.5810 +58.10% +22.98pp ★
KOSPI 1.3511 +35.11% baseline
Top5 buy-and-hold 1.6604 +66.04% +30.93pp
Random5 buy-and-hold 1.4307 +43.07% +7.96pp

S315 대비 변화: - S315: -10.76% / -45.87pp - S316: +58.10% / +22.98pp - 개선 폭 +68.86pp (NAV) / +68.85pp (KOSPI 대비)


3. 거래 내역 (n_trades=3)

Date Action Code Name 가격 사유
2026-03-03 ENTRY 079550 LIG넥스원 661,000 state=IMBALANCE_UP/phase=MARKUP/best_state=HOT(방산) score=1.25
2026-04-22 EXIT 079550 LIG넥스원 1,019,879 state=BALANCE/phase=DIST/chart=-0.40 분배 확정
2026-05-11 ENTRY 005930 삼성전자 285,500 state=IMBALANCE_UP/phase=MARKUP/best_state=HOT(반도체) score=1.09
  • LIG넥스원 1건 수익률 +54.3% (50거래일 보유)
  • 삼성전자 보유 중 (5/22 종가 평가 +8.4%)
  • 거래 2건만으로 알파 +23pp 확보

4. 구조적 함의

풀 정의 (PM 가르침: "가장 강한 테마 1,2,3 × 가장 강한 종목 1,2,3 = 10~20개")

  • best_rs_60d 상위 3 테마 × 각 테마 leader-judge 4기준(cum_return/downside_resilience/turnover_concentration/reaction_speed) 1~3위
  • universe 100 안에서만 leader 후보 → 차트 산출 범위 정합 (확장 없이 작은 풀로 검증)

OF 정의 (PM 가르침: "동력이 살아있는가")

  • 강한 종목 = 이미 60일 +30%~200% 상승, POC/VAL에서 멀리 있음 → near_support 부적합
  • IMBALANCE_UP 종목 = 이미 매수 우위 상태 → buy_intent 단봉 신호 불필요
  • 실제 필요: 추가 상승 동력 잔존 = exhaustion 없음 + CVD 살아있음
  • 같은 정의가 상황 A(쉬는 종목)에도 적용: 눌림 중 동력 안 죽었는지

5. 결함 / 한계

  1. 거래 표본 n=3 — 알파 +23pp의 통계적 유의성 입증 불가. 더 긴 기간 + 더 많은 진입 필요.
  2. 풀 평균 8.3종 < MAX_POS 5 와 진입 통과율 낮음 → 70거래일 중 진입 2번. 게이트가 보수적.
  3. chart_score ≤ -0.3 차단state=None 차단 때문에 풀 후보 중 60~70%가 진입 불가 (chart 데이터 누락).
  4. LIG넥스원 1종이 알파의 거의 전부 (+54.3% × 100% 비중). 표본 1건에 의존.
  5. 강상승장 시점이라 baseline(KOSPI +35%) 자체가 강함. 약상승장/하락장 미검증.

6. 산출

코드 변경

  • scripts/backtest/e4_portfolio_walk.py:
  • compute_theme_rs_for_dates() → 종목 + 테마 단위 RS 둘 다 반환
  • _stock_metrics_at() + _score_theme_members_at() 신규 (S314 leader-judge 일반화)
  • select_daily_candidates() 신규 (강한 테마 top × leader top, universe 제한)
  • can_enter() 재작성 (상황 A/B 분기, 추가 상승 동력 확인)
  • run_portfolio() 시그니처 확장 (theme_df, themes_map, ohlcv_cache, universe 인자)
  • main() 캐시 분리 (_daily_theme_rs.parquet + _daily_theme_rs_byTheme.parquet)

데이터

  • data/backtest/e4_portfolio/_daily_theme_rs_byTheme.parquet (5,103행, S316 신규)
  • data/backtest/e4_portfolio/portfolio_nav.parquet (S316 NAV, 63 거래일)
  • data/backtest/e4_portfolio/trade_log.json (3건)
  • data/backtest/e4_portfolio/summary.json (S316 v2 결과)

7. 다음 세션 후보

  1. 표본 확장 — 백테스트 기간을 1년+로 확장하여 거래 n 증가
  2. chart_score ≤ -0.3 차단 재검토 — chart 데이터 없는 종목이 자동 차단되어 풀 활용도 낮음
  3. 약상승장/하락장 검증 — 현재 결과는 강상승장 한정
  4. OF 추가 조건 검증 — exhaustion+cvd 외 보조 신호 (volume profile, vsa) 추가가 알파 개선시키는지