파이썬 자동매매에서 자주 만나는 오류와 점검 방법

파이썬 자동매매 코드를 돌리다 갑자기 에러가 터지면 심장이 덜컥 내려앉거든요. 새벽에 봇이 멈춰버린 경험이 있다면, 지금부터 정리하는 긴급 수정 패턴 6가지가 다음번 사고를 막아줄 거예요.

제가 처음 자동매매 프로그램을 돌렸을 때 일이에요. 저녁에 세팅 다 해놓고 자신만만하게 잠들었는데, 아침에 일어나보니 프로그램이 새벽 2시에 멈춰 있더라고요. 매도 타이밍을 놓쳐서 그날 꽤 아팠어요. 알고 보니 API 인증키가 만료된 거였는데, 에러 로그를 제대로 남기지 않아서 원인 찾는 데만 반나절이 걸렸습니다.

그 이후로 에러 한 번 터질 때마다 패턴을 기록해뒀거든요. 결국 자동매매에서 반복적으로 발생하는 오류는 몇 가지로 수렴한다는 걸 깨달았어요. 환경 문제, 인증 문제, 네트워크 문제, 그리고 예외처리 부재. 이 네 범주만 확실히 잡아두면 새벽에 봇이 죽는 일은 거의 사라집니다.

에러 메시지, 읽는 법부터 달라져야 한다

자동매매 봇에서 에러가 터졌을 때 대부분 당황해서 에러 메시지 전체를 구글에 복붙하거든요. 근데 그건 비효율적이에요. 파이썬의 Traceback은 아래에서 위로 읽는 구조라서, 맨 마지막 줄이 실제 에러 타입이고 그 바로 윗줄이 에러가 발생한 코드 위치예요.

예를 들어 TypeError: string indices must be integers라는 에러가 뜨면, 딕셔너리로 기대한 변수에 문자열이 들어왔다는 뜻이에요. 자동매매에서 이게 자주 나오는 이유가 있어요. API 응답이 정상 JSON이 아니라 에러 문자열로 넘어오는 경우거든요. 잔고 조회를 했는데 인증 실패로 “error”라는 텍스트가 반환되면, 그걸 딕셔너리처럼 접근하니까 터지는 거예요.

또 하나 놓치기 쉬운 게 ModuleNotFoundError예요. 가상환경을 새로 만들고 나서 패키지를 안 깔은 채로 실행하면 바로 이게 뜨는데, 특히 키움 API처럼 32비트 파이썬이 필요한 환경에서 64비트로 가상환경을 만들면 모듈 자체가 인식이 안 돼요. 저도 이걸로 이틀을 날린 적이 있어요.

에러 메시지를 볼 때 습관 하나만 들이면 돼요. 맨 아래 줄 에러 타입 먼저 확인하고, 그 위의 File 경로에서 몇 번째 라인인지 찾아서 해당 줄 주변을 살피는 거예요. 이것만으로도 디버깅 시간이 절반 이하로 줄어들거든요.

try-except 예외처리, 자동매매에서는 이렇게 써야 한다

자동매매 코드에서 try-except를 안 쓰는 건 안전벨트 없이 고속도로 타는 거랑 비슷해요. 예외가 한 번이라도 발생하면 프로그램 전체가 죽어버리거든요. 매도해야 할 종목을 매도 못 하면 그게 바로 금전적 손실로 이어져요.

근데 초보분들이 흔히 하는 실수가 있어요. except Exception으로 모든 에러를 뭉뚱그려 잡아놓고, 그 안에서 pass만 쓰는 거예요. 이러면 에러가 발생해도 아무 로그가 안 남아서 나중에 원인을 찾을 수가 없어요. 제가 처음에 딱 이 실수를 했거든요. 에러는 안 나는 것 같은데 주문이 체결이 안 되는 미스터리한 상황이 벌어졌었어요.

⚠️ 주의

except 블록 안에 pass만 쓰면 에러가 조용히 묻혀버려요. 자동매매에서 이건 치명적이에요. 최소한 except Exception as e: print(e) 형태로 에러 내용을 출력하거나, logging 모듈로 파일에 기록해야 해요. 에러를 삼키는 코드가 가장 위험한 코드예요.

