키움증권 API를 활용한 잔고조회 코드 설명
키움증권 API를 사용하면 사용자의 계좌 잔고, 거래 내역, 주식 가격 등을 조회할 수 있습니다. 이 블로그에서는 PyQt5와 키움증권의 Open API를 이용하여 잔고를 조회하는 코드를 단계별로 설명하겠습니다. 코드는 PyQt5를 사용해 GUI를 구현하고 키움증권 API와 상호작용하여 실시간 데이터를 받아 처리합니다.
1. 라이브러리 및 클래스 초기화
from PyQt5.QAxContainer import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
import time
import pandas as pd
from util.const import *
PyQt5는 GUI 애플리케이션 개발을 위한 도구이며, QAxContainer는 ActiveX 컨트롤을 쉽게 사용할 수 있게 도와줍니다. 또한, time과 pandas 라이브러리는 요청 대기 및 데이터 처리를 위한 도구입니다.
class Kiwoom(QAxWidget):
# 초기설정 함수
def __init__(self):
super().__init__()
self._make_kiwoom_instance()
self._set_signal_slots()
self._comm_connect()
self.account_number = self.get_account_number()
self.tr_event_loop = QEventLoop()
self.order = {}
self.balance = {}
self.universe_realtime_transaction_info = {}
Kiwoom 클래스는 QAxWidget을 상속받아 키움증권의 API와 연동됩니다. 생성자에서 초기 설정을 하고, 로그인, 계좌번호 조회 등을 처리하는 여러 메서드를 호출합니다.
2. Kiwoom API 인스턴스 생성 및 로그인
# kiwoom API와 연동함수
def _make_kiwoom_instance(self):
self.setControl("KHOPENAPI.KHOpenAPICtrl.1")
여기서는 QAxWidget의 setControl 메서드를 사용해 키움증권 Open API 컨트롤을 초기화합니다.
# 로그인 요청함수
def _comm_connect(self):
self.dynamicCall("CommConnect")
self.login_event_loop = QEventLoop()
self.login_event_loop.exec_()
CommConnect 메서드를 통해 로그인 요청을 보냅니다. 로그인 완료 여부는 QEventLoop 객체를 통해 확인됩니다.
3. 계좌번호 조회
# 계좌번호 요청함수
def get_account_number(self, tag="ACCNO"):
acount_list = self.dynamicCall("GetLoginInfo(QString)", tag)
acount_number = acount_list.split(';')[0]
return acount_number
로그인 후 계좌번호를 요청하는 부분입니다. GetLoginInfo 메서드를 통해 계좌번호를 받아옵니다.
4. 잔고 조회 함수 구현
이제 본격적으로 잔고를 조회하는 코드를 살펴보겠습니다. 이 코드는 특정 계좌의 잔고와 보유한 종목들의 정보를 조회하여 출력합니다.
# 잔고요청 함수
def get_balance(self):
self.dynamicCall("SetInputValue(QString, QString)", "계좌번호", self.account_number)
self.dynamicCall("SetInputValue(QString, QString)", "비밀번호입력매체구분", "00")
self.dynamicCall("SetInputValue(QString, Qstring)", "조회구분", "1")
self.dynamicCall("CommRqData(QString, QString, int, QString)", "opw00018_req", "opw00018", 0, "0002")
self.tr_event_loop.exec_()
return self.tr_data
- SetInputValue는 요청 시 필요한 파라미터를 설정하는 함수입니다.
- 계좌번호: 조회할 계좌의 번호
- 비밀번호입력매체구분: 로그인된 상태에서는 '00'으로 설정
- 조회구분: '1'은 잔고조회
- CommRqData는 데이터를 요청하는 함수입니다.
- "opw00018_req": 잔고조회 요청명령
- "opw00018": 요청코드
- 화면번호는 "0002"로 임의 설정
tr_event_loop는 요청이 완료될 때까지 대기하는 역할을 하며, 요청이 완료되면 잔고 데이터를 반환합니다.
5. TR 데이터 처리 함수
잔고조회 요청 후 받은 데이터를 처리하는 함수는 _on_receive_tr_data입니다.
# tr data 처리함수
def _on_receive_tr_data(self, screen_no, rqname, trcode, record_name, next, unused1, unused2, unused3, unused4):
tr_data_cnt = self.dynamicCall("GetRepeatCnt(QString, QString)", trcode, rqname)
# 잔고조회
if rqname == "opw00018_req":
for i in range(tr_data_cnt):
code = self.dynamicCall("GetCommData(QString, QString, int, QString)", trcode, rqname, i, "종목번호")
code_name = self.dynamicCall("GetCommData(QString, QString, int, QString)", trcode, rqname, i, "종목명")
quantity = self.dynamicCall("GetCommData(QString, QString, int, QString)", trcode, rqname, i, "보유수량")
purchase_price = self.dynamicCall("GetCommData(QString, QString, int, QString)", trcode, rqname, i, "매입가")
return_rate = self.dynamicCall("GetCommData(QString, QString, int, QString)", trcode, rqname, i, "수익률(%)")
current_price = self.dynamicCall("GetCommData(QString, QString, int, QString)", trcode, rqname, i, "현재가")
total_purchase_price = self.dynamicCall("GetCommData(QString, QString, int, QString)", trcode, rqname, i, "매입금액")
available_quantity = self.dynamicCall("GetCommData(QString, QString, int, QString)", trcode, rqname, i, "매매가능수량")
code = code.strip()[1:]
code_name = code_name.strip()
quantity = int(quantity)
purchase_price = int(purchase_price)
return_rate = float(return_rate)
current_price = int(current_price)
total_purchase_price = int(total_purchase_price)
available_quantity = int(available_quantity)
self.balance[code] = {
'종목명': code_name,
'보유수량': quantity,
'매입가': purchase_price,
'수익률': return_rate,
'현재가': current_price,
'매입금액': total_purchase_price,
'매매가능수량': available_quantity
}
self.tr_event_loop.exit()
time.sleep(0.5)
- GetRepeatCnt: 반복 데이터를 가져오기 위한 함수로, 보유 종목의 개수를 의미합니다.
- GetCommData: 종목번호, 보유수량, 매입가, 현재가 등의 정보를 받아옵니다.
- 데이터를 각각 받아와서 self.balance 딕셔너리에 저장합니다.
6. 잔고 데이터 출력
print(self.balance)
잔고 데이터를 조회한 후에는 이를 출력하거나 필요한 형태로 가공할 수 있습니다. 예를 들어, self.balance는 각 종목의 정보를 포함하는 딕셔너리로, 보유한 주식의 상태를 확인할 수 있습니다.
7. 결론
이 코드 예제에서는 키움증권 API를 이용하여 계좌 잔고와 보유 종목의 정보를 조회하는 방법을 설명했습니다. 키움증권의 OpenAPI와 PyQt5를 사용하면 다양한 트레이딩 도구를 개발할 수 있습니다.