파이썬에서 키움증권의 클래스를 사용하려면 PyQt의 QAxWidget 클래스를 사용하여 인스턴스를 생성해야 함.
키움증권이 제공하는 클래스는 각각 고유의 CLSID 또는 ProgID를 가지는데 해당 값을 QAxWidget 클래스의 생성자로 넘겨주면 인스턴스가 생성됨.
키움증권의 개발 가이드를 참조하면 CLSID는 {A1574A0D-6BFA-4BD7-9020-DED88711818D} 임을 알 수 있고, 이를 윈도우 레지스트리 편집기를 통해 검색하면 ProgID는 아래와 같이 `‘KHOPENAPI.KHOpenAPICtrl.1’ 임을 알 수 있음.
CLSID는 10진수로 구성되어 있어 조금 복작하기 때문에 파이썬에서 증권사 API가 제공하는 클래스의 인스턴스를 생성할 때는 보통 문자열로 된 ProgID를 사용하는 것이 편리.
키움증권이 제공하는 클래스를 사용하기 위해 ProgID를 QAxWidget 클래스의 생성자로 전달하여 인스턴스를 생성.
키움이 제공하는 클래스 사용
1 2 3 4
classMyWindow(QMainWindow): def__init__(self): # 코드 생략 self.kiwoom = QAxWidget("KHOPENAPI.KHOpenAPICtrl.1")
self.kiwoom은 QAxWidget 클래스의 인스턴스인데 QAxWidget 클래스는 아래와 같이 QWidget과 QAxBase라는 클래스를 상속 받음.
OpenAPI+는 로그인 윈도우를 실행하는 CommConnect 메서드를 제공.
즉, 인스턴스를 통해 CommConnect 메서드를 호출하기만 하면 로그인을 위한 윈도우가 자동으로 실행됨.
키움증권의 OpenAPI+는 OCX 방식으로 개발되었기 때문에 파이썬에서 메서드를 호출하는 방식도 COM 방식과는 다름.
COM 방식에서는 인스턴스를 통해 메서드를 호출했던 것과 달리 OCX 방식에서는 QAxBase 클래스의 dynamicCall 메서드를 사용하여 원하는 메서드를 호출할 수 있음.
정리해보면 OpenAPI+가 제공하는 메서드를 사용하기 위해서는 self.kiwoom 객체를 통해 dynamicCall 메서드를 호출해야 함.
이때 dynamicCall 메서드의 인자로 호출하려는 메서드를 넘겨줌.
call CommConnect
1
self.kiwoom.dynamicCall("CommConnect()")
서버 접속 상태를 확인 하기 위해 GetConnectState 메서드를 호출한 후 메서드의 리턴 값을 확인.
OpenAPI+의 CommConnect 메서드를 통해 키움증권 서버에 로그인을 시도하면 키움증권 서버는 아래와 같이 OnEventConnect라는 이벤트를 발생.
따라서 프로그램이 OnEventConnect 이벤트를 처리한다면 GetConnectState 메서드를 사용하지 않고도 로그인 상태 확인 가능.
OpenAPI+는 통신 연결 상태가 변경될 때 OnEventConnect라는 이벤트가 발생.
발생된 OnEventConnect 이벤트를 처리하기 위해 MyWindow 클래스에 event_connect라는 이름의 메서드를 구현하고
이벤트와 이벤트 처리 메서드를 연결 시키면 이벤트(OnEventConnect) 발생 시 자동으로 이벤트 처리 메서드 (self.event_connect)가 호출 됨.
event_connect 메서드는 메서드의 인자로 넘어오는 err_code 값을 확인. QTextEdit 객체에 문자열을 추가하기 위해 append라는 메서드를 사용.
참고로 이 append는 파이썬 리스트의 append 메서드와 전혀 관련 없음.
각 TR의 기능을 살펴보고 원하는 기능을 제공하는 TR을 사용하여 데이터를 서버에 요청한 후 전송된 값을 받으면 됨.
아래는 opt1001TR를 사용하여 주식 종목의 기본적인 정보를 얻어오는 프로그램의 모습
PyQt를 사용하여 UI를 구성하는 코드 구현
사용된 PyQt 위젯 리스트
클래스
용도
QLabel
간단한 텍스트 나 이미지 출력(‘종목코드:’ 출력)
QLineEdit
간단한 사용자 입력 처리
QPushButton
버튼 생성(‘조회’ 버튼 생성)
QTextEdit
메시지 출력 (실행결과 메시지)
QLabel은 텍스트나 이미지를 출력하는 데 사용. 만약 텍스트를 출력한다면 생성자의 첫 번째 인자로 출력될 문자열을 넘겨주면 됨.
두 번째 인자에는 부모 위젯을 지정. 아래 전체 코드에서 QLable은 QMainWindow안에 위치하므로 부모 위젯으로 self를 지정. label = QLabel('종목코드: ', self)
QLineEdit 위젯을 통해 입력받은 종목 코드를 'SetInputValue` 메서드의 두 번째 인자로 넘겨주는 것을 확인.
TR 구성이 완료됐다면 CommRqData 메서드를 사용하여 TR을 서버로 송신. CommRqData의 첫 번째 인자는 사용자가 TR을 구분하기 위한 용도.
두 번째 인자는 요청하는 TR 이름으로 opt10001을 입력.
세 번째 인자는 단순 조회 TR일 때는 0을 입력.
네 번째 인자는 4자리의 화면 번호.
TR을 서버로 송신했으므로 OnReceiveTrData라는 이벤트를 처리할 메서드를 구현하고 이를 이벤트와 연결.
OnReceiveTrData 이벤트가 발생했다는 것은 서버로부터 데이터를 전달 받았음을 의미하므로 OnReceiveTrData 메서드에서 CommGetData 메서드를 호출하여 데이터를 얻음.
GetLoginInfo 메서드는 이벤트 방식으로 동작하는 것도 아니므로 단순히 dynamicCall 메서드를 통해 호출하면 값을 바로 얻을 수 있음.
다만 메서드의 인자가 한 개인데 실제 인자를 넘겨주는 부분에서 다음 코드와 같이 반드시 리스트 형태로 값을 넘겨줘야 함.
GetCodeListByMarket 메서드의 리턴 값은 문자열이고 해당 문자열 내에서 각 종목은 세미콜론으로 구분.
종목 코드를 효과적으로 관리하기 위해 세미콜론을 기준으로 문자열을 분리하여 파이썬 리스트를 생성.
1
kospi_code_list = ret.split(';')
한글 종목명 얻기
1 2 3 4
kospi_code_name_list = [] for x in kospi_code_list: name = self.kiwoom.dynamicCall("GetMasterCodeName(QString)", [x]) kospi_code_name_list.append(x + " : " + name)
종목 코드와 종목 한글명이 저장된 파이썬 리스트를 addItems 메서드의 인자로 넘겨주어 파이썬 리스트에 있는 항목들이 QListWidget에 추가되도록 해줌.