전략 장부를 만들고, 2호를 등록하지 않았다 — 판정 기준이 규모 쏠림만으로 통과된다
여러 전략이 한 엔진에 줄 서는 전략 장부를 구현했다(테스트 225, 1호 규칙 재생 일치). 그런데 페이퍼 2호의 판정 기준 A — 동일비중 대비 주간 승률 55% — 를 임원 신호 없이 규모만 맞춘 대조군이 85% 통과했다. 이벤트 스터디 t 9.9와 포트폴리오 t −0.3의 격차 원인을 찾을 때까지 등록을 보류한다. 키움 토큰 시간대 버그와 DB 백업도.
어제 밤 "내일 하자"로 미뤄 둔 일이 오늘 첫 순서였다. 페이퍼 2호. 교수님은 아침에 계획을 승인하고 판정 기준 A(2027-03, 동일비중 대비 주간 승률 ≥ 55% ∧ 누적 초과 > 0)를 골랐다. 저녁에는 등록하지 않았다. 그 사이에 무슨 일이 있었나.
전략 장부
2호를 1호처럼 전용 테이블로 복제하지 않는다. 전략은 클래스 하나이고(DB만 읽어 그날 신호 후보를 돌려준다), 체결·평가·벤치 3종(동일비중·규모 매칭·KODEX)·주간 채점·장세 기록은 엔진이 똑같이 한다. 규칙은 등록 때 해시로 고정되고, 코드의 규칙이 등록과 다르면 실행기가 거부한다. 폐기한 전략도 지우지 않는다 — 몇 개를 시도했는지가 다중 비교의 분모다.
만들기 전에 골든을 만들었다. 자리 지표(RSI18·90일 고점·20일 수익)는 백테스트 파이썬 정본으로 기대값을 뽑아 PHP가 1e-9까지 맞아야 통과다. 일부러 RSI 기간을 17로 바꾸면 차이 1.1, 입력 종가 하나를 1e-7 흔들면 6e-6 — 테스트가 잡는다. 1호 규칙을 새 엔진에 태워 일일 수익·NAV·포지션이 1호 코드와 똑같이 나오는 것까지 확인했다. 테스트 225.
과거 시세가 22거래일뿐이라 300거래일로 늘려야 했다. 네이버 이력은 페이지당 60건이 한계(넘기면 빈 응답)라 종목당 5콜, 2,675종목. 1호 구간(2026-08-20~)은 읽지도 쓰지도 않고 그 앞만 INSERT, 삭제 없음, 종목 단위 이어받기. VPS에서 13분, 실패 0.
리뷰가 잡은 것
배포 전 코드 리뷰(HIGH 3·MEDIUM 6). 1호 적재가 끝났는지 안 보고 돌면 파생 전 상태(size NULL)를 읽어 전부 illiquid로 굳는다 — 준비 조건을 바꾸고 cron을 세 번(18:40·19:10·21:40) 걸었다. 늦게 적재된 이벤트의 late 판정을 실행 날짜가 아니라 적재 시각으로 해야 밀린 날을 나중에 돌려도 같은 결과가 난다. 노출이 없는 주를 승·패로 세면 안 된다. 그리고 vault 버그 하나 — 247540처럼 앞자리가 0이 아닌 종목 코드가 정수로 바뀌어 회피 플래그에서 빠지고 있었다. 모닝 리포트 「쌓이는 곳」의 ⚠ 열도 같은 영향을 받고 있었다.
동전 확률도 다시 셌다. 판정 기간(2026-09-22~2027-03-31)에 금요일이 27개라 15승이 필요하고, 동전으로 통과할 확률은 35.1%다. 계획서의 27.9%는 26주 기준이었다.
H3 — 기준이 틀렸다
리뷰의 세 번째 HIGH. 2호 근거인 H5b 롤링 포트폴리오가 진입을 하루 앞당겨 세고 있었다(t 종가 진입). 고쳐서 라이브 규칙 그대로(비용 0.3%, 같은 종목 중복 무시, 결측 제외, t+1 진입) 2년을 다시 돌렸다.
| 27주 판정 창 | 백테스트대로면 통과 | 동전 | 임원 신호 없이 규모만 맞춘 대조군 |
|---|---|---|---|
| A: 동일비중 대비 승률 55% ∧ 누적 초과 > 0 | 77% | 30% | 85% |
| A를 규모 매칭 대비로 | 63% | 30% | — |
동일비중 대비로는 알파와 규모 쏠림을 구별하지 못한다. 이 2년은 KODEX가 연 +84% 간 대형주 장이라, 규모 분위만 맞춘 가상 포트가 2호보다 더 잘 통과한다. 비유하면 키 큰 학생만 뽑은 반이 전교 평균보다 크다고 식단 덕이라 할 수 없는 것과 같다. 규모 매칭 대비로 보면 구별은 되지만 포트폴리오 주간 t가 −0.28이다.
여기서 숫자가 어긋난다. 같은 신호로 이벤트 스터디를 하면 규모 매칭 대비 +10.6%p/120일(t 9.9)인데 포트폴리오로 굴리면 0 근처다. 방법론 9번 — 상식에 반하면 코드부터 의심. 유력한 원인 둘: 같은 종목 중복 매수를 무시하는 규칙이 신호의 43%를 버리는데 반복 매수 종목이 성과의 큰 몫이었다(빼면 t 1.22 → 2.04). 그리고 매수 후 보유(이벤트 스터디) vs 매일 재조정(포트폴리오)의 가중 차이. 학술 표준대로면 겹치는 창의 이벤트 t는 부풀고 캘린더타임 포트가 정직한 검정이다 — H5b의 "t 6.6"이 과대였는지도 여기서 판정된다.
교수님은 보류를 골랐다. 엔진과 과거 시세는 서버에 올라가 있고, 등록과 cron만 남겨 뒀다. 규칙과 기준을 다시 확정한 뒤 등록한다.
부수적으로 고친 것
키움 토큰 시간대 버그. 오전부터 서버의 키움 호출이 전부 8005로 실패했다. 토큰 만료 시각은 PHP(KST)로 쓰고 비교는 MariaDB NOW()(UTC)로 해서, 만료된 토큰을 9시간 더 유효로 보고 있었다. 토큰이 바뀔 때마다 9시간씩 반복될 뻔한 버그다. 판정을 PHP 시계로 통일했다(테스트 7).
DB 백업. 백업이 하나도 없었다. 매일 03:30 덤프 7일 보관, 키움 토큰·계좌 키 테이블 제외(사본이 로컬·클라우드로 나가도 키가 새지 않게), 로컬 backups/로 가져오는 스크립트. 첫 덤프 49.9MB.
남은 한 문장
엔진은 하루에 만들 수 있었지만 기준은 하루에 정하면 안 됐다. 백테스트가 통과시키는 기준을 규모만 맞춘 대조군도 통과한다면, 그 기준은 아무것도 판정하지 않는다.