실전에서 권장하는 패턴은 이래요. 주문 실행, API 호출, 데이터 파싱 등 외부와 통신하는 부분마다 try-except를 걸되, except 안에서 에러 로그를 남기고, 필요하면 일정 시간 대기 후 재시도하는 로직을 넣는 거예요. 단순히 에러를 잡는 게 아니라 복구까지 설계하는 게 핵심이에요.

그리고 한 가지 더. except를 세분화하면 대응이 정교해져요. ZeroDivisionError, KeyError, ConnectionError 같은 구체적인 예외를 먼저 잡고, 맨 마지막에 Exception으로 나머지를 포괄하는 구조가 좋아요. 어떤 에러가 발생했는지 로그만 봐도 바로 파악이 되거든요.

API 인증 오류, 가장 흔한 원인 3가지

자동매매 에러의 절반 이상은 API 인증 관련이에요. 제 경우에도 처음 3개월간 터진 에러의 약 60%가 인증 문제였거든요. 코드 로직 자체는 멀쩡한데 인증만 꼬이면 전부 무용지물이 되니까 진짜 허무해요.

가장 먼저 의심해야 할 건 API 키 만료예요. 업비트, 바이낸스, 한국투자증권 할 것 없이 API 키에는 유효기간이 있어요. 잘 돌아가던 봇이 어느 날 갑자기 401 에러를 뱉으면 십중팔구 이거예요. 업비트의 경우 API 키 생성 시 만료 기간을 설정하게 되어 있고, 한국투자증권 오픈API는 토큰을 주기적으로 갱신해야 하거든요.

두 번째는 허용 IP 불일치예요. 거래소에서 API 키를 발급할 때 특정 IP만 허용하도록 설정할 수 있는데, 서버 IP가 바뀌거나 집 공유기의 공인 IP가 변경되면 바로 차단당해요. 저도 클라우드 서버를 재시작했더니 IP가 바뀌어서 한참 헤맸던 적이 있어요.

인증 오류 유형 주요 증상 해결 방법
API 키 만료 401 Unauthorized 거래소에서 새 키 재발급
허용 IP 불일치 403 Forbidden 현재 공인 IP 확인 후 재등록
JWT 모듈 충돌 AttributeError: no encode jwt 삭제 후 PyJWT 설치
토큰 미갱신 접속 후 일정시간 뒤 실패 토큰 자동갱신 로직 추가

세 번째가 의외로 많이 걸리는 건데, JWT 모듈 충돌이에요. 파이썬에서 JWT 관련 패키지가 jwt와 PyJWT 두 가지가 있거든요. jwt를 설치하면 encode 함수가 없어서 AttributeError가 뜨는데, 이걸 모르면 코드를 아무리 뜯어봐도 답이 안 나와요. pip uninstall jwt 하고 pip install PyJWT로 교체하면 깔끔하게 해결돼요.

네트워크 타임아웃과 요청 한도 초과, 봇이 멈추는 진짜 이유

인증은 멀쩡한데 봇이 가끔씩 멈추는 경우가 있어요. 이건 대부분 네트워크 문제예요. 거래소 서버가 일시적으로 느려지거나, 내 서버의 인터넷이 끊기면 requests 라이브러리가 응답을 무한정 기다리다가 프로그램이 멈춰버리거든요.

이걸 방지하려면 requests.get이나 requests.post에 timeout 파라미터를 반드시 넣어야 해요. timeout=10이면 10초 안에 응답이 없으면 예외를 발생시켜요. 이게 없으면 진짜 봇이 영원히 대기 상태에 빠질 수 있어요. 저는 이걸 모르고 처음에 한 달 넘게 돌렸는데, 어느 날 서버가 48시간째 응답 대기 중인 걸 발견했을 때 그 허탈함이란.

💡 꿀팁

requests 호출 시 timeout=(5, 15)처럼 튜플로 넣으면 연결 타임아웃 5초, 읽기 타임아웃 15초로 분리 설정할 수 있어요. 자동매매에서는 연결은 짧게, 읽기는 넉넉하게 잡는 게 안정적이에요. 그리고 타임아웃 예외가 발생하면 3~5초 대기 후 재시도하는 루프를 넣어두면 일시적 장애는 자동으로 넘어갈 수 있거든요.

