목 차
1. 들어가며
2. 사전설명
1) 실시간 데이터 받는 원리
2) realtype 및 fid 값의 개념
3. 코드설명
4. 전체코드
5. 마치며
1. 들어가며
지난 글에서는 키움증권 OpenAPI-W를 통해 해외선물의 "실시간 데이터 받아오는 원리"에 대해 알아보았다. 코드를 어떻게 짜야될지 막막할 때는 WKOA Studio에 종목코드 등을 입력하고 "조회"를 누르면, 수신받는 데이터의 태형(type)이나 결과물(현재가, 체결량 등) 등을 확인할 수 있어서 좋은 것 같다.
이번 글에서는 "실시간 데이터 받기"에 관한 코드를 작성해보자. "非실시간 데이터 받기"에 익숙해졌다면, 비교적 쉽게 접근가능할 것이라 생각된다. 천천히 살펴보자.
2. 사전설명
1) 실시간 데이터 받는 원리
< 그림1 >은 실시간 데이터 받는 원리를 설명하였다. 데이터입력(①) - 데이터요청(②)까지는 절차가 똑같다. 차이가 난다면, 실시간 연결(⑤) 및 실시간 수신(⑥)에서 차이가 난다.
2) realtype 및 fid 값의 개념
realtype는 무엇인가? fid 값들의 모음이라고 생각하면 된다. fid 값을 찾을 때는 realtype을 먼저 찾고, fid 값을 찾는다. < 그림2-1 >에서는 realtype 이름이 "해외선물시세(②)" 아래에 있는 현재가(fid 14)를 찾을 수 있다. < 그림2-1 >에서 출력화면에서 realtype이 "해외선물시세"인 것을 확인할 수 있다.
fid 값은 각 단어에 붙는 "고유한 값"이라고 생각하면 된다. < 그림2-1 >에서 체결시간은 20, 현재가는 140, 전일대비는 11이 각각의 고유한 fid 값이다.
※ 국내주식 OpenAPI에서는 fid값들의 모음을 "realtype"이라고 하며, 해외선물에서는 "realname"로 부르고 있긴하다. 필자는 realtype으로 설정했는데 에러없이 잘 돌아간다. 사용자 판단에 따라 realtype의 코드이름을 정하자.
< 그림2-2 >는 realtype이 "해외선물호가"인 fid 값(②)을 확인할 수 있다.
3. 코드설명
활용될 라이브러리, 로그인 등의 내용은 설명을 생략한다.
1줄~35줄 : 활용될 라이브러리, 로그인 등의 내용은 설명을 생략한다.
13줄 : 이 글의 첫번째 핵심이다. 실시간 데이터를 받으려면 데이터 입력-요청을 통해 키움증권에서 이벤트가 발생하는데, 사용자가 수신받을 함수(46줄)와 이벤트를 실시간 연결한다.
38줄~43줄 : 74줄에서 전달해준 2개 변수(NQZ23, 1분)을 키움증권에 입력(SetInputValue) 및 요청(CommRqData)한다.
46줄~68줄 : 이 글의 두번째 핵심이다. 실시간 수신받을 함수를 선언한다.키움증권 서버에서 이벤트가 발생하면 11줄(OnReceiveRealData)와 연결되어서, 데이터를 실시간 수신(GetCommRealData)받는다.
46줄 : 키움서버에서 전달받은 종목, realtype(fid 값 모음), realdata(활용하지 않음)의 3가지 정보를 수신받는 함수를 정의한다.
48줄 : print 문을 주석처리하지 않았다. 전달받은 realtype가 무엇인지 알아야, 향후 코드 짜는게 편할 것이다. "전달받은 realtype"를 확인하였다면, 주석처리해도 된다.
50줄 : 키움증권에서 전달받은 realtype가 "해외선물시세"이면,
51줄~52줄 : 현재가격과 체결량을 실시간으로 가져와라.
54줄~55줄 : 지금은 주석처리를 했지만, 필요하면 주석을 풀고 실행해도 된다. "현재가격과 체결량"을 실시간으로 계속 가져온다.
57줄~64줄 : 키움증권에서 전달받은 realtype가 "해외선물호가"이면, "호가시간", "최우선매도호가", "최우선매수호가"의 데이터를 출력한다. (지금은 주석처리)
current_price = abs(float(self.kiwoom.dynamicCall("GetCommRealData(QString, int)", scode, 140).strip()))
volume = float(self.kiwoom.dynamicCall("GetCommRealData(QString, int)", scode, 15).strip())
※ 여기서 잠깐!!! GetCommRealData 함수를 활용하는 방법
GetCommRealData 함수는 2가지 변수를 받는다. 종목코드(scode)와 fid 값이다.
GetCommRealData을 통해 전달받은 데이터의 태형은 문자형(str)이다. 현재가격 및 체결량의 경우 실수(float)형으로 만들었다.
66줄~68줄 : 키움증권에서 전달받은 realtype가 "잔고"이면,
68줄 : 종목코드를 출력하라. 실제 "종목코드"는 실행되지 않는다. 왜? 키움증권은 "해외선물시세" 및 "해외선물호가"의 2가지 realtype만 제공하는 것 같다. ㅠㅠ
74줄 : 74줄에서 "종목코드, 분봉"을 넣은 후 38줄의 함수에 변수를 넣어서 실행한다.
4. 전체코드
< 접은글 >의 코드를 실행하려면 키움증권에 월 시세 이용료($185)를 지불하여야 한다.
import sys
from PyQt5.QAxContainer import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
class btlg_system():
def __init__(self):
self.kiwoom = QAxWidget("KFOPENAPI.KFOpenAPICtrl.1")
print("로그인 시작!")
self.kiwoom.OnEventConnect.connect(self.login_Connect)
self.kiwoom.OnReceiveRealData.connect(self.tr_realdata_get)
self.kiwoom.dynamicCall("CommConnect(1)") # CommConnect() : 괄호 안에 자동(1)을 넣는다.
self.login_event_loop = QEventLoop() # from PyQt5.QtCore import * : qtcore가 임포트되어야 함
self.login_event_loop.exec_()
self.kiwoom.dynamicCall("GetCommonFunc(QString, QString)", "ShowAccountWindow", "") # 계좌번호 입력창을 띄우는 내부함수
########### 국내주식과는 달리 setrealreg를 사용하지 않는다 #################
# self.kiwoom.dynamicCall("SetRealReg(QString, QString, QString, QString)", "1746", "NQZ23", 15, "0") # 해선에서는 사용하지 않는 코드이다.
# self.kiwoom.dynamicCall("SetRealReg(QString, QString, QString, QString)", "2746", "NQZ23", 15, "1") # 해선에서는 사용하지 않는 코드이다.
######################################################################
#### 해외선물의 실시간 데이터 조회는, 차트조회(opc10002) 등을 통해 commrqdata를 조회하면, OnReceiveTrData에 연결되며 GetCommRealData로 데이터를 수신받는다.
#### 해당종목이 실시간 자동등록되어, OnReceiveRealData로 수신되는 구조
########## 로그인 관련 함수 ##########
def login_Connect(self, err_code):
if err_code == 0:
print('로그인 성공했습니다!')
self.login_event_loop.exit()
else:
print('로그인 실패했습니다!')
######## 키움서버에 TR 요청하는 함수 모음 ##########
def rq_data_opc10002(self, stock_code_num, time_unit):
self.kiwoom.dynamicCall("SetInputValue(QString,QString)", "종목코드", stock_code_num)
self.kiwoom.dynamicCall("SetInputValue(QString,QString)", "시간단위", time_unit)
self.kiwoom.dynamicCall("CommRqData(QString, QString, QString, QString)", "opc_10002", "opc10002", "", "5000")
self.tr_event_loop = QEventLoop()
self.tr_event_loop.exec_()
########## OnReceiveRealData을 통해 수신받은 데이터 함수 ##########
def tr_realdata_get(self, scode, realtype, realdata):
# print(scode)
print(realtype)
if realtype == "해외선물시세":
current_price = abs(float(self.kiwoom.dynamicCall("GetCommRealData(QString, int)", scode, 140).strip()))
volume = float(self.kiwoom.dynamicCall("GetCommRealData(QString, int)", scode, 15).strip())
# print(current_price)
# print(volume)
elif realtype == "해외선물호가":
hoga_time = float(self.kiwoom.dynamicCall("GetCommRealData(QString, int)", scode, 21).strip())
first_sell_hoga = float(self.kiwoom.dynamicCall("GetCommRealData(QString, int)", scode, 27).strip())
first_buy_hoga = float(self.kiwoom.dynamicCall("GetCommRealData(QString, int)", scode, 28).strip())
# print(hoga_time) # 호가시간
# print(first_sell_hoga) # 최우선매도호가
# print(first_buy_hoga) # 최우선매수호가
elif realtype == "잔고": # "잔고"는 제공하지 않는다.
code = float(self.kiwoom.dynamicCall("GetCommRealData(QString, int)", scode, 9203).strip())
print(code)
if __name__ == "__main__":
app = QApplication(sys.argv)
btl = btlg_system()
btl.rq_data_opc10002("NQZ23", "1")
# btl.tr_realdata_get("NQZ23", "해외선물시세", "") # 14줄의 OnReceiveRealData와 '실시간 데이터 수신(tr_realdata_get)'가 연결(connect)되어야 실시간 데이터를 수신받을 수 있다.
app.exec_()
5. 마치며
실시간 데이터 받는 코드를 알아보았다. "데이터입력-요청-연결-수신"의 "非실시간 데이터 받기" 틀에서 크게 벗어나지 않았다. 최초에 어떻게 접근해야할지, 그 부분에서 고민이 길었던 것 같다. WKOA Studio에서 실시간 데이터 받기가 되니, 혹시나 몰라 opc10002를 통해 데이터 입력(SetInputValue) 및 요청(CommRqData)를 넣어 코드를 작성해서 실행해보니, 운이 좋게도 실시간 데이터를 받아올 수 있었다.
본문에서도 언급하였지만, 필자의 실력부족 때문인지 해외선물시세, 해외선물호가 등 2개 realtype만 받아올 수 있었다.
'이렇게 데이터를 받아올 수 있구나' 정도로 생각하자. 어떤 조회방법을 선택하든 수익만 나면 훌륭한 매매이다.
'2. 해외선물 > 2-1. 해외선물 자동매매 연구' 카테고리의 다른 글
(키움증권 해외선물 자동매매 파이썬) (1) 실시간 데이터 받아오는 원리 (1) | 2023.11.03 |
---|---|
(키움증권 해외선물 자동매매 파이썬) 22. 진입/청산 알고리즘 구상하기(完) (2) | 2023.10.29 |
(키움증권 해외선물 자동매매 파이썬) 21. 매매내역을 엑셀로 기록하기 (8) | 2023.10.28 |
(키움증권 해외선물 자동매매 파이썬) 20. 오버나잇(overnight) 피하는 방법 (매매 종료시간 설정) (5) | 2023.10.27 |
(키움증권 해외선물 자동매매 파이썬) 19. 매매시간 및 대기시간 설정 (0) | 2023.10.26 |
(키움증권 해외선물 자동매매 파이썬) 18. 진입/청산 시도횟수 체크하기 (2) | 2023.10.25 |
(키움증권 해외선물 자동매매 파이썬) 17. 시간별 다른 코드 적용하기 (3) | 2023.10.24 |
(키움증권 해외선물 자동매매 파이썬) 16. 현재시간 출력하기 (5) | 2023.10.23 |