728x90
반응형
키움증권 API 활용기 05. 계좌잔고조회
지난번 일봉데이터불러오기 파일에 추가해서 작업.
1. 계좌번호 요청하기 > 얻기
2. 현재 잔고 종목, 수량 등 잔고 요청하기 > 얻기
3. 자동로그인 등록하기
1. 계좌번호 요청
1) 변수 선언 : account_num = None (초기화 : 번호 없음으로 시작)
self.account_num = None #계좌번호
2) 계좌정보 요청 및 출력
- 먼저, 계좌 전체 리스트를 가져오고, GetLoginInfo()
- 다음, 그중 첫번째 리스트 (0) 을 가져온다. 이를 '사용계좌번호'라고 정함
#계좌 정보
def get_account_info(self):
account_nums = str(self.kiwoom.dynamicCall("GetLoginInfo(QString)", ["ACCNO"]).rstrip(';'))
print(f"계좌번호리스트 : {account_nums}")
self.account_num = account_nums.split(";")[0]
print(f"사용계좌번호 : {self.account_num}")
3) get_account_info() '계좌정보를 얻고 출력하는 함수'를 실행하는 시점은?
- 접속을 확인하고 난 다음 순서!
#상태표시 이벤트 + 계좌번호 얻기 실행 포함
def _event_connect(self, err_code):
if err_code == 0:
print("connected")
self.get_account_info()
else:
print("disconnected")
self.login_event_loop.exit()
2. 잔고 확인
1) 잔고 불러오기 실행 설정
- 초기화 설정 마지막 라인에 잔고를 불러오는 함수를 실행한다고 했습니다.
self.get_account_balance()
2) 수신할 데이터 설정
- 처음 if 조건문은 일봉데이터 요청하는 것
- 두번째 if 조건문은 계좌 잔고를 요청하는 것
#수신 데이터
def _receive_tr_data(self, screen_no, rqname, trcode, record_name, next, unused1, unused2, unused3, unused4):
if rqname == "opt10081_req": # 일봉데이터 요청
self._on_opt10081(rqname, trcode)
elif rqname == "opw00018_req": # 계좌 요청
self._on_opw00018(rqname, trcode)
3) get_account_balance 함수 : 잔고불러오기 함수
- 계좌번호, 비밀번호 등 설정 (비밀번호는 자동입력으로 설정)
def get_account_balance(self):
self.set_input_value("계좌번호", self.account_num)
self.set_input_value("비밀번호" , "")
self.set_input_value("비밀번호입력매체구분", "00")
self.set_input_value("조회구분", "2") # 2 = 개별
self.comm_rq_data("opw00018_req", "opw00018", 0 ,"5000")
4) _on_opw00018 함수 : 잔고 정보 요청 데이터 설정 함수
def _on_opw00018(self, rqname, trcode):
현재잔고 = int(self._comm_get_data(trcode, "", rqname, 0, "추정예탁자산" ))
print(f"현재잔고: {현재잔고}")
data_cnt = self._get_repeat_cnt(trcode, rqname)
for i in range(data_cnt):
종목코드 = self._comm_get_data(trcode, "", rqname, i, "종목번호").replace("A", "").strip()
매매가능수량 = int(self._comm_get_data(trcode, "", rqname, i, "매매가능수량"))
보유수량 = int(self._comm_get_data(trcode, "", rqname, i, "보유수량"))
매입가 = int(self._comm_get_data(trcode, "", rqname, i, "매입가"))
수익률 = float(self._comm_get_data(trcode, "", rqname, i, "수익률(%)"))
print(종목코드, 매매가능수량, 보유수량, 매입가, 수익률)
3. 자동로그인 설정
- 먼저 수동으로 API에 로그인합니다.
- 그리고 나서 상태바에서 아래 아이콘을 찾습니다.
1) 윈도우 우측 하단 상태바에서 아이콘을 '우마우스' 클릭
2) '계좌비밀번호 저장' 을 클릭
3) 비밀번호 입력 후 '등록' 클릭
- AUTO 로그인 체크!!
이렇게 하면 다음 부터 파이썬에서 코드 실행시 API에 자동 로그인 됩니다.
전체 코드입니다.
import sys
import pandas as pd
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton
from PyQt5.QAxContainer import QAxWidget
from PyQt5.QtCore import QEventLoop
import datetime
class KiwoomAPI(QMainWindow):
def __init__(self) :
super().__init__()
self.daily_data_df : pd.DataFrame = pd.DataFrame(columns=['시간','시가','고가','저가','종가','거래량'])
self.account_num = None #계좌번호
btn1 = QPushButton("일봉데이터 출력", self)
btn1.resize(200,100)
btn1.clicked.connect(self.btn1_clicked)
self.kiwoom = QAxWidget("KHOPENAPI.KHOpenAPICtrl.1")
self._set_signal_slots()
self.login_event_loop = QEventLoop()
self.kiwoom.dynamicCall("CommConnect()")
self.login_event_loop.exec_()
self.request_opt10081("039490", date = datetime.datetime.now().strftime("%Y%m%d"))
self.get_account_balance()
#계좌 정보
def get_account_info(self):
account_nums = str(self.kiwoom.dynamicCall("GetLoginInfo(QString)", ["ACCNO"]).rstrip(';'))
print(f"계좌번호리스트 : {account_nums}")
self.account_num = account_nums.split(";")[0]
print(f"사용계좌번호 : {self.account_num}")
def get_account_balance(self):
self.set_input_value("계좌번호", self.account_num)
self.set_input_value("비밀번호" , "")
self.set_input_value("비밀번호입력매체구분", "00")
self.set_input_value("조회구분", "2") # 2 = 개별
self.comm_rq_data("opw00018_req", "opw00018", 0 ,"5000")
def btn1_clicked(self):
print(self.daily_data_df)
#이벤트 발생시 TR데이터 수신을 위한 메소드 설정
def _set_signal_slots(self):
self.kiwoom.OnEventConnect.connect(self._event_connect)
self.kiwoom.OnReceiveTrData.connect(self._receive_tr_data)
#상태표시 이벤트 + 계좌번호 얻기 실행 포함
def _event_connect(self, err_code):
if err_code == 0:
print("connected")
self.get_account_info()
else:
print("disconnected")
self.login_event_loop.exit()
#수신할 데이터에 대한 설정
def comm_rq_data(self, rqname, trcode, next, screen_no):
self.kiwoom.dynamicCall("CommRqData(QString, QString, int, QString)", rqname, trcode, next, screen_no)
#요청을 위한 입력값에 대한 설정
def set_input_value(self, id, value):
self.kiwoom.dynamicCall("SetInputValue(QString, QString)", id, value)
#setInputValue 요청을 위한 함수
def request_opt10081(self, code, date):
self.set_input_value("종목코드", code)
self.set_input_value("기준일자", date)
self.set_input_value("수정주가구분", 1)
self.comm_rq_data("opt10081_req", "opt10081", 0, "5000")
#수신 데이터
def _receive_tr_data(self, screen_no, rqname, trcode, record_name, next, unused1, unused2, unused3, unused4):
if rqname == "opt10081_req": # 일봉데이터 요청
self._on_opt10081(rqname, trcode)
elif rqname == "opw00018_req": # 계좌 요청
self._on_opw00018(rqname, trcode)
# 요청하여 불러올 데이터
def _comm_get_data(self, code, real_type, field_name, index, item_name):
ret = self.kiwoom.dynamicCall("CommGetData(QString, QString, QString, int, QString)", code,
real_type, field_name, index, item_name) # index = 몇번째값, item_name = 이름
return ret.strip()
#데이터 갯수 세기
def _get_repeat_cnt(self, trcode, rqname):
ret = self.kiwoom.dynamicCall("GetRepeatCnt(QString, QString)", trcode, rqname)
return ret
#수신한 데이터 결과물 실행
def _on_opt10081(self, rqname, trcode):
data_cnt = self._get_repeat_cnt(trcode, rqname)
for i in range(data_cnt):
date = self._comm_get_data(trcode, "", rqname, i, "일자")
open = self._comm_get_data(trcode, "", rqname, i, "시가")
high = self._comm_get_data(trcode, "", rqname, i, "고가")
low = self._comm_get_data(trcode, "", rqname, i, "저가")
close = self._comm_get_data(trcode, "", rqname, i, "현재가")
volume = self._comm_get_data(trcode, "", rqname, i, "거래량")
self.daily_data_df.loc[i] = {
'시간' : date,
'시가' : int(open),
'고가' : int(high),
'저가' : int(low),
'종가' : int(close),
'거래량' : int(volume),
}
def _on_opw00018(self, rqname, trcode):
현재잔고 = int(self._comm_get_data(trcode, "", rqname, 0, "추정예탁자산" ))
print(f"현재잔고: {현재잔고}")
data_cnt = self._get_repeat_cnt(trcode, rqname)
for i in range(data_cnt):
종목코드 = self._comm_get_data(trcode, "", rqname, i, "종목번호").replace("A", "").strip()
매매가능수량 = int(self._comm_get_data(trcode, "", rqname, i, "매매가능수량"))
보유수량 = int(self._comm_get_data(trcode, "", rqname, i, "보유수량"))
매입가 = int(self._comm_get_data(trcode, "", rqname, i, "매입가"))
수익률 = float(self._comm_get_data(trcode, "", rqname, i, "수익률(%)"))
print(종목코드, 매매가능수량, 보유수량, 매입가, 수익률)
#기본 실행 조건
if __name__ == "__main__":
app = QApplication(sys.argv)
kiwoom_api = KiwoomAPI()
kiwoom_api.show()
sys.exit(app.exec_())
728x90
반응형