요청 한도 초과도 은근히 자주 터지는 문제예요. 업비트 API는 초당 요청 가능 횟수가 정해져 있고, 응답 헤더의 Remaining-Req 값으로 남은 횟수를 확인할 수 있어요. 이 값이 3 이하로 떨어지면 0.3~0.5초 정도 time.sleep을 걸어주는 게 안전해요. 한국투자증권 오픈API도 초당 20건 제한이 있어서, 종목을 많이 조회하는 로직이라면 반드시 요청 간격을 조절해야 해요.

429 상태 코드(Too Many Requests)가 뜨면 일정 시간 대기 후 재요청하는 로직이 있어야 해요. 이걸 무시하고 계속 요청을 보내면 IP 자체가 차단될 수도 있어서, 단순 에러 이상의 문제가 되거든요.

logging 모듈로 원인 추적하는 실전 팁

print로 디버깅하던 시절이 있었어요. 솔직히 간단한 테스트에는 print도 괜찮은데, 자동매매처럼 24시간 돌아가는 프로그램에서는 print가 무력해요. 터미널을 안 보고 있으면 메시지가 그냥 사라지니까요.

파이썬 기본 내장 모듈인 logging을 쓰면 에러 메시지를 파일로 저장할 수 있어요. 날짜, 시간, 에러 레벨, 파일명, 라인 번호까지 자동으로 기록되거든요. 제가 앞에서 새벽에 봇이 죽었던 사건도, logging을 도입한 이후에는 아침에 로그 파일만 열면 정확히 몇 시 몇 분에 어떤 에러가 터졌는지 바로 보이더라고요.

logging의 레벨은 DEBUG, INFO, WARNING, ERROR, CRITICAL 다섯 단계예요. 자동매매에서는 평소에 INFO 레벨로 주문 실행·체결 로그를 남기고, 에러 발생 시 ERROR 레벨로 상세 내용을 기록하는 방식이 실용적이에요. 로그 파일이 너무 커지는 게 걱정이면 RotatingFileHandler를 쓰면 일정 크기 이상이 되면 자동으로 새 파일로 넘어가요.

📊 실제 데이터

자동매매 커뮤니티에서 공유되는 경험담을 종합하면, logging 도입 전후로 에러 원인 파악 시간이 평균 2~4시간에서 10~20분 이내로 줄었다는 후기가 많아요. 로그에 timestamp와 에러 코드, 응답 본문(response.text)까지 기록해두면 대부분의 에러는 로그 파일만으로 원인 특정이 가능하거든요.

한 가지 실수하기 쉬운 게, API 응답에서 에러 코드만 로그에 남기는 경우예요. 상태 코드 401이라는 숫자만 보면 원인을 바로 특정하기 어려운데, response.text까지 같이 기록하면 “잘못된 액세스 키입니다”처럼 구체적인 메시지가 남아서 훨씬 빠르게 대응할 수 있어요.

오류 재발 방지, 배포 전 이것만 체크하세요

에러를 고치는 것도 중요하지만, 애초에 안 터지게 만드는 게 최선이잖아요. 제가 1년 넘게 자동매매를 운영하면서 정리한 배포 전 체크리스트가 있어요.

첫째로 파이썬 버전과 패키지 호환성을 확인해야 해요. 키움 Open API는 32비트 파이썬에서만 동작하고, 대신증권 크레온 API도 마찬가지예요. 반면 업비트나 바이낸스 같은 REST API 기반은 64비트에서 잘 돌아가요. pip list로 설치된 패키지를 확인하고, requirements.txt로 버전을 고정해두면 환경 이슈를 크게 줄일 수 있어요.

그다음으로 중요한 건 API 키를 코드에 직접 쓰지 않는 것이에요. 환경변수나 .env 파일에 분리하고, 깃허브에 올릴 때 .gitignore에 반드시 추가해야 해요. 키가 노출되면 누군가 내 계좌로 주문을 넣을 수 있거든요. 실제로 깃허브에 API 키를 그대로 올렸다가 계좌가 털린 사례도 있어요.

💬 직접 써본 경험

저는 봇을 배포하기 전에 반드시 모의투자 환경에서 24시간 이상 테스트를 돌려요. 한국투자증권이나 키움증권 모두 모의투자 서버를 제공하고 있거든요. 실전에서 한 번 터지는 에러보다 모의투자에서 열 번 터지는 에러가 훨씬 싸요. 이 습관 하나가 제 계좌를 몇 번은 지켜줬어요.

