DayBot

2026-08-19 (수) 회고

노출 0.21%로 얻은 알파 +6.11%p — 이건 이긴 게 아니라 자리에 없었던 것이다

지수가 B&H 기준 −6.21% 무너지는 동안 봇은 시간가중 노출 0.213%로 실현 −0.1069%(2거래 0승)를 냈고, 그래서 당일 알파 +6.108%p·3일 누적 알파 +5.139%p가 찍혔지만 이 숫자는 전략의 성과가 아니라 부재의 기록이다.

1. 지수를 이겼나 — 숫자는 이겼다고 말하지만 비교가 성립하지 않는다

창 bot_pct bench_index_pct bench_bh_pct alpha_pct
20d−0.901 (bot_days 11)−5.1813 (bench_days 3)−5.2484 (bench_days 3)+5.1393 (alpha_days 3)
60d−0.901 (11)−5.1813 (3)−5.2484 (3)+5.1393 (3)

D11의 답을 오늘 찾았다. 알파는 재현된다. 산식은 bot_pct가 아니라 벤치와 정렬된 3일의 봇 실현손익 복리를 쓴다.

항목 계산 값
봇 3일 실현 복리0 · (−0.0022325) · (−0.1069126)−0.10914%
벤치 B&H 3일 복리(+2.4657) · (−1.4011) · (−6.2145)−5.24842%
차−0.10914 − (−5.24842)+5.13928 (보고값 5.1393)

8/18에도 같은 산식이 맞는다: −0.0022325 − (+1.03004) = −1.03227 (보고값 −1.0323). 어제 "재현 불가"라고 쓴 것은 내가 bot_pct(11일 누적)를 알파의 봇 항으로 착각했기 때문이다. D11은 해결로 넘기고, 남는 문제는 산수가 아니라 표시다 — 같은 rolling 표에 11일 누적과 3일 정렬값이 같은 열처럼 놓여 있어 나란히 읽을 수 없다. 이건 새 결함으로 올린다.

exposure_pct_avg = 39.559 = (59.065 + 59.398 + 0.2127) / 3 정확히 일치. 8/14부터 남겨둔 "분모가 무엇인가"의 답도 확정됐다: 벤치 표본일 3일의 단순 평균이다.

그리고 오늘 노출은 0.213%다. 수익률 비교 자체가 성립하지 않는다. exposure_pct의 정의도 오늘 산수로 확정된다:

거래 명목 / 자본 보유 기여
917주 × 1,090 = 999,530원9.995%09:58:36→10:02:48 = 4.2분—
918주 × 1,089 = 999,702원9.997%11:18:19→11:22:25 = 4.1분—
합—8.3분 / 390분(9.995×4.2 + 9.997×4.1)/390 = 0.2127%

보고값 0.212739와 소수점 넷째 자리까지 같다. exposure_pct는 시간가중 명목/자본이다. 즉 오늘 봇은 하루 390분 중 8분만 시장에 있었고, 그 8분에서 돈을 잃었다. 지수가 −6.2% 빠진 것과 봇의 −0.107%는 같은 축에 놓을 수 없는 숫자다.

2. 결과 — 인버스를 두 번 사서 두 번 다 졌다. mfe는 두 건 모두 0.0이다

항목 값
레짐RED_B (09:30:02) · 코스피 −6.378% · 기울기 −0.004%p · 코스닥 −2.406% · 전일 −1.549%
대상114800 KODEX 인버스(1×) 고정
거래 / 승2 / 0 (승률 0%, n=2 — 구간을 낼 수 없다)
총손익 / 비용 / 순손익−10,093원 / −598.26원 / −10,691.26원 (−0.1069%)
누적 실현 / cum_return / MDD−0.901% / −0.9012% / 0.9557% (MDD 변동 없음)
미실현 / mtm_pnl_pct0.0 / −0.1069% (= 실현과 동일)
노출0.2127% (코어 기대 60.0 · 실제 0.0)
워치독 / API 오류0 / 0
관찰정적 27 → 동적 0 (ETF 3종 dynamic_detail: null)
지수최저 −6.777%, 최고 −3.799%
아카이브27종목 10,578봉
시각 일
09:30:02RED_B — 대상 114800 고정
09:58:34신호 1,090 (day_high 1101 · 눌림 0.999% · vwap 1090.98) → 지정가 1,090 / 917주
09:58:36체결 1,090 (2.5초), slippage 0.0
10:02:48trend_loss 1,085 — 순 −4,884.17원 (−0.4886%), mfe 0.0 / mae −0.367
11:18:16신호 1,089 (눌림 1.090% · vwap 1086.30) → 지정가 1,089 / 918주
11:18:19체결 1,089 (3.0초), slippage 0.0
11:22:25trend_loss 1,083 — 순 −5,807.08원 (−0.5809%), mfe 0.0 / mae −0.551

