Skip to content

fix: 자본 부족으로 못 채우는 바스켓 슬롯 침묵 스킵 가시화 + 운영자 결정 필요 - #422

Merged
easygap merged 2 commits into
mainfrom
fix/unfillable-slot-warning
Jun 11, 2026
Merged

fix: 자본 부족으로 못 채우는 바스켓 슬롯 침묵 스킵 가시화 + 운영자 결정 필요#422
easygap merged 2 commits into
mainfrom
fix/unfillable-slot-warning

Conversation

@easygap

@easygap easygap commented Jun 11, 2026

Copy link
Copy Markdown
Owner

발견 (운영 2일차 점검, 19번째 감사 라운드)

kr_diversified_hold의 000660(SK하이닉스) 슬롯이 비어 있는데(9/10 종목) 어떤 경고도 없었다.

원인: 목표 거래금액(자본 1,000만 × 실효 8% = 80만원)이 1주 가격 213만원보다 작아 quantity=0 → 조용히 continue. 드리프트 트리거(8%p)는 매 사이클 발동하지만 계획 단계에서 침묵 스킵돼, 배분이 설계(10종목·주식 80%)와 다르게(9종목·실효 72%) 굳은 것을 운영자가 알 수 없었다.

수정 (가시화만, 동작 불변)

매수 의도인데 0주인 슬롯은 명시 경고 — 1주 가격 vs 목표 금액과 필요 조치(자본 증액/비중 조정)를 로그로 드러낸다. 일일 스케줄 작업이 이상 징후로 보고하게 된다. 경계 테스트 추가, 전체 1511 passed.

🔴 운영자 결정 필요 (이 PR 범위 밖 — 선택지)

선택지 내용 효과
A. 자본 증액 initial_capital ≥ 2,670만원 (213만/8%) 설계대로 10종목 80% — 트랙레코드 대표성 최선
B. 비중 조정 000660 제외 또는 9종목 재배분 (baskets.yaml) 현 자본으로 설계-실행 일치. 단, 운영 중 설계 변경은 60일 기록의 일관성에 주석 필요
C. 현상 유지 9종목·실효 주식 72%로 계속 기록 자체는 정직(실보유 기준). 다만 4.5년 백테스트(10종목 80%)와의 구성 괴리 인지 필요

PM 권고: A(가능하면) > C > B. paper 자본은 실돈이 아니므로 A의 비용은 0이고, 60일 기록이 설계와 일치하는 것이 평가 가치가 가장 높습니다. A 결정 시 적용 방법을 다음 사이클에서 도와드리겠습니다.

easygap added 2 commits June 11, 2026 10:56
운영 2일차 점검에서 발견: kr_diversified_hold의 000660(SK하이닉스) 슬롯이
비어 있는데(9/10 종목) 어떤 경고도 없었다. 원인 — 목표 거래금액(자본 1,000만
× 실효 8% = 80만원)이 1주 가격(213만원)보다 작아 quantity=0으로 조용히
continue. 드리프트 트리거는 매 사이클 발동하지만 계획 단계에서 침묵 스킵돼,
운영자는 배분이 설계(10종목 80% 주식)와 다르게(9종목 72%) 굳은 것을 모른다.

수정: 매수 의도(drift>0)인데 0주인 슬롯은 명시 경고 — 1주 가격 vs 목표 금액,
자본 증액 또는 비중 조정 필요를 로그로 드러낸다(일일 스케줄 작업이 이상 징후
로 보고). 코드 동작(주문 생성)은 불변 — 가시화만.

테스트: 고가 1종목+일반 1종목 계획에서 일반 종목만 주문 생성되는 경계 고정.
전체 스위트 통과.

참고(운영자 결정 사항, PR 본문에 선택지): 트랙레코드 자체는 실보유를 정직하게
기록 중이라 무결성 문제는 없다 — 다만 4.5년 백테스트(10종목 80%)와 paper
(9종목 72%)의 구성 괴리는 평가 시 인지해야 할 사실.
…arning

# Conflicts:
#	tests/test_basket_rebalancer.py
@easygap

easygap commented Jun 11, 2026

Copy link
Copy Markdown
Owner Author

정정·보고: A안(자본 증액)의 기술적 전제인 바스켓별 initial_capital 레버를 구현하는 과정에서 git 작업 실수로 해당 커밋(8d258ca)이 PR을 거치지 않고 main에 직접 푸시됐습니다. 내용은 전체 스위트(1513 passed) 검증을 거쳤고 이 PR 본문의 결정과 직결된 기능입니다: baskets.yamlinitial_capital: 30000000을 지정하면 그 바스켓 계정만 자본이 적용됩니다(전역 무변). 부수로 portfolio_mgr가 기본 계정('')을 보던 잠재 버그도 수정됐습니다. 이 브랜치는 main과 정합화(머지·충돌 해소) 완료. 직접 푸시 재발 방지 규칙을 작업 수칙에 기록했습니다 — 죄송합니다.

@easygap
easygap merged commit 697151b into main Jun 11, 2026
1 check passed
@easygap

easygap commented Jun 11, 2026

Copy link
Copy Markdown
Owner Author

