증권사의 Open API를 활용하면 주식 데이터 조회, 자동 매매 등 다양한 금융 작업을 자동화할 수 있습니다.
키움 증권은 Open API를 두 가지 종류를 제공합니다.
- COM/ActiveX 기반
- RestAPI 기반
우선 키움증권 COM/ActiveX 기반 Open API를 Python에서 사용하는 방법에 대해 알아본 후 추후에 RestAPI 기반 (Flutter) 사용법에 대해서 알아보도록 하겠습니다.
참고로 COM/ActiveX 기반 Open API는 python 윈도우 32bit 환경만 제공합니다.
Open API 사용신청
키움 홈페이지에 로그인하여 메뉴에서 고객서비스 항목을 선택하면 아래와 같이 Open API 항목을 볼 수 있습니다.
키움 Open API(국내 주식), 해외파생 Open API(해외 주식 – 미국) 항목을 각각 선택한 후 사용 신청을 합니다.

아래와 같이 서비스 사용 등록/해지 선택하여 모든 내용을 동의한 후에 등록을 한다.

설치
서비스 소개 메뉴에서 아래 그림과 같이 키움 Open API+ 모듈 다운로드를 실행하여 파일(OpenAPISetup.exe)을 다운받고 설치하면 C:\OpenAPI에 설치됩니다.

모의 투자 신청

