자동매매 봇이 하루 종일 죽어 있었는데, 감시는 “이상 없음”이라고 했다

봇은 새벽부터 죽어 있었습니다. 그런데 그걸 감시하라고 만들어둔 프로그램은 하루 종일 ‘이상 없음’을 출력하고 있었습니다.

봇 헬스체크를 돌리다가 알았습니다. 화면을 보고 처음 든 생각은 하나였어요.

“아 망했다.”

그날 자동매매 봇은 아침부터 한 건도 주문을 내지 못했습니다. 데이터도 하나도 쌓이지 않았고요. 그런데 감시 화면에는 이렇게 찍혀 있었습니다.

“[health] 자동수집 전부 FRESH — 이상 없음.”

원인은 허무했습니다

증권사 API 키가 만료됐습니다. 모의투자용 키는 발급일로부터 3개월이 유효기간인데, 5월 초에 받은 키가 8월 5일 새벽에 수명을 다한 겁니다. 갱신 알림 같은 건 따로 오지 않습니다. 그냥 어느 날 아침부터 안 됩니다.

시각 무슨 일
8/4 17:50 마지막 정상 동작 (데이터 200건 적재, 오류 0)
8/5 06:30 첫 인증 실패. 봇이 기동하자마자 즉사
8/5 08:25~17:50 장중 수급 수집 9회 시도, 전량 0건
8/5 15:50 테마 수집 실패
8/5 17:30 백필 작업 인증 실패
8/6 06:30 키 교체 후 정상 복구

에러 메시지도 분명했습니다. 인증에 실패했습니다[8001:App Key와 Secret Key 검증에 실패했습니다]. 로그를 열면 이 줄이 하루 종일 쌓여 있었습니다. 숨어 있던 게 아니라 대놓고 찍혀 있었어요.

그런데 감시는 그걸 못 봤습니다.

감시가 왜 못 봤나

나중에 뜯어보니 구멍이 하나가 아니었습니다. 세 가지가 겹쳤습니다.

🕳️ 감시 목록에 없었다
자동 감시가 보고 있던 건 다른 네 개뿐. 정작 매매하는 쪽이 목록에서 빠져 있었습니다
📄 ‘실행됨’을 ‘정상’으로
로그 파일이 오늘 날짜로 써졌는지만 확인. 실패해도 로그는 써집니다
↩️ 배치가 실패를 감췄다
윈도우는 마지막 명령 기준으로 성공을 판단합니다. 마지막 줄이 echo였습니다

두 번째가 특히 얄궂었습니다. 감시 로직이 확인하는 건 “오늘 날짜로 로그가 생겼는가”였습니다. 그런데 프로그램이 실패해도 로그는 생깁니다. 에러 메시지로 가득 찬 파일이 쌓이고 있었는데, 감시는 그걸 보고 “오늘도 잘 돌았네”라고 판단한 겁니다.

세 번째는 이렇게 생긴 문제였습니다. 배치 파일 마지막 두 줄이

py 스크립트실행 >> 로그
echo ----- 종료 ----- >> 로그

이렇게 돼 있었습니다. 윈도우는 배치 파일의 성공·실패를 마지막 명령 기준으로 잡습니다. 마지막이 echo니까 결과는 언제나 성공이었어요. 실제 프로그램이 어떻게 끝나든 스케줄러에는 늘 “정상 종료”로 기록됐습니다.

여기까지는 고치면 되는 것들

진짜 문제는 따로 있었습니다

위의 셋은 기술적인 실수입니다. 찾아서 고치면 끝나는 것들이죠. 이번 일에서 제일 뼈아팠던 건 그게 아니었습니다.

감시 시스템을 AI에게 만들게 하고, 그 뒤로는 결과만 봤습니다. 만들 때 “이게 진짜 다 보고 있나”를 확인하지 않았어요. 너무 믿었습니다.

그 대가가 이렇게 나왔습니다. 사고를 정리하다가 8거래일 연속으로 거짓 보고를 받고 있었다는 걸 알았습니다. 매일 저녁 텔레그램으로 “오늘 거래 없음”이라는 요약이 왔는데, 실제로는 8월 3일과 4일에 체결이 있었습니다. 봇은 거래를 했고, 저는 안 했다고 보고받았습니다.