그리고 자동매매를 장기 운영한다면, 프로그램이 비정상 종료되었을 때 자동으로 재시작되는 구조를 만들어두는 게 좋아요. 리눅스라면 systemd 서비스로 등록하거나, 윈도우라면 작업 스케줄러를 활용할 수 있어요. 완벽한 코드는 없으니까, 죽더라도 빨리 살아나는 구조가 현실적이에요.

마지막으로 하나만 더 말씀드리면, 자동매매는 투자 행위이기 때문에 코드 오류가 직접적인 금전 손실로 이어질 수 있어요. 전문가 상담이나 충분한 테스트 없이 실전 계좌에서 바로 돌리는 건 권장하지 않아요. 제 경우는 이랬지만 개인마다 환경과 상황이 다를 수 있으니, 본인 판단과 책임 하에 진행하시는 게 맞아요.

Q. try-except로 모든 에러를 잡으면 프로그램이 절대 안 죽나요?

A. except Exception으로 대부분의 런타임 에러는 잡을 수 있지만, 메모리 부족이나 시스템 레벨의 문제는 잡지 못할 수 있어요. 그래서 프로그램 자체를 감시하는 외부 모니터링(systemd, 작업 스케줄러 등)도 병행하는 게 안전해요.

Q. API 키를 .env 파일에 넣으면 어떻게 불러오나요?

A. python-dotenv 라이브러리를 설치한 뒤 load_dotenv()를 호출하고 os.getenv(‘KEY_NAME’)으로 가져오면 돼요. pip install python-dotenv로 설치할 수 있고, 코드에 키를 직접 노출시키지 않는 가장 간편한 방법이에요.

Q. 키움 API는 왜 32비트 파이썬에서만 되나요?

A. 키움 Open API가 COM 방식의 32비트 ActiveX 컨트롤로 만들어졌기 때문이에요. 64비트 파이썬에서는 32비트 COM 객체를 직접 호출할 수 없어서 호환 문제가 생기거든요. 아나콘다를 쓴다면 conda create로 32비트 가상환경을 별도로 만들어야 해요.

Q. 자동매매 봇을 24시간 돌리려면 어떤 환경이 좋나요?

A. 국내 주식은 장 시간만 돌리면 되지만, 코인이나 해외 주식은 24시간이 필요해요. 개인 PC보다는 클라우드 서버(AWS, 오라클 클라우드 프리티어 등)를 활용하면 안정적이에요. 오라클 클라우드 프리티어는 무료로 서버를 제공하니 비용 부담도 적어요.

Q. 거래소 API 에러 코드 목록은 어디서 확인하나요?

A. 각 거래소 공식 개발자 문서에 에러 코드표가 정리되어 있어요. 업비트는 docs.upbit.com, 한국투자증권은 apiportal.koreainvestment.com, 키움증권은 openapi.kiwoom.com에서 확인할 수 있어요. 에러 코드표를 한 번 훑어두면 디버깅 속도가 확 달라져요.

본 포스팅은 개인 경험과 공개 자료를 바탕으로 작성되었으며, 전문적인 의료·법률·재무 조언을 대체하지 않습니다. 정확한 정보는 해당 분야 전문가 또는 공식 기관에 확인하시기 바랍니다. 본 글의 내용은 정보 제공 목적이며, 개인 상황에 따라 결과가 다를 수 있습니다. 자동매매를 통한 투자는 원금 손실의 위험이 있으므로 반드시 전문가와 상담 후 결정하시기 바랍니다.

자동매매 코드 오류는 결국 에러 메시지 읽기, 예외처리 설계, 인증 관리, 네트워크 방어, 로깅 이 다섯 가지로 귀결돼요. 하나씩 잡아가면 새벽에 봇이 죽어서 당황하는 일은 확실히 줄어들거든요.

처음 시작하는 분이라면 try-except와 logging부터 도입해보세요. 이미 운영 중인 분이라면 API 키 만료일 체크와 timeout 설정이 되어 있는지 점검해보시고요. 코드가 완벽할 순 없지만, 죽었을 때 빨리 원인을 찾고 살릴 수 있는 구조를 만드는 게 진짜 실력이에요.


도움이 되셨다면 댓글로 본인의 에러 경험을 공유해 주세요. 같은 실수를 줄이는 데 서로 큰 도움이 되거든요. 공유도 환영합니다!