본문 바로가기
AI/작업일지

[260721~22] "환각"인 줄 알았던 버그를 잡고, 첫 실주문을 냈다

by 라베덕 2026. 7. 23.

실거래 준비 마지막 단계라 정신없이 작업하다 보니 그날그날 글 쓸 틈이 없었는데, 그 이틀 안에 데이터 버그 하나와 이 프로젝트의 첫 실거래가 같이 있었습니다

이틀치를 한 번에 묶어서 올립니다. 실거래 준비 마지막 단계라 정신없이 작업하다 보니, 그날그날 글을 쓸 시간이 없었습니다. 그래도 이 이틀 안에 이 프로젝트에서 꽤 중요한 일들이 있어서, 하나로 정리해서 남겨둡니다.

"환각"이라고 생각했던 게, 사실은 버그였다

가격 데이터를 가져오는 곳 하나를 다른 곳으로 바꾸는 작업을 하고 있었습니다. 그런데 바꾸고 나서 이상한 일이 생겼습니다. 장 시작 전인데도 가격 지표가 가끔 며칠 전 값처럼 보이는 경우가 있었습니다.

전에 비슷한 증상을 본 적이 있어서, 처음엔 "AI가 또 이상한 가격을 지어내나 보다"라고 생각하고 넘어갔었습니다. 그런데 이번엔 제대로 파봤더니 원인이 전혀 달랐습니다.

새로 붙인 데이터 출처가 최근 값부터 주는 게 아니라 오래된 값부터 순서대로 주고 있었고, 코드는 그걸 눈치채지 못한 채 맨 앞의 값을 "가장 최근 값"으로 믿고 있었던 겁니다. 순서가 뒤집혀 있었을 뿐인데, 겉으로는 마치 AI가 며칠 전 가격을 오늘 가격이라고 우기는 것처럼 보였던 겁니다.

AI 판단을 의심하기 전에 데이터 순서부터 확인했어야 했다는, 조금 부끄럽지만 확실한 교훈을 얻었습니다. 순서를 명시적으로 확인하고 정렬하도록 고쳤습니다.

자동매매가 반나절 멈췄었다

같은 날 다른 곳에서 코드를 조금 손봤는데, 그 변경이 뜻하지 않게 모의투자(가상 자금) 자동매매 루프를 건드렸습니다. 그날 오전부터 모든 주문이 조용히 거절되고 있었습니다.

원인은 여러 곳에 남겨야 하는 표시 하나가 몇 군데에서 빠져 있었던 것이었습니다. 다행히 실계좌가 아니라 모의투자였고, 다음 매매 주기부터는 저절로 정상으로 돌아왔습니다.

작은 패치로 빠진 표시를 다시 채워 넣었습니다. 실계좌였다면 훨씬 심각했을 종류의 실수라, 이번에 모의투자에서 미리 걸린 게 다행이었습니다.

이제 안 쓰기로 한 증권사, 실거래 경로를 아예 잠갔다

며칠 전 증권사를 옮기기로 한 이야기를 했었는데, 그 뒷정리도 이날 했습니다. 예전 증권사 쪽 실거래 주문 경로를 세 겹으로 막아서, 실수로라도 그쪽으로 진짜 주문이 나갈 수 없게 만들었습니다.

이미 안 쓰기로 한 길인데 어설프게 열어두면 나중에 꼭 사고가 난다는 게 이 프로젝트에서 여러 번 배운 교훈이라, 이번엔 미루지 않고 바로 처리했습니다.

그리고 다음 날, 첫 실주문이 나갔다

실계좌에 아주 적은 금액을 넣고, 종목 하나를 실제로 사고 곧바로 되팔아봤습니다. 그동안 페이퍼(모의)로만 검증하던 경로가 실계좌에서도 처음부터 끝까지 문제없이 도는지 확인하기 위한, 딱 한 번의 왕복 거래였습니다.

주문이 나가고, 체결되고, 그 결과가 장부에 제대로 반영되는 것까지 전 과정이 계획대로 흘러갔습니다. 왕복이라 남은 손익은 매매에 드는 비용만큼의 아주 작은 금액이었고, 애초에 그걸 벌자고 한 거래가 아니었습니다.

전날까지 안전장치를 의심하고 버그를 잡던 게, 결국 이 한 번의 거래를 위한 과정이었습니다. 실거래로 가는 문이 이제 실제로 열렸다는 사실 자체가 이 이틀의 진짜 결과입니다.

그 직전에 잡은 버그 두 개

실주문을 넣기 전에, 계좌를 들여다보기만 하는(주문은 안 내는) 점검을 실계좌로 먼저 돌려봤습니다. 여기서 진짜 문제 두 가지가 나왔습니다.

하나는 잔고나 보유 종목, 주문 상태를 조회하는 코드가 전부 모의투자용 방식 그대로 실계좌에 요청을 보내고 있었던 것이었습니다. 그래서 실계좌 서버가 이 요청들을 전부 거부하고 있었습니다. 조회 방식을 실계좌/모의투자로 나눠서 고쳤습니다.

다른 하나는 체결 여부를 확인하는 로직이 거래 경로 하나만 확인하고 있었던 것이었습니다. 정규 거래시간이 아닌 다른 경로로 체결된 주문은 아예 안 보이는 사각지대였는데, 방치하면 "체결 안 됐다"고 오판해서 같은 주문을 또 낼 위험이 있었습니다. 두 경로를 다 확인하도록 고쳤습니다.

둘 다 돈이 실제로 걸리기 직전에야 잡을 수 있었던 종류의 문제라, 미리 하길 잘했다는 생각이 듭니다.

몇 주짜리 정리 작업의 마지막 조각을 내려놓았다

실거래를 준비하며 병행하던 구조 정리 작업의 마지막 조각 하나도 이날 마무리됐습니다. 가장 위험도가 높다고 판단해서 일부러 맨 뒤로 미뤄뒀던 부분입니다.

막상 열어보니 이미 실거래 경로는 충분히 안전한 상태였습니다. 남아있던 옛 경로는 급하게 다시 만들 필요가 없다고 판단해서, 서두르지 않고 나중으로 미루기로 했습니다. 위험한 걸 서둘러 처리하는 것보다, 위험하지 않다는 걸 확인하고 여유 있게 미루는 쪽을 택했습니다.

그 밖에

  • 이상 상황을 그냥 알려주기만 하던 감시 장치 하나를, 직접 조치까지 하도록 등급을 올렸습니다. 여러 번 리허설을 통과한 뒤에 내린 결정입니다.
  • 데이터 아카이브(새 창) 쪽에 장중 수급 관련 데이터를 모으는 새 수집 통로를 하나 더 열었습니다.
  • 네트워크가 끊기는 상황, 같은 주문이 두 번 나가려는 상황, 급락 시 매매를 멈추는 안전장치까지, 모의투자 환경에서 실제로 상황을 만들어 리허설했습니다. 전부 의도대로 작동했습니다.
  • 코스피와 코스닥에 배분하는 비중을 미리 정해두는 쪽으로 정책을 바꿨습니다. 점수만 보고 한쪽 시장이 배분을 독식하는 걸 막기 위해서입니다.
  • 종목 하나를 여러 번에 나눠 사는 기능을 검토했었는데, 지금 규모에서는 얻는 것보다 복잡도가 더 크다고 판단해서 만들지 않기로 했습니다.

돌이켜보면 이 이틀은 정반대의 감정이 공존했습니다. 하루는 AI의 판단을 의심했다가 알고 보니 데이터 탓이었다는 걸 확인하는 부끄러움이었고, 다음 날은 오래 준비해온 것이 실제로 작동하는 걸 보는 뿌듯함이었습니다.