확정되는 것 셋.

(a) 두 진입 모두 한 번도 플러스가 아니었다. mfe_pct가 두 건 다 0.0이다. 눌림 매수(0.999% / 1.090%) 직후 계속 밀려 4분 만에 추세이탈로 나갔다. 지수가 −6.4% 빠지는 날 인버스를 샀는데도 그렇다 — 인버스는 이미 09:58 이전에 고점 1,101을 찍고 내려오는 중이었고, 봇은 그 하락을 두 번 매수했다. n=2다. 규칙을 바꾸지 않고 가설로 넘긴다.

(b) 청산은 손절이 아니라 trend_loss다. 2번 거래 청산가 1,083은 진입 시각 vwap 1086.30 × (1−0.003) = 1083.04와 일치한다. 손절선 −0.6%(1,082.5)에 닿기 전에 추세이탈이 먼저 작동했다. 실전 손절 누적은 7건에서 늘지 않았다.

(c) 비용 구조가 어제와 반대다. 손실 10,691원 중 가격이 10,093원(94%), 비용이 598원(6%). 회당 왕복 약 299원 = 명목의 0.03%로 8/18과 같다. 증권거래세 0(ETF)이다.

3. replay 비교 — v4가 처음으로 실전을 거의 재현했다. v2는 관찰 0으로 전부 무정보

재생 관찰 거래 기대값 순손익
v4 ETF 레짐 (현재 전략)—2−0.627%/거래−62,654원 (−0.63%)
v4 트레일링 끔 (대조군)—2−0.627%/거래−62,654원 (현재 전략과 완전 동일)
v2 반사실 (구 VWAP 회귀)00—표본 없음
v2 트레일링 끔00—표본 없음
v2 옛 유니버스 상한00—표본 없음
v2 3단계 지수차단 −1.500—표본 없음
v2 4단계 손절·익절·사이즈00—표본 없음

(a) D12가 크게 좁혀졌다 — 진입은 2건 모두 일치, 청산은 1건 어긋난다.

실전 재생
1번09:58 1,090 → 10:02 1,085 (−0.4886%)09:59 1,090 → 10:02 1,085 (−0.49%)
2번11:18 1,089 → 11:22 1,083 (−0.5809%)11:18 1,089 → 11:22 1,081 (−0.76%)

거래 건수·종목·진입가·진입 분이 맞는다. 어긋난 것은 2번의 청산가 2틱이고, 그 방향은 재생이 더 깊다 — D5(재생 손절 실행가가 파라미터보다 깊다)와 같은 방향이다. 다만 D5는 파라미터 대비 비교이고 오늘 것은 재생 대 실전 비교라 표본을 합산하지 않는다. 청산가가 vwap−0.3%에서 결정되므로 재생의 vwap 계열이 실전과 미세하게 다르다는 정황이다. D12는 해결로 올리지 않는다.

(b) 재생 규모가 실전의 6배다. 재생 누적 −62,654원(−0.63%) 대 실전 −10,691원(−0.107%). 거래·가격이 같은데 손익 규모가 다르다 — 재생 사이징이 자본 10%가 아니라는 뜻으로 읽히나 원자료에 재생 사이징 값이 없어 확인하지 못했다.

(c) 재생과 실전의 가드 입력값이 다르다. 실전 레짐 prev_close_pct −1.5493, 재생 출력 "가드 통과(전일 −1.63%)". 같은 날 같은 판정을 같은 입력으로 하지 않고 있다. 오늘은 둘 다 가드 통과라 결과가 같았지만, 가드 임계 −3.0 근처에서는 판정이 갈린다. n=1로 확정되는 결정론적 불일치다 — 결함으로 올린다.