이유는 경로 하나였습니다. 거래 기록을 읽어오는 파일 위치가 존재하지 않는 폴더를 가리키고 있었어요. 파일이 없으니 “거래 없음”으로 처리됐고, 그게 매일 알림으로 나갔습니다.

8거래일
거짓 ‘거래 없음’ 보고
3주
다른 봇의 무거래 기간
0건
사고 당일 실제 매매

여기서 스스로에게 물어봤습니다. 8일 동안 매일 그 알림을 받으면서 한 번도 이상하다고 느끼지 않았나?

못 느꼈습니다.

다른 봇 하나는 3주 동안 거래가 한 건도 없었습니다. 그것도 별다른 생각 없이 넘어갔습니다. 나중에 확인해보니 이건 실제로 정상이었습니다. 시장 조건이 진입 기준에 안 맞아서 설계대로 막고 있었어요. 고장이 아니었습니다.

문제는 제가 그 둘을 구분할 방법이 없었다는 겁니다. 하나는 진짜 정상이고 하나는 거짓 보고인데, 둘 다 똑같이 “거래 없음”으로 보였습니다. 그리고 저는 어느 쪽도 의심하지 않았습니다.

3주 무거래는 왜 정상이었나

이건 따로 확인해볼 가치가 있었습니다. 그 봇에는 시장이 나쁠 때 아예 안 들어가는 장치가 걸려 있습니다. 조건이 두 개인데, 둘 다 통과해야 매매를 시작합니다.

조건 보는 것 사고 당시
① 지수 추세 코스피가 200일 이동평균선 위에 있는가 통과 (6,358 > 5,761)
② 시장 폭 오르는 종목 비율이 절반을 넘는가 미달 (20.1%)
최종 둘 다 통과해야 진입 차단

지수는 위에 있었지만 오르는 종목이 다섯 중 하나뿐이었습니다. 지수만 몇 개 대형주가 끌어올리고 나머지는 빠지는 장이었던 거죠. 이런 국면에서 단기 매매를 하면 지수는 멀쩡한데 내 종목만 깨지기 쉽습니다. 그래서 막았습니다.

즉 3주 침묵은 고장이 아니라 설계대로 작동한 결과였습니다. 그런데 저는 그걸 확인해서 안 게 아니라, 사고를 조사하다가 우연히 알았습니다. 결과적으로 맞았을 뿐이지 제가 판단한 게 아닙니다.

부수적으로 하나 더 알게 됐습니다. 봇이 죽어 있던 8월 5일에는 이 시장 판정 자체가 새로 계산되지 않았습니다. 그래서 판정값이 전날 것에 멈춰 있었습니다. 이번엔 “진입 금지” 상태라 무해했지만, 반대로 “진입 허용” 상태에서 멈췄다면 며칠간 옛 판정으로 매매할 수도 있었다는 뜻입니다.

침묵보다 거짓 안심이 위험합니다

⚠️ 주의 알림이 안 오면 사람은 불안해서 확인합니다. 그런데 ‘이상 없음’이 매일 꼬박꼬박 오면 확인할 이유가 사라집니다. 감시가 있다는 사실 자체가 안심을 만들고, 그 안심이 확인을 대신해버립니다.

이번 일을 정리하면서 남은 게 이겁니다. 감시를 붙였다는 것만으로 마음이 놓였고, 그 마음이 눈으로 확인하는 일을 밀어냈습니다.

무엇을 고쳤나

  • ✓매매하는 봇들을 감시 대상에 실제로 편입 (목록에 없던 게 원인이었으니)
  • ✓판정 기준을 바꿈 — ‘로그가 써졌는가’가 아니라 ‘오늘 인증 실패 줄이 몇 개인가’
  • ✓배치 파일이 실제 종료 코드를 넘기도록 수정
  • ✓거짓 보고를 하던 기록 경로를 실제 파일로 교체
  • ✓키 발급일을 파일에 기록하고 만료 14일 전부터 경고

그리고 하나를 새로 만들었습니다. 평일 아침 9시 5분 점검입니다.

기존 점검은 밤에 돌았습니다. “어제 잘 돌았나”를 확인하는 용도죠. 그런데 이번 사고는 새벽 6시 30분에 이미 판별 가능한 상태였습니다. 밤에 알아봐야 그날 장은 끝난 뒤입니다.