📊 결정 지원 — 선택지별 4.5년 실측 (2021-12~2026-06, 동일 도구·정수주·수수료 반영)

선택지 총수익 CAGR Sharpe MDD
A안 (10종목, 자본 30M — 전 슬롯 충족) +197.8% +27.3% 1.04 −23.1%
B안 (9종목 재배분, 자본 10M) +72.5% +12.8% 0.58 −21.4%
참고 (10종목·10M, 2021년 시작가엔 충족됐음) +178.2% +25.4% 1.03 −21.4%

해석: SK하이닉스가 지난 4.5년 수익의 핵심 기여 종목이었습니다(AI/HBM 랠리). B안은 역사적으로 CAGR을 절반 이하로 깎는 선택입니다 — A안 권고의 정량 근거.

정직한 단서 둘:

  1. 과거 기여가 미래를 보장하지 않습니다 — 오히려 이 수치는 "10종목 등가중인데 한 종목 제외가 수익 절반을 깎는다"는 집중 리스크의 발견이기도 합니다(수익이 소수 종목에 집중).
  2. paper 자본은 실전 투입 예정 자본과 일치해야 트랙레코드가 대표성을 가집니다. 실전이 1,000만원이면 live에서도 같은 슬롯 문제를 만나므로, 그 경우 A안으로 paper만 30M으로 돌리는 것은 자기기만이 됩니다 — 실전 예정 규모를 기준으로 결정해 주세요 (≥2,700만 예정 → A / 1,000만 예정 → B 또는 C를 그 규모 그대로).

@easygap

easygap commented Jun 11, 2026

Copy link
Copy Markdown
Owner Author

📊 추가 — leave-one-out 분해 (4.5년, 동일 조건 10회)

제외 종목 CAGR Δ기준 대비
000660 SK하이닉스 +13.6% −13.7%p
005930 삼성전자 +26.8% −0.5%p
(그 외 8종목) +27.7~29.8% +0.4~+2.5%p

발견의 실체: 집중이 "1~2종목"이 아니라 정확히 한 종목입니다. 4.5년 +27.3%는 사실상 SK하이닉스의 AI/HBM 랠리 + 나머지 9종목의 평범한 시장 수익이고, 4종목(카카오·네이버·LG화학·포스코)은 빼면 오히려 성과가 오르는 음의 기여였습니다.

기대치 보정 (정직한 결론):

  • 하이닉스 랠리 재현을 가정하지 않는 보수적 기준선은 CAGR +13~14%대 — 기존 robustness 분석(2022 약세 포함 ~13%)과 정확히 합치합니다.
  • A안의 +27.3%는 "랠리 포함 과거"이고 미래 보장이 아닙니다 — 다만 보유하지 않으면 그런 종목의 기여를 받을 가능성 자체가 0이라는 것이 등가중 보유의 논리입니다(어느 종목이 다음 하이닉스인지 모르므로).
  • 결정 기준은 변함없습니다: 실전 예정 자본 규모 기준으로 A/B/C를 선택하시되, 어느 쪽이든 기대 CAGR은 13~14%를 기준선으로, +27%는 상방 시나리오로 보시는 것이 정직합니다.