(d) 트레일링 대조군은 오늘 차이 0. 두 거래 다 mfe 0.0이라 무장선 3.0%에 근처도 못 갔다. 차이 발생 거래 n=0 — 가설 7에 정보를 더하지 못했다.

(e) v2는 관찰 0종목이다. 그런데 이게 오늘 가장 좋은 소식이다. 재생 탈락 사유 개수와 실전 watchlist의 reject 개수가 완전히 일치한다.

사유 재생 실전 watchlist 집계
거래량1515
갭1212
변동폭99
데이터부족33 (ETF 3종 dynamic_detail: null)

27종 전부 설명된다. 8/14의 9 vs 8 불일치는 이틀 연속 재현되지 않았고, 오늘은 개수가 아니라 사유별 분해까지 맞았다. 가설 5는 유지하되 유리한 방향의 표본이 하나 더 쌓였다.

(f) 대상 114800은 passed_dynamic 0 · dynamic_detail null인데 거래됐다. ETF는 동적 필터를 우회하고 레짐이 직접 지정한다 — 사흘째 같은 형태이고, 설계로 읽히나 원자료에 명시가 없다.

4. 조건 C — 271분, 진입창 100%를 막았다는데 그 안에서 2건이 체결됐다

blocked_minutes = 271, 임계 −1.0%, 지수 최저 −6.777% · 최고 −3.799%.

날짜 blocked 진입창(271분) 기준 지수 최저
8/7271분100%−6.51%
8/10~8/140~4분0~1.5%−1.36 ~ +2.59%
8/1826분9.6%−2.642%
8/19271분100%−6.777%

진입 2건(09:58·11:18)은 09:30~14:00 창 안이다. 차단이 271분 전부라면 이 두 건은 성립할 수 없다. 즉 지수차단은 etf_regime_pullback 경로에 적용되지 않는다 — 매도일에 인버스를 사는 전략이므로 설계일 가능성이 크지만, 그렇다면 blocked_minutes는 실제로 거래하는 경로와 무관한 지표이고 8/7 이후 열흘간 이 값을 읽어온 것이 전부 헛것이다. n=1로 확정되는 모순이라 결함으로 올린다.

3단계 조건(−1.0~−1.5 구간 체류 중 진입 성립 1회)은 오늘도 미충족이다. 지수가 하루 종일 −3.80% 아래에 있어 그 구간을 지나가지도 않았다. 11거래일 연속 미충족.

5. 미해결 결함 — 12건, probe 12건 실행, 그중 5건은 형식 때문에 답이 없다

ID 나이 요약 probe 결과 판정
D13일 · stale코어가 산 379800이 watchlist에 없다미해결. sql:core_orders가 사흘째 8/14 2행만 반환. 막는 것: 등록된 probe 중 코어 후보군을 답할 수 있는 질의가 없다.
D23일 · stale코어 지정가가 신호가보다 위판정 불가. 같은 probe가 주문가를 찍지 않는다. 위와 동일한 이유로 막혀 있다
D33일 · stalecum_return과 rolling 계열의 미실현 포함 여부가 다르다실행 불가(3일째). probe 문자열에 설명문이 붙어 있다. 오늘 정황: 미실현 0이라 mtm_pnl_pct = net_pnl_pct = −0.1069로 완전 수렴, cum(−0.9012)은 복리 누적으로 확인됨
D43일 · stale체결가=주문가인데 slippage null미해결, lab은 정상. 오늘 lab 2건 slippage 0.0. null은 코어 경로 한정 정황이 이틀째
D53일 · stale재생 손절가가 파라미터보다 깊다실행 불가. probe 종류가 허용 목록(tick·sql) 밖. 오늘 손절 표본 0건이라 누적 12건에서 늘지 않음
D72일코어 노출 격차 −60.0%p미해결. sql:core_exposure가 8/19·8/18 모두 −60.0%p, 8/14만 −1.1%p로 답했다. 코어는 8/14 이후 이틀 연속 0%다
D82일exposure_pct와 core_actual_pct가 서로를 부정오늘은 모순 없음. 노출 정의(시간가중)가 확정됐고 오늘은 lab만으로 0.2127%가 정확히 재현된다. 8/18의 59.398 대 0.0 모순은 그대로 남는다
D92일8/18 복원 코어 2종의 청산이 trades에 없다미해결. 오늘은 order 4 / fill 4로 lab 2거래와 정확히 맞아 잔여 주문이 없다. 8/18의 잔여 2건은 여전히 설명되지 않음
D102일mtm_pnl_pct가 실현·미실현 어디에도 없다실행 불가. 오늘은 세 값이 일치해 재현 안 됨 — 코어 보유가 있는 날에만 나타나는 정황
D112일alpha_pct를 재현할 수 없다해결. 위 1장 산식으로 8/18·8/19 두 날 모두 소수점 넷째 자리까지 재현
D122일v4 재생이 실전을 재현하지 못한다미해결, 크게 좁혀짐. 진입 2/2 일치, 청산 1/2 불일치(1,083 대 1,081). probe sql:unfilled_orders는 "건수 0"만 답해 질문에 답하지 않는다
D132일probe 칸에 설명 문장을 넣어 실행 불가미해결, 원인 확정. 오늘도 D3·D5·D10·D11·D13 다섯 건이 "허용되지 않은 probe 종류"로 반환됐다

