AlgoLab Blog · 실전 가이드

키움 OpenAPI+ 자동매매 — 직접 만들기 vs 외주, 뭐가 유리한가

키움 2026-04-22 · 약 7분 읽기 · 알고랩 AlgoLab

키움증권 OpenAPI+ 로 자동매매 프로그램을 만들어보겠다고 결심한 개발자들이 맨 처음 마주치는 건 "생각보다 제약이 많다" 는 사실입니다. API 문서만 보면 간단해 보이지만, 실제 구현에 들어가면 몇 가지 함정이 연속으로 등장하고, 이걸 전부 혼자 뚫는 데 보통 100~200시간 이 듭니다. 이 글에서는 3년 동안 알고랩에서 키움 자동매매 120건+ 제작하며 반복적으로 마주친 4가지 함정과, 직접 만들지 외주 맡길지 결정할 때의 기준을 공유합니다.

함정 1. Python은 반드시 32bit. 대부분 64bit로 시작했다가 재설치

키움 OpenAPI+ 는 Windows OCX 기반이고, 그 OCX 는 32bit 전용입니다. Python 64bit로 깔고 QAxWidget("KHOPENAPI.KHOpenAPICtrl.1") 호출하면 "클래스가 등록되지 않았습니다" 에러가 납니다. 그래서 보통 아래 순서를 밟게 됩니다.

  1. Python 64bit 설치 → 실패 → 구글링
  2. Python 32bit 재설치 → PyQt5 32bit·pywin32 32bit 재설치 → 기존 가상환경 버림
  3. VS Code 인터프리터 경로 수동 변경
  4. pyinstaller로 배포 시 다시 32bit 바이너리 맞춰야 함

이 단계에서만 보통 4~8시간 날립니다. Python 3.11 까지는 32bit 공식 배포 있고, 3.12부터 32bit 공식 배포가 없어지니 3.10 또는 3.11 32bit 를 권장합니다.

함정 2. TR 요청 동시 호출 → 입력 슬롯 덮어씀

키움 API의 핵심 흐름은 SetInputValue로 파라미터 세팅 → CommRqData로 요청 전송 입니다. 문제는 이 두 함수가 단일 입력 슬롯을 공유한다는 점. 백그라운드 폴링과 사용자 트리거 요청이 겹치면 두 요청의 파라미터가 섞여서 "계좌정보를 찾을 수 없습니다" 팝업이 뜨거나 빈 응답이 돌아옵니다.

해결: 모든 TR 호출을 단일 플래그로 직렬화.

class KiwoomAPI:
    def __init__(self, ...):
        self._tr_busy = False  # 단일 락

    def get_balance(self):
        if self._tr_busy:
            return {}  # busy면 즉시 빈 결과 (블로킹 대기 금지)
        self._tr_busy = True
        try:
            self.kiwoom.dynamicCall("SetInputValue(QString, QString)", "계좌번호", account)
            ret = self.kiwoom.dynamicCall("CommRqData(...)", "계좌평가잔고", "opw00018", 0, "0101")
            # 응답 대기 (이벤트 루프)
            return self._last_balance
        finally:
            self._tr_busy = False  # 예외 발생 시에도 반드시 해제

이 패턴을 모르면 백테스팅 쌓아둔 종목 루프에서 간헐적으로 데이터 누락이 생겨서 원인 못 찾고 며칠 헤맵니다.

함정 3. SendOrder 가 조용히 실패 (에러도 안 남)

주문 함수 SendOrder 는 9개 인자를 받는데, 이를 가변 형식으로 호출하면 PyQt5 QAxBase 가 일부 인자 누락 처리해서 주문 자체가 접수 안 되는데 에러도 안 나고 로그도 안 남습니다. 체결 콜백도 당연히 안 오고요.

해결: 반드시 9개 인자를 리스트로 묶어서 전달.

ret = kiwoom.dynamicCall(
    "SendOrder(QString, QString, QString, int, QString, int, int, QString, QString)",
    ["매수주문", "0101", account, 1, "005930", 10, 0, "03", ""]  # 반드시 list로 묶음
)

호가구분 상수도 헷갈립니다: "00"=지정가, "03"=시장가. 시장가는 가격(7번째 인자)을 반드시 0 으로 넣어야 합니다.

함정 4. 실시간 시세 등록 한도 — 최대 100종목

키움 OpenAPI+ 는 한 계정당 실시간 시세 등록 한도가 100종목입니다. 코스피+코스닥 전체 실시간 감시는 불가능. 그래서 "시총 상위 100" 처럼 미리 필터링된 종목 리스트로 좁혀서 등록하는 구조가 표준입니다.

또한 SetRealReg 의 4번째 인자 ("0"=최초 등록, "1"=추가) 를 잘못 넣으면 기존 등록이 전부 해제됩니다. 디버깅 매우 어려운 버그 양산.

그래서 — 직접 만들기 vs 외주, 뭐가 유리한가

아래 기준으로 결정하시면 됩니다.

직접 만드는 게 낫다면

외주가 유리하다면

알고랩 기준으로 "기본 구조 + 조건검색 + 익절/손절 + 텔레그램 알림 + .exe" 정도면 80~120만원, 제작 기간 5~7일 입니다. 본인 시간 100시간을 여기에 쓸지, 다른 데 쓰고 외주를 맡길지는 본인 시간 가치로 판단하시면 됩니다.

참고: 이 글에서 언급한 4가지 함정은 전체 함정 중 일부입니다. 잔고 재동기화, 조건검색 콜백 순서, 장 시작 직후 10~20초 체결 틱 누락 등도 실제로 제작 중 자주 만나는 이슈들입니다. 자세한 기술 문서는 키움 OpenAPI+ 플랫폼 페이지를 참고하세요.

직접 뚫기 귀찮으시면 알고랩에

3년간 359건 이상 제작한 알고랩이 맞춤 제작해드립니다.
24시간 빠른 답변 가능합니다.

무료 상담 시작하기