코인 자동매매 만들기 #3

그리드 매매 봇 사흘 체결 0건, 손절선이 매수 칸보다 위였다

코인 자동매매 만들기3편 중 3번째

고점 기준 손절을 건 그리드 봇은 손절폭이 칸 간격보다 작거나 같으면 첫 칸 다음을 사지 못한다. 켜기 전에 칸1 매수가와 손절가를 나란히 계산한다.

사흘 동안 체결 0건

회사를 나와 AI로 사업을 세우는 과정을 기록하면서, 그 한쪽에서 업비트 계좌로 코인 자동매매 봇을 돌린다. 이번에 뜯어본 건 BTC·ETH·XRP 세 종목에 5% 간격 9칸짜리 격자를 깔아 둔 봇이다. 격자(그리드 매매)는 가격이 한 칸 내려갈 때마다 사고 한 칸 오르면 파는 방식이라, 원래는 박스권에서 자주 체결돼야 한다. 거래 기록의 마지막 줄은 2026-09-22T23:29:46 KRW-XRP buy였고, 그 뒤로 체결은 0건이었다.

먼저 의심한 것: 에러 로그의 401

의심할 거리는 많았다. 맥이 배터리로 절전에 들어갔다 깨어나면서 공인 IP가 바뀌었고, 업비트는 등록 안 된 IP에서 온 요청을 no_authorization_ip 401로 거절했다. 죽은 봇을 되살리는 맥의 상주 작업 관리자(launchd)는 봇을 계속 다시 띄웠고, 누적 크래시는 184회, 에러 로그는 7.7MB까지 불었다. 에러 로그를 종류별로 세자 이 401 한 줄이 117번 나왔다.

범인처럼 보였다. 그런데 크래시로 설명되는 건 봇이 죽어 있던 이틀뿐이었다. 살아 있던 9/22~9/23 낮에도 사지 않았고, IP가 원래 값으로 돌아와 봇이 스스로 복구된 뒤에도 사지 않았다. 질문을 바꿨다. 막힌 건가, 기다리는 건가.

설정 두 줄이 서로를 막고 있었다

에러 로그를 덮고 봇의 설정값과 그날 가격을 나란히 놓았다.

STEP_PCT=5, STOP_PCT=5, STOP_REF=peak
칸1 매수가 = p0×0.95, 손절선 = peak×0.95 ≥ p0×0.95
실측: BTC 칸1 110,227,550 < 손절선 111,266,850

칸 간격도 5%, 손절도 5%인데 기준이 다르다. 칸1 매수가는 시작가(p0)의 95%이고, 손절선은 시작한 뒤 찍은 최고가(peak)의 95%다. 최고가는 시작가보다 낮을 수 없으니 가격이 아무리 천천히 내려와도 칸1에 닿기 전에 손절선을 먼저 밟게 되고, 9칸짜리 격자는 실제로는 한 칸 사서 +5%에 팔거나 -5% 근처에서 손절하고 영구 정지하는 봇이었다. ETH·XRP도 같은 모양이었다. 29만원을 넣어 두고 3만원만 썼고, 세 종목에 각 한 칸(BTC 10,004원, ETH 10,005원, XRP 10,005원)씩만 들고 있었다.

사흘 무체결은 고장이 아니었다. 가격이 ±5%를 움직이지 않아서, 막힌 게 아니라 기다린 것이다. 에러 로그를 아무리 파도 이 답은 안 나왔다. 에러가 아니었으니까.

고점 기준 손절을 건 그리드 봇이라면, 켜기 전에 칸1 매수가와 손절가를 숫자로 나란히 적어 보세요. 손절폭이 칸 간격보다 작거나 같으면 그 봇은 한 칸 이상 사지 않습니다.

격자를 내렸다

손절폭을 넓히는 대신 격자를 접었다. 예전에 ETH 한 종목으로 돌린 격자의 9/17~22 실적이 +1,225원이었는데, 같은 기간 그냥 들고 있었으면 약 +27,700원이었다. 격자를 청산한 실현손익은 BTC -114원, ETH -53원, XRP +310원이다. 30만원은 BTC·ETH를 50일 이동평균(MA50) 위에서만 들고 있는 추세추종 봇으로 옮겼고, 지금 둘 다 MA50 위라 보유 중이다. 같은 날 시작 대조가 401이나 DNS 실패에서 죽으면 재시작 대신 60초에서 600초까지 늘려 가며 기다리게 고쳤다. 격자 봇은 멈춤 파일(TRI_STOPPED)로 막아 두었고, 새 봇의 첫 자동 판정은 9월 26일 로그에서 확인한다.

← 전체 글