단계별로 자동매매 봇 개발하기 (M1 → M2 → M3)

🌐 English

자동매매 봇을 처음부터 "매매까지 되는 완성품"으로 만들려 하면 십중팔구 실패합니다. 검증되지 않은 시그널 위에 주문 로직을 얹으면, 무엇이 틀렸는지조차 알 수 없기 때문입니다. 실제 ETF 갭 봇을 만들며 쓴 3단계 마일스톤 방법론을 정리합니다.

⚠️ 이 글은 교육·정보 제공 목적입니다. 투자 권유가 아니며, 투자 손실 책임은 본인에게 있습니다.

원칙: 돈이 움직이는 부분을 가장 마지막에

핵심 원칙 하나입니다. 실제 주문을 내는 코드는 가장 나중에, 가장 검증된 상태에서 켠다. 그래서 마일스톤을 이렇게 나눴습니다.

  • M1 — 데이터 흐름 가시화 (매매 없음)
  • M2 — 매매 로직 (소액 실거래)
  • M3 — 운영 안정화 (강제청산·알림·대시보드)

M1: 보이게 만든다, 사고팔지는 않는다

첫 단계 목표는 오직 하나 — 데이터가 제대로 흐르는지 눈으로 확인하는 것입니다. 이 단계에서 매매 함수들은 실행되지 않는 stub으로 둡니다.

// M1: 전략·주문 함수는 로그만 찍고 채널을 비운다

func strategyEngine() {

    for gap := range gapCh {

        logCh <- fmt.Sprintf("[M1 stub] gap=%+v", gap) // 판단·주문 없음

    }

}

M1에서 실제로 한 일:

  • WebSocket으로 종목별 호가·체결 구독, 틱 파싱
  • 장 시작 시가 캡처와 기준선 표시
  • 갭에 쓰일 값(현재가·시가·변동률)을 REST/화면으로 확인

이 단계의 검증은 화려하지 않습니다. go build가 통과하는지, 빈 종목코드가 자동으로 skip되는지, 헬스체크가 응답하는지, 첫 raw 메시지의 필드 인덱스가 문서와 맞는지. 매매 로직은 한 줄도 없지만, 여기서 데이터가 신뢰할 만하다는 확신을 얻지 못하면 다음 단계로 가지 않습니다.

M2: 계산과 매매를 붙인다 (소액)

데이터가 믿을 만해진 뒤에야 시그널과 주문을 연결합니다. M2에서 붙이는 것:

  • 시가 캡처 영속화 — 재시작·정지에도 당일 기준선 유지
  • 갭 계산 — 순수 함수로 분리해 단위 테스트 (정상값/시가 0/데이터 stale/이론치 일치 등 경계 케이스)
  • 전략 엔진 — 갭합이 임계치를 넘으면 진입, 좁혀지면 청산
  • 주문 실행 — 이때 처음으로 실제 REST 주문 등장

M2에서도 안전하게 가는 방법이 있습니다. 먼저 주문 직전 차단(dry-run)으로 시그널·수량 계산이 맞는지 확인하고, 그다음 아주 작은 금액으로 실거래를 켭니다. 페어도 전부가 아니라 1~2개로 시작해 1~2주 관측합니다.

갭 계산을 순수 함수로 뽑아둔 게 여기서 빛을 발합니다. 부작용이 없으니 시장이 열리지 않은 시간에도 테스트로 로직을 검증할 수 있습니다.

// 시장 없이도 검증 가능한 순수 함수

got := ComputeGap(...)

if got.GapSum != want {

    t.Fatalf("gapSum=%v want %v", got.GapSum, want)

}

M3: 오래 돌아가게 만든다

매매가 되기 시작하면, 그다음은 하루하루 안전하게 반복하는 문제입니다. M3에서 넣는 것:

  • 강제청산 — 정해진 시각에 포지션을 무조건 종결 (전략과 분리된 별도 고루틴)
  • 알림 — 진입·청산·오류·강제청산 실패를 즉시 통지
  • 토큰 자동 갱신 — 매일 인증 토큰을 자동 재발급, 실패 시 봇 정지
  • 대시보드 — 페어 상태, 갭 게이지, 갭 히스토리 차트로 한눈에 관측

M3는 "새 기능"이라기보다 "자리를 비워도 되는 봇"을 만드는 단계입니다. 사람이 24시간 지켜볼 수 없으니, 봇이 스스로 위험을 알아채고 멈추거나 알리게 만듭니다.

왜 이 순서가 안전한가

각 단계가 다음 단계의 전제 조건을 검증하기 때문입니다.

  1. M1이 데이터 신뢰성을 보장하지 못하면 → M2 시그널은 쓰레기 위에 세운 집
  2. M2가 시그널·주문을 검증하지 못하면 → M3 안정화는 틀린 것을 안정적으로 반복할 뿐

그리고 무엇보다, 실제 돈이 움직이는 지점을 최대한 뒤로 미루는 것 자체가 가장 강력한 리스크 관리입니다. M1에서 며칠 데이터만 보다 전략을 접더라도, 잃은 것은 시간뿐 돈은 아닙니다.

정리

가시화(M1) → 매매(M2) → 안정화(M3). 지루해 보이는 순서지만, 각 단계가 다음 단계의 안전벨트가 됩니다. 자동매매 봇에서 가장 빠른 길은, 조급하게 주문 코드부터 켜는 것이 아니라 데이터부터 믿을 수 있게 만드는 것입니다.

댓글

이 블로그의 인기 게시물

한국투자증권 KIS API로 실시간 시세 받기 (WebSocket 실전)

파이썬으로 업비트 API 연동하기 — 시세 조회부터 주문까지 기초

Go로 자동매매 신호봇 프레임워크 설계하기