퀀트 / 트레이딩8 분 읽기

표본을 다 채우기 전에 봇을 껐습니다 — 이겨도 마찰이 다 먹는다는 게 확정돼서

내부자 매수 추종 페이퍼 봇을 32건에서 종료했습니다. 졌기 때문이 아닙니다. 부호검정 p=0.110으로 졌다고 말할 근거도 없었습니다. 초과수익 신뢰구간의 상한이 왕복 마찰선 아래로 확정됐기 때문입니다.

#quant-trading#reality-check#first-principles#verification
왼쪽은 부트스트랩 95% 신뢰구간 마이너스 3.64에서 플러스 0.61까지가 최소효과 1.0%p 선에 닿지 못하는 그림, 오른쪽은 사전등록 문서의 중단 조항
이길 수 있는 최대치조차 마찰선 아래였습니다.

당신의 실험에는 "이겨도 의미 없음"을 선언하는 조항이 있습니까? 지는 걸 감지하는 조항 말고요.

오늘 페이퍼 트레이딩 봇 하나를 껐습니다. SEC Form 4의 내부자 매수를 읽고 5거래일 홀딩으로 드리프트를 먹으려던 봇입니다. 화요일부터 토요일까지 매일 정오에 돌았고, 벤치마크는 SPY였습니다. 완결 표본 32건에서 종료했습니다.

숫자부터

항목
완결 표본 32건 (미결 9, 관측 2026-07-22 ~ 08-27)
승률 34.4% (11/32)
평균 SPY 초과 −1.58%p
누적 PnL −$449.25
부호검정 p 0.110
부트스트랩 95% CI [−3.64, +0.61]%p

여기서 흔한 오독은 "승률 34%에 −$449니까 졌다, 그래서 껐다"입니다. 틀렸습니다. 부호검정 p는 0.110입니다. 졌다고 말할 근거도 없습니다. 32건은 이 분포에서 아무것도 증명하지 못합니다.

그럼 왜 껐나

3주 전에 게이트를 다시 쓰면서 중단 조항을 하나 박아뒀습니다.

FUTILITY(중단) — 초과수익 신뢰구간의 상한 < 최소효과(MDE). 이 조항은 최소표본 이전에도 발화한다.

최소효과는 데이터에서 뽑은 게 아니라 사전에 박은 값입니다. 명목 $1,000/건, 홀딩 5거래일, 편도 5bp면 왕복 마찰이 0.1%p, 슬리피지를 넉넉히 보태도 0.3%p 안쪽입니다. 동시 6포지션이면 연간 슬롯이 약 313건. 여기서 MDE = +1.0%p/건으로 고정했습니다. 이 아래면 마찰 대비 남는 게 없어서 돌릴 이유가 없다는 선입니다.

오늘 CI 상한은 +0.61%p였습니다. 이 전략이 가질 수 있는 최선의 경우조차 1.0%p 선에 닿지 못한다는 뜻입니다. 승패의 문제가 아니라, 이겨도 마찰이 다 먹는다는 게 데이터로 확정된 상태입니다.

당신이라면?

미결 9건이 남아 있었습니다. 그리고 이 표본의 표준편차 6.24%p 기준으로 유의한 판정에 필요한 표본은 306건, 완결 페이스로 1년이 넘습니다. 게다가 페이퍼 운영비는 0입니다. 그냥 계속 돌리시겠습니까, 아니면 지금 끄시겠습니까?

저는 껐습니다. 1년을 더 굴려서 얻는 건 "마찰 이하 효과"를 더 정밀하게 아는 것뿐이기 때문입니다. 정밀해진 0은 여전히 0입니다.

v1 게이트였다면 아직도 돌고 있었다

이 봇의 첫 게이트는 이랬습니다. 완결 n≥30 AND 평균수익>0 AND SPY초과>0.

부호만 보는 규칙입니다. 같은 데이터를 이 규칙에 넣으면 "n=32는 채웠지만 평균이 음수니 아직 통과 아님 → 계속"이 나옵니다. 중단 조항이 없으니 영원히 계속입니다. 표본이 쌓여도 답이 안 나오는 이유는 규칙에 크기 개념이 없어서인데, 규칙은 그 사실을 스스로 말하지 못합니다.

같은 실수를 앞서 한 번 했습니다. 다른 봇을 끄면서 쓴 회고에서 게이트 결함으로 "착수 전 검정력 계산 부재"를 적어뒀는데(검정력 없는 실험), 그때 배운 걸 이 봇의 v2에 옮긴 것이 오늘 종료를 가능하게 했습니다. 판정을 못 내리는 게이트는 분모가 없는 게이트와 같은 병입니다.

자가진단 3개

지금 돌리는 실험·A/B·페이퍼 전략에 이 셋이 있는지 보세요.

  1. 최소효과(MDE)가 착수 전에 숫자로 박혀 있는가? 없으면 사후에 관측값을 보고 "이 정도면 의미 있다"를 만들게 됩니다.
  2. 중단 조항이 있는가? PASS 조건만 있는 게이트는 실패를 선언할 방법이 없어서 무한히 연장됩니다.
  3. 필요 표본을 매 실행 다시 계산해 보여주는가? 표준편차가 커지면 필요 표본도 커집니다. 그 숫자가 커지고 있다는 것 자체가 "신호 대 잡음이 나쁘다"는 정보입니다.

끄는 것도 절차입니다

launchd 잡 2개(daily·대시보드)를 bootout하고 plist를 지웠습니다. 포트가 실제로 죽었는지 lsof로 확인했습니다. 리포는 원장 SQLite를 포함해 42MB tar로 아카이브한 뒤 원본을 지웠습니다 — 나중에 이벤트 드리프트를 다시 볼 일이 생기면 데이터는 그대로 있습니다.

그리고 남은 대시보드 세 곳에서 죽은 링크를 지웠습니다. 이걸 빼먹으면 몇 주 뒤에 자기가 만든 404를 클릭하게 됩니다. 봇을 끄는 절차 자체는 예전에 한 번 정리해뒀습니다.

솔직한 부분

이 봇은 5주를 돌았고, 결과는 "이 전략에 엣지가 있는지 모르겠다"입니다. 알아낸 건 하나뿐입니다 — 알아내려면 306건이 필요하고, 그동안 기대할 수 있는 최대치는 마찰보다 작다. 그건 전략에 대한 지식이 아니라 이 실험에 대한 지식입니다. 그래도 5주 만에 안 게 2.6년 뒤에 아는 것보다 낫습니다.

지금 돌리는 실험 하나를 골라서, 중단 조항 한 줄을 오늘 적어보세요. "얼마 아래면 이겨도 그만둔다"의 그 얼마를, 데이터를 보기 전에요.

관련 글