D13이 막힌 이유가 오늘 확정됐다. 회고 규칙은 "자동화할 수 없으면 사람이 할 확인을 한 문장으로 쓴다"고 하는데, probe 실행기는 tick·sql 두 종류만 받는다. 그래서 사람 확인용으로 쓴 문장은 등록은 되지만 매일 실행 불가로 되돌아온다. 규칙과 파서가 충돌한다. 사람 확인이 필요한 결함은 probe가 영원히 답하지 않으므로, 내가 본문에서 직접 판정하고 근거를 적는 방식으로 처리한다. D1·D2는 그 반대 경우다 — 등록된 질의를 썼는데 그 질의가 질문에 답하지 않는다. 사흘째 같은 2행을 받고 있고, 이건 결함 나이만 늘리는 짓이다.

stale_days = 3, D1~D5가 stale: true. 이 다섯 건은 전부 8/14에 열렸고 사흘 동안 한 걸음도 못 갔다. 회고의 실패다.

6. events — 22건, 경고 0건

type/level n
bot INFO5
fill INFO4
order INFO4
universe INFO3
report INFO2
watchdog INFO2
archive · gate INFO각 1

order 4 / fill 4 / cancel 0이 lab 2거래(진입·청산 각 2)와 정확히 맞는다. 8/18의 잔여 2주문·2체결 같은 잉여가 없다. 수천 건짜리 루프 징후 없음.

warnings가 빈 배열인 것이 오히려 문제다. 어제는 15:40에 봇이 스스로 코어 노출 격차 −60.0%p를 WARN으로 찍었다. 오늘 sql:core_exposure는 8/19에도 격차 −60.0%p라고 답했는데 경고가 없다. 같은 조건에서 자기 진단이 발화하지 않았다. 결함으로 올린다.

7. 내일 확인할 것

  • 코어가 8/14 이후 왜 한 주도 안 사는가. 목표 60%가 이틀 연속 0%인데 주문 기록도 없다
  • 지수차단이 ETF 레짐 경로에 적용되는가. 적용되지 않는다면 blocked_minutes를 무엇에 쓰는가
  • 재생과 실전의 전일 지수 등락률(−1.63 대 −1.55)이 왜 다른가
  • 재생 사이징. 같은 2거래에서 손익 규모가 6배다
  • RED_B 눌림 매수가 인버스 하락 구간을 잡는 빈도

조치 — 파라미터는 바꾸지 않는다

실현 표본은 오늘 2건, 누적 11건(2승, 승률 18.2%, n=11)이다. 오늘 얻은 것은 전부 정의 확정과 재현이지 통계가 아니다. n<500에서 눌림폭·추세이탈·손절·상한을 건드리지 않는다.

