저는 2024년 3월부터 하나증권 OpenAPI와 구글 클라우드 서울 리전을 연결해 개인용 자동매매 시스템을 만들었다. 처음에는 시세를 받아 이동평균선을 계산하고 조건이 맞으면 주문을 보내는 정도면 충분하다고 생각했다. 당시에는 Compute Engine의 작은 인스턴스 하나와 파이썬 프로그램만 준비하면 하루 안에 끝날 줄 알았지만, 실제로는 인증 만료, 주문 응답 지연, 장중 로그 누락 같은 문제가 차례로 나타났다. 이 글에서는 제가 약 9개월 동안 운영하며 겪은 시행착오와, 그 과정에서 설계를 바꾼 이유를 기록하려 한다.
1. 첫 연동에서 부딪힌 인증과 요청 제한
처음 테스트한 날은 2024년 3월 18일이었다. API 문서를 참고해 액세스 토큰을 발급받고 1분봉 조회 요청을 반복했는데, 로컬 윈도우 PC에서는 정상적으로 보이던 요청이 GCP 서버에서 간헐적으로 거절됐다. 원인은 토큰을 메모리에만 저장한 채 프로세스가 재시작될 때마다 새 토큰을 요청했던 데 있었다. 새벽 배치 프로그램이 재시작되면서 인증 요청이 짧은 시간에 몰렸고, 오전 9시 직전에는 조회 요청 일부가 실패했다. 저는 토큰 만료 시각을 별도 저장하고 갱신 간격을 넉넉히 둔 뒤, 요청 사이에 지연 시간을 넣는 방식으로 수정했다.
두 번째 문제는 응답 형식이 문서의 예시와 실제 환경에서 조금씩 달랐다는 점이다. 종목 코드가 잘못됐을 때도 HTTP 상태만 보고 성공으로 처리했더니, 빈 배열을 정상적인 거래 신호로 오인했다. 4월 2일에는 이 오류 때문에 전략이 장 시작 직후 보유 종목을 모두 매도하려는 상황까지 갔다. 주문 함수 앞에 종목 코드 검증, 응답 길이 확인, 마지막 수신 시각 비교를 넣고, 하나라도 맞지 않으면 주문 대신 경고만 남기도록 바꿨다. 그 뒤부터는 API 호출 성공과 실제로 쓸 수 있는 응답을 서로 다른 상태로 기록하고 있다.
2. 서울 리전이라고 지연 시간이 자동으로 줄지는 않았다
저도 처음에는 서울 리전에 VM을 만들면 주문 지연이 자연스럽게 짧아질 거라 기대했다. 하지만 2024년 4월에 측정한 결과는 생각보다 들쭉날쭉했다. 평상시 시세 조회 왕복 시간은 18~25ms였고, 장 시작 직후에는 70ms를 넘는 기록도 나왔다. 네트워크 위치만 바꾸면 해결될 문제라고 판단해 인스턴스 유형을 키웠지만 평균값은 거의 달라지지 않았다. 이후 요청 시간을 밀리초 단위로 남기고 DNS 조회, TLS 연결, API 서버 응답, 파싱 시간을 각각 나눠 측정했다. 병목은 CPU가 아니라 매 요청마다 새 연결을 만들던 코드였다.
커넥션 재사용을 적용하고 동시 요청 수를 제한한 뒤에는 같은 구간의 평균 왕복 시간이 21ms 안팎으로 내려갔다. 그렇다고 모든 주문이 그 속도로 처리된다고 착각하지 않으려 한다. 증권사 서버의 처리 대기, 장중 요청량, 실제 체결까지 걸리는 시간은 별도로 움직였기 때문이다. 저는 주문 신호가 발생한 시각, API에 요청을 보낸 시각, 접수 응답 시각, 체결 확인 시각을 각각 저장했다. 이 네 시각을 구분하고 나니 전략이 느린지 네트워크가 느린지 판단하기 쉬워졌다. 단순히 핑 한 번을 측정한 결과만 보고 시스템 성능을 판단했던 초기 접근은 잘못이었다.
3. BigQuery 백테스트에서 발견한 비용과 시간 오류
시장 데이터를 쌓기 위해 2024년 5월부터 BigQuery를 사용했다. 처음에는 원본 CSV를 그대로 적재하고 매번 전체 기간을 조회했는데, 18개월치 1분봉을 분석하는 쿼리가 40초 이상 걸렸고 스캔 바이트도 예상보다 컸다. 더 난감했던 부분은 날짜와 시간이 문자열로 저장돼 장 시작 전후 필터가 정확하게 적용되지 않았다는 점이다. 9시 직전 자료가 다른 날짜로 묶이는 사례가 발견돼 백테스트 결과가 실제 거래 기록과 계속 어긋났다. 저는 수집 단계에서 한국 시간과 UTC를 명시적으로 분리하고, 날짜 파티션과 종목 코드 클러스터링을 적용했다.
테이블 구조를 바꾼 뒤 같은 기간 조회 시간은 40초대에서 6초 내외로 줄었다. 비용을 줄이려는 목적도 있었지만, 제게 더 큰 변화는 실험 결과를 다시 재현하기 쉬워졌다는 점이었다. 예전에는 CSV 파일을 수정한 뒤 어떤 버전으로 계산했는지 남기지 않아 결과가 매번 조금씩 달랐다. 그래서 전략 코드의 커밋 번호, 사용한 테이블 버전, 수수료율, 슬리피지 값을 실행 기록에 함께 저장했다. 그 과정에서 체결 수수료와 예상 호가 간격을 빼지 않은 백테스트가 실제보다 약 1.8% 높게 나왔다는 사실도 확인했다. 숫자가 좋아 보인다는 이유만으로 전략을 믿으면 안 된다는 교훈을 얻은 지점이다.
4. 주문 모듈보다 먼저 만든 리스크 차단 장치
처음 만든 프로그램은 신호가 나오면 곧바로 주문 함수로 넘어갔다. 이 구조는 2024년 6월 14일에 크게 흔들렸다. 장중 네트워크가 약 40초 끊겼다가 복구되면서 프로그램이 마지막으로 읽은 잔고를 기준으로 매수 주문을 다시 제출했고, 같은 주문이 두 번 접수될 뻔했다. 다행히 모의 계좌에서 발견했지만, 실계좌였다면 곤란한 상황으로 이어질 여지가 컸다. 그 뒤 주문마다 고유한 요청 ID를 만들고, 주문 전 현재 잔고와 미체결 목록을 다시 확인하도록 바꿨다. 직전 요청의 처리 상태가 불명확하면 새 주문을 보내지 않고 운영자 확인을 기다리게 했다.
또한 하루 손실 한도, 종목별 최대 금액, 전체 미체결 주문 수를 프로그램 밖의 설정 파일에 두지 않고 별도 환경 변수와 데이터베이스에 나눠 저장했다. 프로그램 오류로 설정값이 비정상적으로 읽히면 주문 자체를 막는 검사를 추가했다. 2024년 7월에는 시세 수집 프로세스가 멈췄는데 전략 프로세스는 계속 살아 있어 오래된 가격으로 신호를 만드는 문제도 겪었다. 마지막 수신 시각이 10초 이상 갱신되지 않으면 신규 주문을 차단하고, 30초가 지나면 보유 포지션 관리만 남기는 상태 전환을 넣었다. 수익률을 높이는 코드보다 잘못된 주문을 멈추는 코드에 시간을 더 쓴 이유가 여기에 있다.
5. GKE와 Vertex AI를 서둘러 도입하지 않은 이유
처음부터 GKE로 시세 수집, 전략 계산, 주문 실행을 나누려 했지만, 제 시스템 규모에는 오히려 관리 지점이 늘어났다. 컨테이너 세 개를 배포한 뒤 로그 수집과 재시작 정책을 따로 설정해야 했고, 작은 설정 변경에도 이미지 빌드와 배포 과정이 필요했다. 2024년 8월에는 주문 컨테이너만 새 버전으로 교체하는 동안 환경 변수 하나가 누락돼 주문 모듈이 시작되지 않았다. 현재는 단일 VM 안에서 프로세스를 분리하고 systemd와 Cloud Monitoring으로 상태를 감시한다. 트래픽이 급격히 늘거나 여러 전략을 동시에 운영할 때 GKE를 다시 검토하겠지만, 처음부터 클라우드 기술을 많이 넣는 방식이 제 상황에 맞지는 않았다.
머신러닝도 비슷한 시행착오를 겪었다. Vertex AI에서 가격, 거래량, 뉴스 점수를 넣은 분류 모델을 만들었지만, 2024년 9월 백테스트 정확도가 64%로 나와 기대가 컸다. 그런데 시간 순서를 지켜 다시 검증하자 정확도는 51% 수준으로 떨어졌다. 학습 구간과 검증 구간에 비슷한 시점의 정보가 섞였고, 뉴스 게시 시각보다 늦게 공개된 수정 정보가 피처에 들어간 탓이었다. 저는 모델을 실거래에 연결하지 않고, 먼저 미래 정보가 섞이지 않는 검증 파이프라인부터 고쳤다. 현재 모델은 주문 신호가 아니라 기존 전략의 참고 점수로만 기록하며, 일정 기간 실제 결과와 비교한 뒤 사용 범위를 판단하고 있다.
제가 지금 운영하는 구성은 화려하지 않다. 서울 리전의 VM 한 대에서 시세 수집과 전략 계산을 돌리고, 주문 상태와 로그는 별도 저장소에 남긴다. BigQuery에는 정제된 체결·시세 자료만 보내며, 매일 오전에는 전날 주문 수와 누락된 캔들 수를 확인한다. 알림은 장애가 난 뒤 보내는 방식보다, 마지막 시세 수신 시각이 오래되거나 잔고 조회 결과가 비정상일 때 먼저 울리도록 만들었다. 독자가 비슷한 시스템을 시작한다면 처음부터 GKE나 머신러닝에 투자하기보다 모의 계좌에서 인증 만료, 중복 주문, 데이터 공백, 재시작 상황을 일부러 만들어 보는 편이 낫다. 자동매매의 성능은 멋진 기술 이름보다 실패했을 때 안전하게 멈추는 구조와 기록을 다시 확인하는 습관에서 달라진다는 점을 제가 직접 배우고 있다.
'IT & 비즈니스' 카테고리의 다른 글
| 파이썬 트레이딩 봇 개발 프로세스: 기획부터 실전 배포까지의 핵심 가이드 (0) | 2026.08.23 |
|---|---|
| 생성형 AI로 생산성을 극대화하는 실전 가이드 (0) | 2026.08.23 |
| 파이썬 코드의 품격을 높이는 리팩토링 기술과 시스템 성능 교정 팁 (0) | 2026.08.23 |
| 성공적인 트레이딩을 위한 필수 조건: 투자 스트레스의 이해와 관리 (0) | 2026.08.23 |
| 파이썬 자동매매 시스템 구축 가이드 (0) | 2026.08.23 |