32bit python conda 가상환경 생성하기
Python 3.10 에서 테스트
#conda config --env --set subdir win-32
#conda info
conda create -n kiwoom_32
conda activate kiwoom_32
conda config --env --set subdir win-32
conda install python=3.10
# platform : win-32 확인
conda info
# kiwoom 라이브러리 설치
pip install pykiwoom
# numpy 2.0.2 버전 사용시 에러 발생하여 다운그레이드 함 (### ImportError: numpy.core.multiarray failed to import)
pip install numpy==1.26.4
pip install numpy==1.24.4
conda deactivate
#conda config --env --set subdir win-64
키움 OpenAPI 기본사용법
[개요]
OpenAPI(Application Programing Interface)는
OpenAPI를 통해 국내주식상품과 코스피200 선물/옵션을 거래할 수 있습니다.
사용자가 직접 거래/분석프로그램을 개발 할 수 있는 서비스이며 COM형태로 제공합니다.
주요기능은 시세데이터 (조회데이터와 실시간데이터), 주문기능,
조건검색기능(조회데이터와 실시간데이터)을 제공하며 모두 로그인 이후 가능합니다.
OpenAPI는 보안성과 안정성을 최우선하여 운영되며
데이터의 가공을 최소화하여 사용자에게 원천데이터를 제공하는 것을 원칙으로 합니다.
OpenAPI에서 발생되는 주문은 영웅문4 HTS, 영웅문S MTS 등 타매체에서도 확인이 가능하며,
반대로 영웅문4, 영웅문S의 주문에대한 체결신호가 OpenAPI에서 수신됩니다.
※ 당사 OpenAPI는 64비트용으로 제공되지 않습니다.
Visual Studio 2022, 64비트 MS Office 군의 엑셀 등에서는 OpenAPI 컨트롤 사용이 불가 합니다.
또한 OpenAPI는 (함수나 이벤트 모두) 스레드를 지원하지 않으므로 OpenAPI함수나 이벤트를 스레드에서 호출하는것은 안정성을 보장할 수 없습니다.
[기본동작]
OpenAPI 데이터 요청과 데이터 수신 이벤트는 모두 비동기 방식입니다.
(반드시 조회요청한 순서대로 수신되지는 않습니다.)
시세조회나 주문 등 함수호출을 통해 서버로 요청하면 서버의 처리 결과를 그에 맞는 이벤트 발생으로 전달합니다.
이벤트는 일반함수와 구별하기 위해 "On~" 으로 시작되는 이름을 갖습니다.
OnEventConnect (로그인처리완료), OnReceiveTRData (조회요청응답), OnReceiveRealData (실시간시세수신)
[데이터요청과 수신]
예) 조회요청.
요청(조회함수 CommRqData 사용자가 호출) --> 이벤트 발생(OnReceiveTRData) --> 데이터 획득(GetCommData 사용자가 호출)
예) 조건검색요청.
요청(조회함수 SendCondition 사용자가 호출) --> 이벤트 발생(OnReceiveTrCondition)
예) 주문요청.
요청(주문함수 SendOrder 사용자가 호출) --> 이벤트 발생(OnReceiveTRData) --> 이벤트 발생 (OnReceiveChejanData) --> 데이터 획득(GetChejanData 사용자가 호출)
※ 이벤트를 임의로 호출해서 사용하는 것은 불가 합니다.
[계좌번호]
OpenAPI에서는 10자리의 계좌번호가 사용됩니다.
영웅문4 등에서는 끝 2자리를 고객님께 노출하지 않고 8자릿수로 제공됩니다.
OpenAPI에서는 계좌의 끝 2자리를 따로 관리하지 않고
사용자가 입력한 그대로의 계좌번호를 사용하도록 설계되어 있습니다.
따라서 데이터 조회 또는 주문시 계좌번호 10자리를 모두 입력해주셔야 합니다.
[화면번호]
서버에 데이터를 요청하거나, 주문을 발생시킬때 사용합니다.
화면번호는 서버의 결과를 수신할때 어떤 요청에 의한 수신인지를 구별하기 위한 키값의 개념입니다.
0000을 제외한 임의의 숫자(4자리)를 자유롭게 사용하시면 됩니다.
※ 화면번호 사용시 주의할 점 :
같은 화면번호로 데이터 요청을 빠르게 반복하는 경우 데이터의 유효성을 보장할 수 없습니다.
최소한 2개이상의 화면번호를 번갈아가며 또는 매번 새로운 화면번호를 사용하시기 바랍니다.
사용자 프로그램에서 사용할 수 있는 화면번호 갯수가 200개로 한정되어 있습니다.
이 갯수를 넘는 경우 데이터의 유효성을 보장할 수 없습니다.
(구현하시는 프로그램 성격상 화면번호 갯수가 200개가 넘어야 하는 경우, 이전에 사용되었던 화면번호를 재사용 하는 방식으로 구현해야 합니다.)
사용 예제
로그인 및 데이터 조회
from pykiwoom.kiwoom import Kiwoom
kiwoom = Kiwoom()
# 로그인 정보 입력
kiwoom.CommConnect(block=True)
# 계좌 정보 조회
accounts = kiwoom.GetLoginInfo("ACCNO")
print("계좌번호: ", accounts)
# 종목 코드 조회
kospi = kiwoom.GetCodeListByMarket('0') # 코스피
kosdaq = kiwoom.GetCodeListByMarket('10') # 코스닥
print("코스피 종목 수: ", len(kospi))
print("코스닥 종목 수: ", len(kosdaq))
전일가 조회 예제
from pykiwoom.kiwoom import Kiwoom
kiwoom = Kiwoom()
kiwoom.CommConnect(block=True)
# 삼성전자 당일 기준가 조회
price = kiwoom.GetMasterLastPrice("005930")
print("삼성전자 현재가: ", price)
개별 주식 정보 수집
# opt10001 : (TR)주식기본정보요청
# single data (has single row)
df_single = kiwoom.block_request('opt10001',
종목코드='035720',
output='주식기본정보',
next=0 # 0 : single transaction
)
# 출력
df_single
출처: [https://songseungwon.tistory.com/52](https://songseungwon.tistory.com/52) [관성을 이기는 데이터:티스토리]
개별 주식 일봉 차트 조회
# opt10081 : (TR)주식일봉차트조회요청
# multi-data (has multiple rows)
df_multi = kiwoom.block_request('opt10081',
종목코드='005930',
기준일자='20210824', # 기준일로부터 총 600일(변동가능)
수정주가구분=1, # 수정주가 적용(액분 등 반영)
output='주식일봉차트조회', # multi-data
next=0 # 0 : single transaction(단일 요청)
)
# 기준일자 '2021년 8월 24일' 포함 지난 600일 일봉 데이터 출력
print(df_multi)
주식 매수 하기
from pykiwoom.kiwoom import Kiwoom
# Kiwoom 인스턴스 생성 및 로그인
kiwoom = Kiwoom()
kiwoom.CommConnect(block=True)
# 계좌 정보 가져오기
accounts = kiwoom.GetLoginInfo("ACCNO")
account = accounts[0] # 첫 번째 계좌 사용
# 주문 정보 설정
rqname = "주식주문"
screen_no = "1000"
acc_no = account
order_type = 1 # 1: 신규매수
code = "005930" # 삼성전자 종목코드
quantity = 10 # 주문수량
price = 0 # 시장가 주문 시 가격은 0으로 설정
hoga = "03" # 03: 시장가
# 주문 전송
kiwoom.SendOrder(rqname, screen_no, acc_no, order_type, code, quantity, price, hoga)
주식 매도 하기
from pykiwoom.kiwoom import Kiwoom
# Kiwoom 인스턴스 생성 및 로그인
kiwoom = Kiwoom()
kiwoom.CommConnect(block=True)
# 계좌 정보 가져오기
accounts = kiwoom.GetLoginInfo("ACCNO")
account = accounts[0] # 첫 번째 계좌 사용
# 주문 정보 설정
rqname = "주식주문"
screen_no = "1000"
acc_no = account
order_type = 2 # 2: 신규매도
code = "005930" # 삼성전자 종목코드
quantity = 10 # 주문수량
price = 0 # 시장가 주문 시 가격은 0으로 설정
hoga = "03" # 03: 시장가
# 주문 전송
kiwoom.SendOrder(rqname, screen_no, acc_no, order_type, code, quantity, price, hoga)
자동로그인
아래 코드를 실행하면 계좌비밀번호 입력 창이 표시된다. 등록 버튼 옆에 계좌비밀번호를 입력한 후 ‘전체계좌에 등록’ 버튼을 실행합니다. 다음으로 ‘AUTO’라고 표시된 체크박스에 체크합니다. 모의투자의 경우 계좌비밀번호는 0000이며 실계좌인 경우 실제 계좌번호 4자리를 입력합니다. . 설정을 완료했다면 닫기 버튼을 눌러 계좌비밀번호를 입력창을 닫아줍니다.
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QAxContainer import *
class MyWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Python 로그인")
self.ocx = QAxWidget("KHOPENAPI.KHOpenAPICtrl.1")
self.ocx.OnEventConnect.connect(self._handler_login)
# login
self.ocx.dynamicCall("CommConnect()")
self.login_loop = QEventLoop()
self.login_loop.exec()
self.ocx.dynamicCall("KOA_Functions(QString, QString)", "ShowAccountWindow", "")
def _handler_login(self):
try:
self.login_loop.exit()
except:
pass
if __name__ == "__main__":
app = QApplication(sys.argv)
win = MyWindow()
win.show()
app.exec_()

개발 시에만 자동로그인을 사용하고 실사용 시에는 자동로그인을 해제하는 것을 권장합니다.
정리
증권사에서 제공하는 OpenAPI를 활용하여 자신만의 알고리즘을 가진 자동 매매 프로그램을 제작할 수 있습니다.