단계 조건 현재
3 조건 C −1.5지수가 −1.0~−1.5 구간에 머문 분에 진입 성립 1회지수가 하루 종일 −3.80% 아래 — 구간을 지나지 않음. 미충족 (11거래일 연속)
4 손절 −1.5실전 손절 10건 누적7건 (오늘 0건 — 2건 모두 trend_loss)
4 익절 +2.5고점 +3.0% 도달 거래 1건0건. 오늘 최대 mfe 0.0%
5 거래량비재생이 실전을 재현한 뒤 판정조건부 진전 — 유니버스는 탈락 사유까지 완전 일치, v4 진입 2/2 일치, 청산 1건 불일치. 거래 표본이 v2 0건이라 여전히 보류

11거래일 정리

날짜 전략 레짐 실현 거래 승 실현 순손익률 노출 지수 최저
8/4v2—0—0%—−2.83%
8/5v2—20−0.42%—+4.57%
8/6v2—20−0.25%—−1.82%
8/7v2—0—0%—−6.51%
8/10v2—20−0.232%—−0.987%
8/11v4RED_B0—0%—−1.363%
8/12v4GREEN11+0.118%—+1.164%
8/13v4FLAT0—0%—+2.588%
8/14v4 + coreFLAT0—0%59.07%+0.525%
8/18v4 + coreGREEN21−0.0022%59.40% / 0.0%−2.642%
8/19v4RED_B20−0.1069%0.21% / 코어 0.0%−6.777%

누적 11거래 2승 9패, 실현 −0.901%, cum −0.9012%, MDD 0.9557%(변동 없음).

오늘 얻은 것은 계측 세 개의 확정이다: 알파 산식(3일 정렬·봇 실현 복리), 노출 정의(시간가중 명목/자본), 유니버스 재생 일치(사유별 개수까지). 잃은 것은 명확하다 — 지수가 6% 무너지는 날 인버스를 지정받고도 두 번 다 mfe 0.0으로 졌고, 코어는 이틀째 아무것도 사지 않았으며, 진입창 100%를 막았다는 차단 지표 안에서 거래가 두 건 나갔다. +6.11%p 알파는 실력이 아니라 8분짜리 참여의 부산물이다.


진화 블록

종류 내용 검증
결함조건 C 차단 271분(진입창 100%) 안에서 진입 2건이 체결됐다 — 지수차단이 etf_regime_pullback 경로에 적용되지 않는다사람이 지수차단 조건이 ETF 레짐 진입 경로에 적용되는지 코드에서 확인하고 적용되지 않으면 blocked_minutes 지표의 대상 경로를 명시한다
결함재생과 실전의 전일 지수 등락률이 다르다 — 실전 가드 입력 −1.55% 대 재생 출력 −1.63%사람이 실전 레짐 판정과 replay_etf.py 가 전일 종가를 같은 소스에서 읽는지 확인한다
결함코어 노출 격차 −60.0%p가 이틀 연속인데 오늘은 WARN 이 없다 — events.warnings 빈 배열sql:core_exposure
결함rolling 블록의 bot_pct 는 11일 누적인데 alpha_pct 는 벤치 정렬 3일 실현치라 같은 표의 두 값을 나란히 읽을 수 없다사람이 rolling 출력에 알파 계산에 쓰인 봇 3일 실현치를 별도 필드로 찍게 한다
가설RED_B 인버스 눌림 매수가 하락 중인 인버스를 잡는가 — 오늘 2건 모두 mfe 0.0 으로 진입 후 한 번도 플러스가 없었다60거래일 재생에서 RED_B 일과 GREEN 일의 진입당 기대값과 mfe 0 비율을 분리 비교
가설trend_loss(VWAP−0.3) 청산이 손절선 −0.6 보다 먼저 작동하는데 이 규칙이 기대값을 개선하는가 — 오늘 2건 모두 손절 전 추세이탈로 평균 −0.53%60거래일 재생에서 TREND_EXIT 0/1 격자로 기대값과 청산 사유 분포를 비교
가설노출이 0.2%인 날의 알파 +6.11%p 를 누적 알파에 그대로 합산해도 되는가60거래일 표본에서 일별 알파와 exposure_pct 의 상관을 보고 노출가중 알파와 단순 알파를 대조
해결D11알파 = 벤치 정렬일의 봇 실현 복리 − 벤치 B&H 복리. 8/19 −0.10914 −(−5.24842)= +5.13928(보고 5.1393), 8/18 −0.0022325 −(+1.03004)= −1.03227(보고 −1.0323)