그래서 아침 점검은 목적을 다르게 잡았습니다. 인증 실패만 봅니다. 데이터가 최신인지는 안 봐요. 그건 장 끝나고 만들어지는 값이라 아침에 확인하면 거짓 경보만 납니다. 아침 점검의 목적은 진단이 아니라 그날 장을 구제하는 것입니다.

고치면서 알게 된 게 하나 더 있습니다. 기존 밤 점검이 오후 5시에 돌고 있었는데, 정작 데이터를 만드는 작업 하나는 5시 25분에 끝났습니다. 감시가 생산보다 먼저 도는 구조였던 거죠. 이 상태에서 그 작업을 감시 목록에 넣었다면 매일 “데이터 없음” 경보가 울렸을 겁니다. 그리고 매일 울리는 경보는 며칠이면 무시하게 됩니다. 점검 시각을 밤 10시로 옮겼습니다.

거짓 안심이 위험한 만큼, 거짓 경보도 결국 같은 곳으로 갑니다. 둘 다 사람이 화면을 안 보게 만듭니다.

키 만료도 이제 미리 알려줍니다. 발급일을 파일에 적어두고 만기 14일 전부터 경고가 뜨게 했습니다. 실제로 날짜를 앞뒤로 바꿔가며 D-14, D-4, 당일, 만료 후까지 네 번 다 알림이 오는지 확인했습니다. 이번처럼 어느 날 아침에 갑자기 죽는 일은 없어야 하니까요.

돈은 안 잃었는데 신경이 쓰였습니다

솔직히 이 사고로 손실을 본 건 아닙니다. 모의계좌로 돌리고 있었고, 그날은 매매 자체가 0건이었으니까요.

그런데도 계속 마음에 걸렸습니다. 모의로 검증을 쌓아서 실거래로 넘어갈 계획이었는데, 그 일정이 밀리는 게 아까웠습니다. 하루치 기록이 통째로 비면 그만큼 검증이 늦어집니다.

복구가 안 되는 것도 있었습니다. 장중 수급 데이터는 그 시각에만 존재하는 값이라 나중에 다시 받을 수가 없습니다. 종가는 장 끝나고도 조회되지만, “오전 10시에 외국인이 얼마를 사고 있었나”는 그 시각을 놓치면 영영 못 채웁니다. 8월 5일치는 지금도 비어 있습니다.

그래서 자동화를 믿는 정도가 달라졌습니다

이번 일 이후로 믿음이 많이 사라졌습니다.

그런데 이 이야기를 정리하다가 생각난 게 있습니다. 저는 봇을 만들고 감시까지 붙여놓고도 이렇게 됐는데, 사실 더 오래된 게 하나 있더군요.

“나도 자동이체 걸어놓고 몇 년째 안 봤다.”

자동이체, 적립식 자동매수, 자동 리밸런싱. 한 번 걸어두면 알아서 돌아가니까 신경을 끄게 됩니다. 그게 자동화를 쓰는 이유이기도 하고요.

다만 이번에 확인한 건, “조용하다”가 “잘 돌아간다”는 뜻은 아니라는 것입니다. 제 경우엔 조용한 정도가 아니라 매일 “이상 없음”이라고 말해주기까지 했습니다. 그래서 더 안 봤고요.

자동이체가 잔액 부족으로 몇 달째 실패하고 있어도, 적립식 매수가 어느 달부터 안 들어가고 있어도, 알림이 안 오면 모릅니다. 가끔은 자동화가 뭐라고 말하는지가 아니라, 계좌를 직접 열어봐야 합니다. 저도 이번 주말에 자동이체부터 볼 생각입니다.

금융거래 자동이체·자동납부 관련 소비자 정보는 금융감독원에서 확인할 수 있습니다.

관련 글: 자동매매 봇 여정 #10 — 100건의 길 · 자동매매로 돈 못 버는 이유

이 글은 개인의 운영 기록을 정리한 것으로, 특정 서비스나 상품을 권유하지 않습니다. 언급된 시각·수치는 자체 로그 기준이며, 자동이체·자동투자 설정은 각 금융기관 안내를 확인하세요. 최종 판단과 책임은 본인에게 있습니다.

댓글 달기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

위로 스크롤