KIS 자동매매 — 모듈 캐시 이슈 확인 및 매수 사이클 복구
날짜: 2026-04-09
장전 08:50 사이클은 정상적으로 돌고 있었다. 그런데 매수 단계에서 계속 같은 메시지가 떴다. “시장 레짐 불량 — 매수 전체 스킵.”
원인 파악
처음엔 전략 조건을 너무 빡빡하게 잡은 줄 알았다. 하지만 조건이 문제가 아니었다. 실행 중인 스케줄러 프로세스가 수정 전의 rule_engine.py를 메모리에 그대로 들고 있었다. 파일은 바뀌었지만, 프로세스는 어제 상태로 계속 돌고 있었던 것이다.
수정 내용
원인을 확인한 뒤 is_market_ok()에 진단 로그를 추가해 실제 분기 경로를 들여다봤다. 모의투자 환경에서는 KIS API의 30일 제한 때문에 MA60이 비어 있는 경우가 생기는데, 기존 로직은 이때 무조건 False로 처리해 매수 사이클 전체를 막고 있었다. IS_PAPER=True일 때 MA60=None이면 종가 > MA20 기준으로 폴백 판정하도록 수정했다.
개별 종목 스캔의 check_buy_signal()도 같은 문제였다. MA60이 없으면 전부 “데이터 부족”으로 스킵 처리했기 때문에, 모의투자 환경에서는 MA20과 RSI가 정상 계산되는 종목도 전혀 걸러지지 않고 있었다. 모의투자에서는 MA60 조건을 건너뛰고 나머지 조건으로 판단하도록 보완했다. BUY 사유 문자열에서 MA60=None일 때 발생하던 포맷 오류도 함께 잡았다.
DRY_RUN 결과
수정 후 새 프로세스로 DRY_RUN을 다시 돌렸다.
- 레짐 진단: MA60=None + IS_PAPER=True → 종가 > MA20 경로로 매수 가능 판정
- 삼성전자, LG화학: BUY 신호 확인
- SK하이닉스: 주당 가격이 높아 현금 한도 초과 → PASS
- 카카오: 현재가가 MA20 아래 → PASS
- 이후 최대 보유 종목 수 제한에 걸려 스캔 종료
DRY_RUN이라 실제 주문은 없었지만, 매수 신호 판단과 스캔 흐름 자체는 정상으로 돌아왔다.
운영 규칙 정리
오늘 코드 작업과 함께 하나의 운영 규칙이 명확해졌다. 코드를 수정했으면 반드시 스케줄러를 재시작해야 한다. 이를 docs/SOP_scheduler_restart.md로 신규 작성했고, README, PROJECT_STATUS, ARCHITECTURE, devlog에도 반영했다.