키움증권 API 활용기 04. 일봉데이터 조회 요청
키움증권 API 활용기 04. 일봉데이터 조회 요청
1. TR요청 개요
[실시간시세 사용법]
조회 서비스 이용 순서
1) SetInputValue(사용자 호출) : 입력
2) CommRqData(사용자 호출) : 요청
3) OnReceiveTrData(이벤트 발생) : 수신
[OPT10081 : 주식일봉차트조회요청예시]
1) SetInputValue() : 어떤 종목, 언제부터 불러올 것이냐 ('수정주가' 적용 유무 선택)
SetInputValue("종목코드" , "039490"); // 어떤 종목?
SetInputValue("기준일자" , "20160101");// 어느시점 이전부터 ?
SetInputValue("수정주가구분" , "1"); // 수정주가 적용 유무?
2) CommRqData() : 누가 어떤TR항목(요청사항)을 (비)연속조회로, (몇)번 화면에 연결할거냐
LONG lRet = CommRqData( "RQName","OPT10081", "0","0600");
3) OnReceiveTrData() : 데이터 수신을 실행해라!
2. 실 사용 방법
KOA 스튜디오 실행 후, TR목록 / opt10081 : 주식일봉차트조회요청
- 좌측 하단 목록에서 TR목록을 선택
- 좌측열에서 opt10081을 찾아 선택하여 설명을 참조
1) 입력 정보 함수 : SetInputValue( id, value)
조회요청에 필요한 입력 정보 (즉, 요청할 때 필요한 입력값들과 그 형식)
종목코드 | KRX : 000000, NXT : 000000_NX, 통합: 000000_AL |
기준일자 | YYYYMMDD |
수정주가구분 | 0 : 미적용, 1 : 적용 |
코드 예시
setInputValue( id, value)
실사용 예시
종목코드 : 키움증권 코드
기준일자 : 입력 날짜 이전~
수정주가구분 : 1 = 적용
SetInputValue("종목코드" , "039490"); // 키움증권
SetInputValue("기준일자" , "20250924");// 2025년 09월 25일 이전~
SetInputValue("수정주가구분" , "1"); // 수정주가 적용
2) 조회 요청 함수 CommRqData( name , code, next , screenNo )
조회에 필요한 기본 값
CommRqData(
BSTR sRQName, // 사용자 구분명 (임의로 지정, 한글지원)
BSTR sTrCode, // 조회하려는 TR이름
long nPrevNext, // 연속조회여부
BSTR sScreenNo // 화면번호 (4자리 숫자 임의로 지정)
)
3) 데이터 수신 이벤트 OnReceiveTrData
- 조회와 실시간 데이터 처리 / 관련 함수
- 요청했던 조회데이터를 수신했을때 발생됨.
-실제 수신을 위한 함수는 GetCommData()함수를 통해 얻을 수 있음.
def _receive_tr_data(self, screen_no, rqname, trcode, record_name, next, unused1, unused2, unused3, unused4):
변수를 달리해도 되지만 위 항목들의 순서를 지켜서 요청해야함.
sScrNo | 화면번호 |
sRQName | 사용자 구분명 |
sTrCode | TR 명 |
sRecordName | 레코드 명 |
sPreNext | 연속조회 유무 |
nDataLength | 사용안함 |
sErrorCode | 사용안함 |
sMessage | 사용안함 |
sSplmMsg | 사용안함 |
위 코드에서 사용한 예시 설명
- tr 데이터 수신은 : '화면번호', '사용자구분명', 'TR명', '레코드명', '연속조회유무' 여기 까지 사용된다고 보면되겠다.
- 이를 순서에 맞춰 변수로 할당한 것이 아래 예시이다.
screen_no = sScrNo : 화면번호
rqname = RQName : 사용자구분명
trcode = sTrCode : TR명
record_name = sRecordName : 레코드명
next = sPreNext : 연속조회 유무
순서
1. 키움 API 연결
2. 이벤트 설정 : 1) 접속 연결시, 2) TR 데이터 수신시
3. 로그인 이벤트 루프 설정
4. 로그인 상태표시
5. 입력값 정의
6. 출력값 정의
7. 데이터 종류 정의
8. 수신 데이터의 조회 설정
9. 수신 데이터의 항목들 설정
10. 실행
1. 일봉 데이터 조회 요청 코드
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=['시간','시가','고가','저가','종가','거래량'])
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"))
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")
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)
# 요청하여 불러올 데이터
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),
}
#기본 실행 조건
if __name__ == "__main__":
app = QApplication(sys.argv)
kiwoom_api = KiwoomAPI()
kiwoom_api.show()
sys.exit(app.exec_())
콘솔창 출력 확인
- 좌측부터 날짜, 시가, 고가, 저가, 종가, 거래량 이 불러와졌다.
- 오늘 날짜부터 과거 전체 기간동안 데이터가 불러와진다. 최대 600개