거래 0건. 봇은 정상 작동했고 조건이 안 맞았다. 다만 그 판단에 쓴 숫자가 장전 시간외 데이터로 오염돼 있었다.
22종목에 각 조건을 단독으로 적용한 결과다.
| 조건 | 기준 | 통과 | 탈락 |
|---|---|---|---|
| 시가 갭 | −2.0 ~ +3.0% | 6 | 16 |
| 30분 변동폭 | 0.5 ~ 2.5% | 2 | 20 |
| 거래량비 | 전일 동시간 ≥ 80% | 16 | 6 |
변동폭을 통과한 셀트리온(2.31%)·삼성중공업(2.39%)은 갭도 통과했으나(+0.44, +1.21) 거래량비가 둘 다 0.74 — 0.06 차로 탈락했다.
통과했더라도 매수는 거의 없었다.
| 종목 | 최저이탈 | 밴드 체류 | A+B 동시 만족 | 최대 매수 |
|---|---|---|---|---|
| 셀트리온 | −0.56% | 0분 | 0분 | 0회 |
| 삼성중공업 | −1.30% | 6분 | 3분 | 1회 |
여기에 코스피가 진입창 270분 중 134분(50%)을 −1% 아래에서 보내 조건 C로 차단됐다.
| # | 결함 | 증상 | 조치 |
|---|---|---|---|
| 1 | 장전 시간외 캔들 혼입 | 1분봉이 08:41부터 옴. 30봉이어야 할 창이 49봉. 시가·변동폭·거래량비가 전부 오염 | get_intraday_candles() 하나로 통일, 09:00 하한 |
| 2 | 12:20 이후 '당일 평균가'가 당일이 아님 | count 상한 200 → 09:00+200분=12:20부터 최근 200분 이동평균으로 조용히 바뀜 | before 로 나눠 받아 당일 누적 유지 |
| 3 | 탈락 사유 미기록 | passed_dynamic 0/1뿐. 이 회고를 쓰려 7시간 뒤 API 재조회로 재현해야 했다 | watchlist.dynamic_detail 에 실측값+사유. 정원이 차도 계속 평가 |
| 4 | 관찰 0개인 날 데이터 0행 | 파라미터 조정 근거가 가장 필요한 날 아무것도 안 남음 | 장 종료 시 정적 통과 전 종목의 당일 분봉 일괄 보관 |
| 5 | 리포트가 "0건"만 말함 | 봇이 일한 건지 멈춘 건지 구분 불가 | 15:40 리포트에 관찰 N개 (정적 M → 동적 N) + 사유별 탈락 집계 |
1·2번은 회귀 테스트로 고정했다. 구 방식이 테스트에서 49봉·첫봉 08:41을 그대로 재현하는 것까지 확인했다.
계측 수정 시점에는 파라미터를 건드리지 않았다. 다만 같은 날 아래 완화까지 들어가면서 계측 수정의 단독 효과는 관측하지 못한다. dynamic_detail 을 옛 상한으로 다시 채점하면 사후 분리된다.
| 대상 | 기존 | 변경 |
|---|---|---|
| 시가 갭 | −2 ~ +3% | −2 ~ +6% |
| 30분 변동폭 | 0.5 ~ 2.5% | 0.5 ~ 5.0% |
| 관찰 정원 | 5종목 | 10종목 |
처음에는 "하루치로는 못 정한다"며 미뤘다. 세 가지 근거로 바꿨다.
또한 이 상한은 진입 조건과 모순이었다. 변동폭과 VWAP 이탈폭의 상관 r=0.55이고, 변동폭 2.5% 이하 종목의 절반은 진입 밴드(−1~−2%)에 닿을 수조차 없다.
8/4 재현 기준 관찰 0개 → 4개, 신호 성립 시간 0분 → 35분.
정원 5→10은 매매 횟수와 무관하다 — 진입은 하루 2회로 묶여 있으므로 같은 2번을 더 넓은 후보에서 고르는 것뿐이다. 20이 아닌 이유는 루프 비용이다: refresh_candles 가 종목당 분당 1~2회 호출하며 250ms씩 쉬므로 N종목이면 분당 한 번 루프가 N×0.25~0.5초 길어지고 그동안 손절 확인이 멈춘다. 10이면 오후 최대 5초. 더 늘리려면 분봉 갱신을 루프 밖으로 먼저 빼야 한다.
파라미터를 계속 추정으로 정하지 않기 위해 세 가지를 넣었다.
| 무엇 | 왜 |
|---|---|
replay.py | 보관 분봉으로 룰을 다시 돌린다. 실전과 같은 check_entry/check_exit와 같은 PaperBroker 를 쓴다 — 백테스트용 로직을 따로 두는 순간 PRD §1.5가 지목한 실패(백테스트-실전 괴리)를 우리가 만든다. PRD §10 4주차 게이트가 이것이다 |
| 코스피 분봉 보관 | 진입 조건 C를 재현하려면 분 단위 지수 등락률이 필요한데 장중엔 어디에도 남지 않았다. price_snapshots 에 KOSPI 티커로 넣는다 (price 가 가격이 아니라 등락률%) |
| 분봉 갱신 분리 | 종목마다 그때그때 받던 것을 루프당 2종목으로 묶었다. 관찰 N종목이어도 청산 판정이 멈추는 시간이 일정하다. 한 바퀴 15초라 60초 캐시 안에 든다 |
리플레이는 캔들이 아니라 dynamic_detail 의 판단 시점 실측값에 새 임계값을 적용해 재채점한다. 사후에 API 를 다시 부르지 않으므로 데이터가 정정돼도 그날 판단이 그대로 재현된다.
한계도 분명하다 — 보관이 8/5부터라 8/4 이전은 재생할 수 없고, 1년치 소급은 불가능하다. 정적 필터가 그날의 거래대금 순위·경고 상태에 의존해서 당시 유니버스를 복원할 방법이 없다.
| 순서 | 대상 | 제안 | 시점 |
|---|---|---|---|
| 3 | 조건 C 지수 차단 | −1.0% → −1.5% | 1주 후 |
| 4 | 손절·목표·사이즈 묶음 | −0.6/+3.0/25% → −1.5/+2.5/13% | 2주 후 |
| 5 | 거래량비 하한 | 0.8 → 제거 또는 0.5 | 4 이후 |
3번 — 8/4 진입창 270분 중 차단된 시간: −1.0%면 134분(50%), −1.5%면 46분(17%), −2.0%면 13분(5%). 상수 1개, 결합 없음.
4번이 왜 묶음인가 — 손절 1회 손실 = (손절폭 + 왕복비용 0.38%) × 포지션비중 이라 현재값은 (0.6 + 0.38) × 25% = 자본 −0.245%, 일 한도 −0.5%를 나누면 정확히 2.0회다. 손절만 −1.5%로 넓히면 1회에 −0.47%로 한 번 맞고 그날이 끝난다. 포지션을 13%로 함께 줄여야 한다.
그리고 목표만 낮추는 것은 최악이다. 비용 허들은 왕복비용 / (익절 + 손절) 이라 총폭이 좁아지면 허들이 올라간다.
| 설정 | 총폭 | 손익분기 승률 | 랜덤워크 승률 | 초과 필요 |
|---|---|---|---|---|
| 현재 +3.0 / −0.6 | 3.6 | 27.2% | 16.7% | +10.6%p |
| 익절만 축소 +1.5 / −0.6 | 2.1 | 46.7% | 28.6% | +18.1%p |
| +2.5 / −1.5 | 4.0 | 47.0% | 37.5% | +9.5%p |
현재값 27.2%가 낮아 보이지만 무편향 가정으로도 82% 확률로 먼저 터치되는 손절선과 짝지어진 27%다(일변동성 3.8%, 3시간 보유). 손절폭 확대는 리스크 증가가 아니라 잡음 제거다.
문헌의 VWAP 회귀 표준은 손절을 진입보다 멀리(3SD 바깥), 목표는 평균(VWAP) 복귀에 둔다. 우리는 두 축이 다 뒤집혀 있다.
5번 — 정적 필터가 이미 거래대금 상위 60 + 20일 평균 100억을 요구한다. 유동성 확인이 세 번째다.
dynamic_detail 을 옛 상한(+3 / 2.5)으로 재채점 → 계측 수정분과 완화분 분리판정은 동적 필터 탈락 사유. 밴드는 09:30~14:00 중 조건 A를 만족한 분 수, A+B는 하락 멈춤까지 동시 만족한 분 수.
| 종목 | 시가 | 갭% | 30분폭% | 거래량비 | 판정 | 최저이탈% | 밴드 | A+B |
|---|---|---|---|---|---|---|---|---|
| 셀트리온 | 182,100 | +0.44 | 2.31 | 0.74 | 거래량 | −0.56 | 0 | 0 |
| 삼성중공업 | 20,950 | +1.21 | 2.39 | 0.74 | 거래량 | −1.30 | 6 | 3 |
| 한화오션 | 83,600 | +1.95 | 3.47 | 1.17 | 변동폭 | −1.52 | 7 | 2 |
| 두산에너빌리티 | 68,200 | +2.71 | 6.01 | 1.63 | 변동폭 | −1.29 | 5 | 0 |
| 금호타이어 | 6,590 | +2.49 | 3.19 | 0.31 | 변동폭+거래량 | −1.61 | 8 | 1 |
| 로보스타 | 65,700 | 0.00 | 5.48 | 0.61 | 변동폭+거래량 | −0.52 | 0 | 0 |
| LG전자 | 160,400 | +3.02 | 3.05 | 1.41 | 갭+변동폭 | −1.43 | 2 | 0 |
| 미래에셋증권 | 33,550 | +3.23 | 3.13 | 1.09 | 갭+변동폭 | −2.30 | 35 | 14 |
| 에코프로 | 78,800 | +4.37 | 6.98 | 1.49 | 갭+변동폭 | −2.25 | 44 | 17 |
| SK텔레콤 | 84,900 | +5.07 | 7.77 | 1.12 | 갭+변동폭 | −0.28 | 0 | 0 |
| 이수페타시스 | 76,200 | +5.39 | 3.02 | 1.49 | 갭+변동폭 | −3.52 | 29 | 19 |
| 산일전기 | 150,400 | +6.52 | 4.12 | 0.89 | 갭+변동폭 | −1.95 | 29 | 11 |
| 피에스케이 | 130,200 | +7.43 | 7.45 | 0.88 | 갭+변동폭 | −3.97 | 83 | 42 |
| LS ELECTRIC | 196,200 | +7.57 | 4.54 | 0.72 | 갭+변동폭+거래량 | −2.59 | 23 | 10 |
| 테스 | 133,600 | +8.09 | 5.39 | 0.75 | 갭+변동폭+거래량 | −5.76 | 5 | 4 |
| 두산퓨얼셀 | 27,600 | +8.66 | 5.80 | 0.86 | 갭+변동폭 | −2.78 | 20 | 12 |
| 브이엠 | 67,000 | +8.94 | 8.96 | 0.80 | 갭+변동폭 | −5.09 | 35 | 7 |
| 심텍 | 94,000 | +10.85 | 6.06 | 1.18 | 갭+변동폭 | −3.06 | 39 | 30 |
| 노타 | 21,100 | +15.11 | 7.63 | 3.63 | 갭+변동폭 | −3.44 | 34 | 24 |
| 가온전선 | 154,700 | +17.20 | 8.08 | 4.13 | 갭+변동폭 | −4.17 | 139 | 71 |
| 대주전자재료 | 87,300 | +20.91 | 8.13 | 14.13 | 갭+변동폭 | −4.59 | 29 | 14 |
| 셀바스AI | 11,450 | +22.20 | 8.47 | 3.05 | 갭+변동폭 | −5.22 | 22 | 11 |