PyQt5 를 사용해 키움증권 API 를 Python 으로 이용해 보기
이번 포스트에서는 키움 증권 API를 이용해 보겠습니다.
API 이용을 위해서는 키움증권 계좌를 발급받은 뒤 API 신청을 하시면 됩니다.
공인이증서 로그인 후 아래 링크로 들어가서 사용 신청하러 가기 버튼을 눌러 사용 신청을 완료 합니다. (07~22)
https://www.kiwoom.com/nkw.template.do?m=m1408000000

다음으로 키움 OpenAPI+ 모듈 다운로드 한뒤 다음다음으로 설치를 진행하시면 됩니다.
다음으로 KOA Studio를 다운로드 합니다.
그리고 KOA Studio (무설치) 를 실행 한뒤 파일 > OpenAPI 접속을 클릭하면 아래와 같은 창이 나올 것입니다.

여기서 비밀번호를 입력하고 로그인을 수행하면 아래 팝업이 나올텐데
메뉴얼에 보시면 나와 있겠지만 아래 팝업은 그대로 두고 KOA Studio, API 관련 프로그램 모두 종료 후
아래 팝업에서 확인 버튼을 눌러야 합니다. 그렇지 않으면 OpenAPI에 접근할 수 없습니다.

로그인에 성공하면 아래와 같은 화면이 보일 것입니다.
TR 목록은 지원하는 API 목록 이라고 보시면 됩니다.
주식기본정보요청 클릭 -> 종목코드 입력 -> 조회 버튼을 누르면 출력창에 결과 값이 표시됩니다.

1. Python 에서 키움증권 OpenAPI 이용하기
Yahoo 의 경우 서버에 Request 하는 방식으로 OpenAPI 가 되어있는 반면에 키움증권의 API 는 조금 다른 방식을 사용합니다.
바로 OCX 방식인데요. OCX 는 Window 응용 프로그램에서 사용되기 위한 프로그램으로, 쉽게 말해서 윈도우 프로그래밍을 쉽게 해주는 도구라고 보면 될 것 같습니다.
우리는 키움증권 OCX 가 제공하는 함수를 Python에서 불러 줘야 하고, 우리가 함수를 부르면 OCX 가 키움증권 서버에 데이터를 요청하겠죠.
이 OCX 함수를 Python에서 이용하는 방법은 아래 두 가지가 있는데요
- win32com Python 라이브러리 이용
- PyQt5 Python 라이브러리 이용
여기서는 간단하게 PyQt5 를 이용하겠습니다. PyQt5 는 윈도우, 리눅스, 맥, 안드로이드 에서 동작할 수 있는 GUI 개발 라이브러리에요. PyQt5 역시 pip 를 이용해 설치 할 수 있습니다. 가상환경을 Enable 하고 아래 명령어로 라이브러리를 설치해 주세요 !
pip install PyQt5
라이브러리를 설치 했으면 PyQt5 를 이용해 키움증권 API로 아래 일을 해보겠습니다.
- 로그인
- 자동 로그인
- 장 구분별 종목코드 리스트
- 주가 데이터 가져오기
1. 로그인
로그인에 대해서는 아래 URL에 자세히 나와 있습니다.
아래 코드를 돌려 보세요 !
import sys from PyQt5.QtWidgets import * from PyQt5.QtGui import * from PyQt5.QAxContainer import * class MyWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("PyStock") self.setGeometry(300, 300, 300, 150) self.kiwoom = QAxWidget("KHOPENAPI.KHOpenAPICtrl.1") btn1 = QPushButton("Login", self) btn1.move(20, 20) btn1.clicked.connect(self.btn1_clicked) btn2 = QPushButton("Check state", self) btn2.move(20, 70) btn2.clicked.connect(self.btn2_clicked) def btn1_clicked(self): ret = self.kiwoom.dynamicCall("CommConnect()") def btn2_clicked(self): if self.kiwoom.dynamicCall("GetConnectState()") == 0: self.statusBar().showMessage("Not connected") else: self.statusBar().showMessage("Connected") if __name__ == "__main__": app = QApplication(sys.argv) myWindow = MyWindow() myWindow.show() app.exec_()
2. 자동 로그인
키움증권 API 는 연결 할때 마다 로그인을 해야합니다… 매우 귀찮을 일이 아닐 수 없죠
다행이 자동로그인을 하는 방법이 있습니다. 한번 해보죠
우선 로그인을 합니다.
그럼 윈도우 작업표시줄에 아래와같은 트레이가 생깁니다.

이 트레이를 우 클릭 해서 계좌비밀번호 저장 이라는 화면을 클릭하면 아래와 같은 화면이 나오는데 여기서 계좌 비밀번호를 입력하고 등록 버튼을 누른 뒤 AUTO 를 체크하면 됩니다.