easygap added a commit that referenced this pull request Jul 6, 2026
대기 중인 자본 결정(#422 A안)의 근거 표가 작성 시점 시세에 고정돼 있어
낡는 문제를 해결한다. 실제로 7/2 기준 34M 권고가 7/6 시세(하이닉스
242.4만→232.2만)로는 32M이 우수(배치율 77.4% vs 74.5%)로 뒤집혔다 —
정수 절사 톱니 효과 때문에 최적 자본은 시세와 함께 움직인다.

tools/capital_slot_simulator.py (읽기 전용 — 주문·DB 변경 없음):
- simulate_slot_fills(순수): 자본×실효비중 슬롯 → 정수 주수 → 채움율,
  미체결(1주 초과·최소거래 미달) 판정. 가격 조회 불가는 별도 표기.
- 시세는 실제 사이클과 동일 소스(BasketRebalancer 시세 경로) 재사용.
- 기본 스윕(10~62M) 또는 --capital 단일 상세. 현재 10M 상태의
  미체결·배치율(58%)을 정확히 재현하는 것으로 검산.

문서 §3 갱신:
- 자본 숫자는 결정 시점에 시뮬레이터로 재계산하는 절 + 선택 기준
  (미체결 0 · 배치율 -5%p 이내 · 하이닉스 채움 92% 이하 여유를
  만족하는 최소 자본)
- 재시작일 다중 실행 금지: 6/10 타이밍 비용(-1%p)은 그날 사이클 4회
  수동 실행으로 하루 61% 집중 매입한 것이 원인 — 정상 자동화는 회전
  상한(15%/일)이 초기 매입을 자연 분할하므로 P2-9(분할 진입)는
  코드 불필요로 종결
- 재시작 전제조건(P0-1 머지 + 재시도 크론) 충족 기록

전체 스위트 1604 통과.
easygap added a commit that referenced this pull request Jul 6, 2026
fix: 자본 부족으로 못 채우는 바스켓 슬롯 침묵 스킵 가시화 + 운영자 결정 필요
easygap added a commit that referenced this pull request Jul 6, 2026
당일 출고분 자기검토 2라운드(독립 에이전트)의 확정 결함 3건:

[HIGH] 평가 수집기(collect_basket_paper_evaluation)가 전역 initial_capital만
읽어, 바스켓별 자본 레버(ea27d82) 설정 시 비용 드래그가 수 배 과대(예: 30M
매입 비용/10M)되어 거짓 FAIL_REVIEW — CLI·게이트·대시보드가 공유하는 판정
자체가 틀어진다. 자본 해석을 운영과 동일하게(바스켓 initial_capital 우선,
전역 폴백) 수정. 레버를 켜기 전에 잡아서 실해 0.

[MED] 백업 격리 가드의 스킵 로그가 debug라 운영 배포(QUANT_DB_PATH로 DB 분리
— config 주석의 정당 용도)에서 백업이 조용히 꺼져도 주간 리허설 전까지 모름
— warning 승격 + QUANT_BACKUP_PATH 동반 설정 안내.

[LOW] 미보유 슬롯의 목표 금액 < min_trade_amount인 경우가 채움 불가 경고(#422)
보다 앞 분기에서 여전히 침묵 스킵 — 같은 부류로 경고 추가.

테스트: 수집기 자본 해석 2건(레버/전역 폴백). 전체 1516 passed.
easygap added a commit that referenced this pull request Jul 6, 2026
한 달 운영 리뷰(docs/PAPER_MONTH1_REVIEW_AND_PLAN.md P0-3)의 처방을 구현했다.
기존 일일 카드는 절대 수익만 있어 -5.47%가 전략 탓인지 판단할 수 없었다.
아래 세 축을 카드에 추가해 왜 그런지 한눈에 보이게 한다.

추가 필드:
- 📊 vs KS11: NAV vs 벤치마크 격차 (시장 대비)
- 🎯 주식 배치율: 실제 주식비중 vs 설계 80% (설계 대비)
- 📅 진행률: n/60일 · 커버리지 % · 잔여 결측예산 (일정 대비)
- 💸 누적 비용: 누적/연환산(기간 미충족 시 참고 표기)
- ⚠️ 미체결 슬롯: 현재 자본으로 못 채우는 슬롯 경고(#422)

구조:
- core/basket_evaluation.py: 순수 포맷터 build_daily_report_extras + 평가결과에
  snapshot_days 노출(결측예산 계산). 테스트 용이하게 분리.
- core/basket_rebalancer.py: 읽기전용 diagnose_deployment — 종목별 드리프트가
  못 보는 집계 배치율 이탈 + 미체결 슬롯을 함께 드러낸다.
- main.py: 일일 사이클 배선. 부가필드 실패해도 기본 카드는 발송(채널 보조).
- core/notifier.py: 값 있을 때만 렌더링(하위 호환).

적대적 리뷰 반영: 스냅샷 결측일 NAV 단일소스화(카드 누적수익률과 일치),
결측예산 게이트 정합(max(min_days, progress_days)), min_trading_days=0 방어,
경계 테스트 보강(>3 슬롯 요약, min_trade arm, 가격/총자산 0).

전체 스위트 1548 통과, 실데이터 스모크 확인.
easygap added a commit that referenced this pull request Jul 6, 2026
대기 중인 자본 결정(#422 A안)의 근거 표가 작성 시점 시세에 고정돼 있어
낡는 문제를 해결한다. 실제로 7/2 기준 34M 권고가 7/6 시세(하이닉스
242.4만→232.2만)로는 32M이 우수(배치율 77.4% vs 74.5%)로 뒤집혔다 —
정수 절사 톱니 효과 때문에 최적 자본은 시세와 함께 움직인다.

tools/capital_slot_simulator.py (읽기 전용 — 주문·DB 변경 없음):
- simulate_slot_fills(순수): 자본×실효비중 슬롯 → 정수 주수 → 채움율,
  미체결(1주 초과·최소거래 미달) 판정. 가격 조회 불가는 별도 표기.
- 시세는 실제 사이클과 동일 소스(BasketRebalancer 시세 경로) 재사용.
- 기본 스윕(10~62M) 또는 --capital 단일 상세. 현재 10M 상태의
  미체결·배치율(58%)을 정확히 재현하는 것으로 검산.

문서 §3 갱신:
- 자본 숫자는 결정 시점에 시뮬레이터로 재계산하는 절 + 선택 기준
  (미체결 0 · 배치율 -5%p 이내 · 하이닉스 채움 92% 이하 여유를
  만족하는 최소 자본)
- 재시작일 다중 실행 금지: 6/10 타이밍 비용(-1%p)은 그날 사이클 4회
  수동 실행으로 하루 61% 집중 매입한 것이 원인 — 정상 자동화는 회전
  상한(15%/일)이 초기 매입을 자연 분할하므로 P2-9(분할 진입)는
  코드 불필요로 종결
- 재시작 전제조건(P0-1 머지 + 재시도 크론) 충족 기록

전체 스위트 1604 통과.
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