필터가 강할수록 좋은 종목을 놓친다 — 오늘 실거래로 확인한 역효과
오늘 아침, 매수 신호가 떴는데 주문이 전부 실패했다.
로그에는 “주문가능금액을 초과했습니다”라고 찍혀 있었다. 잔고 화면에는 62만원이 있었다. KIS는 0원이라고 판단하고 있었다.
원인은 D+2 결제 구조였다. 주식을 사면 금액이 이틀간 묶인다. 그 사이에는 KIS API의 실제 주문가능금액이 0으로 반환된다. 시스템은 전일정산금액을 보고 있었다. 보이는 돈과 쓸 수 있는 돈이 달랐다.
코드를 고치기 전에 실행 경로를 확인해야 한다
오전에 KT 매도 예약 18건이 쌓인 것도 발견했다. 처음엔 main.py를 고쳤는데 문제가 사라지지 않았다.
AI와 실제 실행 경로를 추적해보니 scheduler.py에 장중 5분마다 독립적으로 돌아가는 함수가 따로 있었다. 내가 고친 파일이 실제로 실행되는 파일이 아니었다.
버그는 항상 실제로 실행되는 경로에 있다. 고치기 전에 “지금 어디서 실행되고 있는가”를 먼저 확인해야 한다는 것을 오늘 두 번 확인했다.
필터가 강할수록 좋은 종목을 놓친다
오후에 더 근본적인 문제가 보였다.
코스피는 오르는데 보유 종목은 계속 빠졌다. 삼성전자, SK하이닉스가 매번 스캔에서 걸렸다. 확인해보니 MA20 이격 7% 상한선 때문이었다.
과열 종목을 걸러내려고 만든 필터였다. 그런데 반등장에서 대형주가 MA20 대비 13~14% 올라가는 건 정상적인 현상이다. 그게 과열 신호와 같은 기준으로 묶인 것이다.
보호하려고 만든 장치가 좋은 종목을 막고 있었다.
레짐이 하루 단위로 바뀌면 전략도 하루 단위로 흔들린다
매수·매도 조건 사이에 버퍼도 없었다. MA20 바로 위에서 매수한 종목이 조금만 눌리면 즉시 매도 신호가 나오는 구조였다. KT가 정확히 이 케이스였다.
더 깊은 문제는 레짐 판단이었다. 전일 KOSPI 종가 하나로 강세/중립을 결정하던 방식은 너무 불안정했다. 하루 단위로 레짐이 바뀌면 전략도 하루 단위로 흔들린다.
5가지 조건 점수제로 바꾸고, 2일 연속 같은 신호가 나와야 레짐이 전환되도록 했다. 총자산 기준 현금 보유 비율도 붙였다: 강세 20%, 중립 35%, 약세 60%.
오늘 버그를 고치다가 전략의 구멍을 발견했다.
버그는 코드 문제처럼 보이지만, 그 아래를 보면 API 이해의 문제이거나 시장 구조에 대한 오해인 경우가 많다. 실거래가 아니었으면 드러나지 않았을 것들이다.
다음 주 월요일 확인: 장전 사이클에서 새 레짐 판단이 어떻게 작동하는지 확인한다.