이렇게 하면 이후 로그인 부터는 자동으로 로그인이 됩니다.
4. 장 구분별 종목코드 리스트 가져오기
키움증권 에서 제공하는 장의 종류는 코스피, ELW, 코스닥 등등 이 있습니다. 이 중에서 코스피, 코스닥, 코넥스의 주가 코드를 선택적으로 가져오는 프로그램을 만들어 보겠습니다.
키움증권 API 에서 제공하는 GetCodeListByMarket 함수를 사용하면 시장 별 회사의 코드 정보를 얻어 올 수 있습니다. 이 때 코드 정보만 날라오게 되는데 GetMasterCodeName 이라는 함수를 이용해 해당 코드의 기업 이름을 알 수 있습니다. (이에 대한 자세한 내용은 OpenAPI 문서를 참조하시기 바랍니다. )
그러면 이 데이터를 가지고 우리가 주식 데이터 가져오기 (종목 코드와 주가)에서 했던 것 처럼 Pandas Dataframe 으로 만들 수 있습니다.
이 기능에 추가로 이 데이터는 API 로그인이 되어있어야지만 받아오는게 가능 하겠죠 ??? 그래서 프로그램 하단 Status Bar에 API 연결 상태를 출력하는 기능을 추가했습니다.
자 그럼 아래 코드를 Pycharm 혹은 터미널에서 돌려 보세요
import sys from PyQt5.QtWidgets import * from PyQt5.QAxContainer import * import pandas as pd class KiwoomAPIWindow(QMainWindow): def __init__(self, connect=1): super().__init__() self.title = 'AutoTrader' self.left = 50 self.top = 50 self.width = 640 self.height = 480 self.initUI() self.kiwoom = QAxWidget("KHOPENAPI.KHOpenAPICtrl.1") if connect == 1: # API 연결 self.kiwoom.dynamicCall("CommConnect()") # API 연결 되었는지를 Status Bar에 출력 self.kiwoom.OnEventConnect.connect(self.login_event) def initUI(self): self.setWindowTitle(self.title) self.setGeometry(self.left, self.top, self.width, self.height) # 라벨 생성 label_market = QLabel('장 선택 ', self) label_market.move(10, 70) # 콤보 박스 생성 self.cbox_market = QComboBox(self) self.cbox_market.setGeometry(100, 70, 150, 32) self.cbox_market.setObjectName(("box")) self.cbox_market.addItem("장내", userData=0) self.cbox_market.addItem("코스닥", userData=10) self.cbox_market.addItem("코넥스", userData=50) # 버튼 생성 btn_market = QPushButton('장 리스트 가져오기', self) btn_market.setToolTip('0: 장내, 10: 코스닥, 50: 코넥스 등등등 Spec 참조 ') btn_market.resize(200, 32) btn_market.move(300, 70) btn_market.clicked.connect(self.on_click_market) self.show() def login_event(self, error): if error == 0: strs = '로그인 성공 Code : ' + str(error) self.statusBar().showMessage(strs) else: strs = '로그인 실패 Code : ' + str(error) self.statusBar().showMessage(strs) def on_click_market(self): print(self.cbox_market.currentText(), ' ',self.cbox_market.currentData()) # GetCodeListByMarket 으로 종목코드 요청 result = self.kiwoom.dynamicCall('GetCodeListByMarket(QString)', str(self.cbox_market.currentData())) code_list = result.split(';') data_list = [] for code in code_list: name = self.kiwoom.dynamicCall('GetMasterCodeName(QString)', code) data_list.append([name, code]) # 데이터 프레임으로 만들기 df = pd.DataFrame(data_list, columns=['회사명', '종목코드']) print(df.head()) if __name__ == "__main__": app = QApplication(sys.argv) kaWindow = KiwoomAPIWindow() app.exec_()
어떻게 나오시나열 ?
아래와 같이 나오면 성공입니다.
참고로 Pycharm에서 돌릴 시 Pycharm을 관리자 권한으로 실행시키시는 걸 추천합니다. 그리고 모의 투자신청이 안되어 있으면 로그인이 실패하니 모의 투자 신청 후 Try 해주세요

자 그럼 Combo Box 를 선택하고 “장 리스트 가져오기” 버튼을 눌러 봅시다. 장내, 코스닥, 코넥스를 한번씩 선택해서 눌렀는데요
아래와 같이 나오면 정상 출력 된 것 입니다. 장별로 4개 까지만 나온 이유는 head() 함수를 써서 인데요 해당 함수는 DataFrame 앞에 몇개의 데이터만 보여주는 함수입니다.

5. 주가 데이터 가져오기
는 다음시간에 할게요 .. .ㅋㅋㅋㅋ 머리 풀가동 했더니 좀 쉬어야 겠습니다.
