Skip to content

리스크 오버레이(추세 필터·낙폭 제어) + 대시보드 개편 + README - #463

Merged
easygap merged 5 commits into
mainfrom
feat/risk-overlays-dashboard-2026-09
Sep 17, 2026
Merged

easygap merged 5 commits into
mainfrom
feat/risk-overlays-dashboard-2026-09

Conversation

@easygap

@easygap easygap commented Sep 17, 2026

Copy link
Copy Markdown
Owner

무엇을 바꿨나

1. 리스크 오버레이 — 주식 비중을 언제 줄이는가 (core/risk_overlays.py, core/basket_rebalancer.py)

종목 선택 알파가 없다는 확정 결론은 그대로 두고, 운용 중인 트랙의 주식 비중 조절 규칙만 바꿨다. tools/risk_overlay_backtest.py로 코스피200(2002~), KODEX 200 실제 ETF(2014~), 대형주 10종목(2021-12~)을 같은 비용·적립 규칙으로 비교했고 전체 표는 docs/RISK_OVERLAY_FINDINGS.md에 있다.

트랙 정책 연수익률 최대낙폭 최악 연도 샤프
적립(ETF 2014~) 고정 비중(현행) +9.62% −21.7% −11.2% 0.59
적립(ETF 2014~) 추세 필터 절반 + 낙폭 제어 +8.76% −16.3% −4.6% 0.64
관찰(대형주 10종목) 고정 비중(현행) +18.32% −26.1% −13.5% 0.82
관찰(대형주 10종목) 낙폭 제어 +15.84% −16.4% −10.6% 0.85

정직하게: 수익률을 올리는 정책은 없다. 손실을 줄이는 정책은 있다. 변동성 목표는 한국에서 수익을 2~9%p 깎아 기본 off.

  • kr_pocket(주력, 모의투자): 추세 필터(코스피200 200일선 ±2% 히스테리시스, 아래면 절반) + 낙폭 제어(−10%에서 절반, −5% 회복 시 복귀) . 2026-09-17 현재 200일선 +12%, 낙폭 −5%라 즉시 바뀌는 주문은 없다.
  • kr_diversified_hold(관찰): 실전 전환 승인 대기 중이라 끄고 권장값만 기록.
  • 배수는 설계 비중에 곱한다(95% × 0.5 = 47.5%). 배치 진단·트리거·헬스·대시보드가 전부 그날의 적용 비중을 본다. 데이터가 없으면 직전 상태를 유지하고 data_issues로 드러낸다. 상태는 data/overlay_state/<basket>.json.

2. 대시보드 개편 (monitoring/)

종이·잉크 두 색, 헤어라인 규칙, Inter Tight + Noto Sans KR. 첫 화면은 스크롤에 따라 자산 곡선이 그려지며 총자산 → 적립을 뺀 시간가중수익률 → 최대 낙폭을 보여준다. 본문은 지표·종목표·평가금액/낙폭/월별 차트·검증·운영 상태표. 문구는 증권사 앱 어휘로 다시 썼다. API에 목표 비중·보유분 합계·오버레이 판단을 추가했다.

3. README — 실제 화면 캡처 6장과 백테스트 그림으로 한눈에 읽히게 다시 씀.

확인한 것

  • 새 테스트 24건(순수 함수 16 + 리밸런서 통합 8) + 기존 대시보드·리밸런서·배치 테스트 통과, 전체 스위트 로컬 실행.
  • main.py --mode rebalance --basket kr_pocket --dry-run으로 실제 지수 데이터로 오버레이 판단이 기록되는 것 확인(배수 1.0).
  • 대시보드 1440px·375px 콘솔 에러 0건, API 응답 20~70ms.

끄는 법

config/baskets.yamlkr_pocket.overlays.*.enabled: false. 다음 사이클부터 설계 비중으로 돌아간다.

종목 선택 알파가 없다는 결론 위에서 주식 비중을 언제 줄이는지만 바꾼다.
tools/risk_overlay_backtest.py로 세 구간(코스피200 2002~, KODEX 200 2014~,
대형주 10종목 2021-12~)을 같은 비용·적립 규칙으로 비교했고 결과는
docs/RISK_OVERLAY_FINDINGS.md에 정리했다.

- core/risk_overlays.py: 추세 필터(200일선 ±2% 히스테리시스), 낙폭 제어(-10%
  발동·-5% 해제), 변동성 목표(기본 off)를 순수 함수로 두고 상태는
  data/overlay_state/<basket>.json으로 잇는다. 데이터가 없으면 직전 상태를
  유지하고 data_issues로 남긴다.
- BasketRebalancer._stock_fraction = 설계 비중 × 오버레이 배수. 배치 진단·
  트리거·주문 계획이 같은 값을 쓰고, 헬스(main.py)도 적용 비중과 비교한다.
- kr_pocket은 추세 필터 + 낙폭 제어를 켰다(현재 코스피200 200일선 +12%,
  낙폭 -5%라 즉시 바뀌는 주문 없음). kr_diversified_hold는 실전 전환 승인
  대기 중이라 권장값만 기록하고 껐다.
- 테스트: 순수 함수 16건, 리밸런서 통합 8건. conftest가 상태 디렉터리를
  임시 경로로 격리한다.
- 첫 화면: 스크롤에 따라 평가금액·투자원금(점선)·적립 시점이 그려지고 총자산 →
  적립을 뺀 시간가중수익률 → 고점 대비 최대 낙폭 세 패널이 교차 전환된다. rAF
  기반 스크럽(스크롤 목표값과 차이가 있을 때만 그림, 정지 시 CPU 0).
- 본문: 오늘 할 일·운영 상태 요약, 트랙별 지표 6개와 스파크라인, 종목별 매입
  비중 vs 목표 비중 막대표, 평가금액 차트(커서 툴팁)·낙폭 차트·월별 수익률,
  검증 진행률, 운영 상태표. 카드·유리·그림자·사진 없이 헤어라인 규칙만 쓴다.
- 글꼴은 Inter Tight(숫자) + Noto Sans KR(한글) 400·500, 손익 색은 상승 빨강·
  하락 파랑. 문구는 증권사 앱 어휘로 다시 썼다(총자산·투자원금·평가손익·
  시간가중수익률·최대낙폭·자동매매).
- API: 계좌별 목표 비중(target_weights), 보유분 매입·평가 합계, 리스크 오버레이
  적용 비중·판단 요약(overlay)을 추가. 최대낙폭은 장부의 그날 낙폭이 아니라
  기록 전체의 최대값으로 계산한다.
- ?scrub=·?section= 캡처 모드로 헤드리스 브라우저에서 같은 화면을 찍을 수 있다.
- 오래된 화면 캡처 3장을 지우고 새 캡처 6장으로 교체.
무엇을 하는 프로젝트인지, 돈이 어떻게 굴러가는지, 정직한 기대치가 얼마인지,
2026년 9월에 무엇을 바꿨는지를 첫 화면에서 알 수 있게 구성했다. 개발 노트
형식의 항목 나열 대신 새 대시보드 캡처 6장과 오버레이 백테스트 그림을 넣었고,
실행·안전장치·문서 안내는 짧게 줄였다.
주기 갱신만 숨은 탭에서 쉬고, 첫 로드와 '다시 확인'은 탭 상태와 무관하게 실행한다.
이전엔 뒤에서 연 탭이 8초 뒤 빈 화면으로 남았다.
@easygap
easygap merged commit 57e029a into main Sep 17, 2026
1 check passed
@easygap
easygap deleted the feat/risk-overlays-dashboard-2026-09 branch September 17, 2026 02:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant