회고EthiBot

EthiBot v4.1 - 슬롯을 계좌로 바꾸고, 사후 보정 지옥을 건너다

v4는 돌아갔다. 진짜 문제는 '매주 빠짐없이 돌리는 것'이었다.
📅 2026.07.21⏱ 읽기 약 8
EthiLab알고리즘 시그널 연구소실시간 스윙 트레이딩 시그널을 웹에서 확인하세요바로가기 →

v4는 돌아갔다, 그런데

지난 개발기에서 PPO 강화학습을 버리고 LLM 판단 + Rust/Tauri 네이티브 앱으로 v4를 다시 세웠다고 적었다. 봇은 돌아갔다. 아침에 켜면 종목을 고르고, 조건이 맞으면 사고, 익절이나 손절 조건에 닿으면 팔았다.

그런데 "돌아간다"와 "매주 빠짐없이 돌아간다"는 완전히 다른 문제였다. v4.1은 화려한 신기능을 붙인 버전이 아니다. 매매 루프를 실제로 신뢰할 수 있게 만드는 데 대부분의 시간을 쓴, 안정화 버전이다. 그 과정이 생각보다 훨씬 지루하고, 훨씬 어려웠다.

슬롯을 계좌로 바꾸다

가장 큰 구조 변경은 "슬롯 = 계좌"였다.

이전에는 하나의 봇이 하나의 전략을 돌렸다. v4.1에서는 각 슬롯이 독립된 계좌를 물고, 슬롯마다 다른 전략을 동시에 돌릴 수 있도록 바꿨다. 한 전략을 검증하는 동안, 다른 슬롯에서 또 다른 전략을 나란히 시험할 수 있는 구조다.

말로는 간단하지만, 슬롯이 여럿으로 나뉘는 순간 "이 체결이 어느 슬롯 것인지", "이 잔고가 어느 슬롯 것인지"를 모든 경로에서 구분해야 했다. 그리고 바로 여기서, 예상 못 한 지옥이 시작됐다.

사후 보정이라는 함정

자동매매에서 제일 안 믿음이 가는 순간은 "주문은 넣었는데 체결 확인이 늦을 때"다.

증권사에 매수 주문을 넣는다. 그런데 체결 응답이 곧바로 안 온다. 네트워크가 느릴 수도, 서버가 잠깐 500을 던질 수도 있다. 봇은 일단 "대기 중"으로 두고 다음 틱에 다시 확인한다. 그러다 몇 초, 몇십 초 뒤에 "아 체결됐네" 하고 뒤늦게 인식한다. 이걸 사후 보정이라고 부른다.

문제는, 체결을 뒤늦게 인식했을 때 손봐야 할 곳이 한 군데가 아니라는 것이었다. 매수 하나를 확정하면 최소 세 곳을 동시에 맞춰야 한다.

  • 알림: 텔레그램으로 "매수 체결" 메시지를 보낸다
  • 화면: 잔고 위젯과 보유 종목 카드를 갱신한다
  • 장부: 매매 이력 DB에 기록하고, 당일 매수 카운트를 올린다

여기에 방향(매수/매도)까지 곱하면 여섯 가지 조합이 된다. 그리고 사후 보정이 일어나는 경로는 하나가 아니었다. 체결 확인 지연, 증권사 잔고와의 대조, 장 마감 청산, 프로그램 종료 시 동기화... 경로마다 이 여섯 조합을 빠짐없이 채워야 했다.

한 셀만 빠져도 문제가 터졌다. 실제로 겪은 사례 하나. 매수 체결을 뒤늦게 인식하고 알림도 보냈고 장부에도 적었는데, "대기 중 주문 목록"에서 그 종목을 안 지웠다. 10분 뒤, 봇은 그 종목을 여전히 미체결로 보고 "체결이 안 됐습니다, 수동 확인이 필요합니다"라는 경고를 보냈다. 이미 체결돼서 팔 준비까지 하던 종목인데 말이다.

이런 누락이 한두 번이 아니었다. 매도는 챙겼는데 매수를 빠뜨리고, 알림은 갔는데 화면이 안 바뀌고, 화면은 바뀌었는데 장부에 실현손익이 안 반영되고. 매주 한 번씩 어딘가에서 이 패턴이 재발했다.

체크리스트로 만들다

결국 이걸 머리로 기억하는 걸 포기했다.

"방향 두 개(매수/매도) × 축 세 개(알림/화면/장부)"를 격자로 그려놓고, 사후 보정 코드를 새로 만들거나 고칠 때마다 여섯 칸을 하나씩 짚어 다 채웠는지 확인하는 체크리스트로 만들었다. 새 경로가 생기면 그 경로에도 같은 격자를 댔다.

교훈은 시시할 만큼 단순하다. 매수했으면 알림·화면·장부가 다 맞아야 한다. 하나만 빠져도 다음 주에 사이클이 안 돈다. 자동매매의 어려움은 사고파는 판단이 아니라, 사고판 뒤에 상태를 빠짐없이 정리하는 데 있었다.

조회가 성공했다고 값이 최신인 건 아니다

또 하나 오래 붙잡았던 함정.

장 마감에 포지션을 정리하고 나서, 청산 리포트에 찍힌 가격이 실제 체결가와 미묘하게 달랐다. 처음엔 체결가 자체가 틀린 줄 알고 회계를 의심했다. 실측해보니 매매 판단도, 회계도 전부 정상이었다. 틀린 건 로그와 화면에 표시된 숫자뿐이었다.

원인은 이랬다. 청산 로직이 가격을 디스크에 저장된 값에서 읽어왔는데, 그 값은 거래 이벤트가 일어날 때만 갱신됐다. 청산 시점엔 그 사이 흐른 시간만큼 낡아 있었다. 조회 자체는 매번 성공했다. 실패 로그도 없었다. 그래서 "값이 정확하다"고 믿었던 거다.

교훈. "조회에 성공했다"는 "값이 최신이다"를 보장하지 않는다. 실패 로그가 안 뜬다는 게 데이터가 맞다는 증거가 될 수 없다. 표시용 숫자 하나가 틀린 채로, 그 위에 "슬리피지가 크다" 같은 잘못된 관찰이 쌓이고 있었다. 낡은 표시가 판단 데이터를 조용히 오염시키고 있었던 셈이다.

지금, 그리고 배운 것

지금 EthiBot은 매일 장이 열리면 조용히 돌아간다. 장중엔 시간마다 로그를 훑어 이상이 없는지 보고, 마감 후엔 그날의 매매를 리포트로 남긴다. 화려하진 않지만, 이제는 대체로 빠짐없이 돈다.

v4.1에서 배운 건 결국 이거다. 자동매매의 진짜 난이도는 "돌아가게 만들기"가 아니라 매번 똑같이 돌아가게 만들기에 있다. 신호를 잘 잡는 것보다, 잡은 뒤의 뒤처리를 한 칸도 빠뜨리지 않는 것. 조회 성공을 데이터 정합으로 착각하지 않는 것. 지루한 쪽이 훨씬 중요했다.

다음은 손절 기준을 데이터로 조정하는 일이 남아 있다. 쌓이는 데이터를 보며 전략을 어디까지 밀어붙일지도 천천히 판단하려 한다. 급하게 가지 않으려 한다. 안정화가 이렇게 어렵다는 걸, 이번에 제대로 배웠으니까.


본 글은 개인 자동매매 봇의 개발 기록입니다. 게시된 매매 기록은 투자 권유가 아니며, 투자의 최종 판단과 책임은 본인에게 있습니다.

시그널 전략 상세는 EthiLab에서 확인할 수 있습니다.