트레이딩

[키움API] KOA StudioSA 톺아보기 - 조회와 실시간 데이터 처리 (1)

성민석 2021. 11. 2. 12:17

안녕하세요 성민석입니다.

오늘은 키움증권 API와 관련된 기본 설명과 동작을 설명드릴 예정입니다. 기본적으로 KOA StudioSA에서 제공해주는 내용을 바탕으로 글을 작성해나갈 예정입니다. 여기서 제 개인적인 의견이나 첨언이 들어갈 경우 파란색으로 표시하겠습니다.

 

지난 포스팅에는 키움API와 관련하여 로그인 버전 처리에 대해서 알려드렸습니다.

2021.10.31 - [트레이딩/증권사 API] - [키움API] 로그인 버전 처리

 

[키움API] 로그인 버전 처리

안녕하세요 성민석입니다. 오늘은 키움증권 API와 관련된 기본 설명과 동작을 설명드릴 예정입니다. 기본적으로 KOA StudioSA에서 제공해주는 내용을 바탕으로 글을 작성해나갈 예정입니다. 여기서

minsuk-sung.tistory.com

 

이번 포스팅에서는 키움증권API에서 가장 중요한 내용인 TR조회에 대해서 알려드리겠습니다. 저번 시간과 다르게 TR요청과 실시간 데이터 처리를 한 번에 다루기엔 양이 방대해서 포스팅을 두 개로 나눠서 올립니다.

 


조회 처리(조회 요청)

OpenAPI가 제공하는 데이터중에서 원하는 데이터를 서버에 요청해서 수신받는 것을 말합니다. 이는 하나의 TR(Transaction) 단위로 처리됩니다. 각 TR은 서버와 데이터를 주고받을 때 약속된 규약입니다. 각각의 TR은 입력 부분(Input)과 출력 부분(Output)을 가지고 있습니다. Input은 사용하는 TR에 따라 항목이 달라지며 사용자(고객)가 입력해야 하는 부분(이때 쓰이는 함수가 SetInputValue함수)이고, Output은 요청에 대한 서버의 응답으로 수신(이때 쓰이는 함수가 CommRqData함수)되는 데이터입니다. Output은 여러 항목으로 제공되며 필요한 항목의 값만을 골라서 얻을 수 있습니다. 

 

출력 부분은 항목이 하나로 전달되는 싱글 데이터와 복수의 건수로 전달되는 멀티 데이터가 있습니다. TR에 따라 싱글데이터(또는 멀티데이터)만 있거나 둘 다 있는 경우도 있습니다. 싱글데이터와 멀티데이터가 제공해주는 데이터는 모두 다릅니다.

 

OPT10070 : 당일주요거래원요청 - 싱글 데이터
OPT10081 : 주식일봉차트조회요청 - 싱글 + 멀티데이터

 

OpenAPI가 제공하는 TR들은 KOA Studio의 "TR목록" 탭에서 찾아볼 수 있습니다. 이중 필요한 TR을 선택하여 약속된 Input값을 입력 후 서버에 요청하면 해당 TR에 정의되어 있는 Output 항목들의 값을 구할 수 있습니다.

 

※ 주의할 점: 조회 시 입력값 항목들은 SetInputValue 함수로 반드시 순서에 맞게 입력해야 합니다.

계좌 비밀번호는 별도의 입력창으로 입력/등록하고 조회 시에는 공백으로 입력합니다.

ex) SetInputValue("비밀번호" ,  "");

 

일반적으로 GetRepeatCnt() 함수를 이용하여 TR요청을 통해서 한 번에 받을 수 있는 데이터의 총 수를 확인합니다. 예를 들어 차트조회는 한 번에 최대 900개 데이터를 수신할 수 있는데 이렇게 수신한 데이터 개수를 얻을 때 사용합니다. 이 함수는 OnReceiveTRData() 이벤트가 발생될 때 그 안에서 사용해야 합니다.

 

조회 요청/수신 사용법

조회 요청하고자 하는 TR의 입력값(input)을 셋팅한뒤 조회 요청을 합니다. 서버는 요청에 대한 결과를 보내주고 이벤트를 발생시켜 데이터를 수신합니다. 수신한 데이터중 필요한 항목에 해당하는 값을 구합니다. API에서는 잘 말해주지 않지만 OnReceiveTrData 함수에서 발생한 이벤트에 대해서 데이터를 수신할 때, CommGetData이나 GetCommData 함수를 통해서 데이터를 가져올 수 있습니다.

 

SetInputValue (사용자 호출) →  CommRqData (사용자 호출) → OnReceiveTrData (이벤트 발생) → CommGetData (데이터 수신)

 

연속 조회

TR별로 한 번에 전달할 수 있는 데이터 개수가 정해져 있습니다. 이 개수보다 조회할 데이터가 많을 때는 연속 조회로 모든 데이터를 조회할 수 있습니다. 연속 조회는 CommRqData()에서 인자 값만 바꿔서 다시 요청합니다.

 

CommRqData("일별데이터조회", "OPT10086" , 0, "0001");

위처럼 요청한 데이터가 한 번에 수신된 데이터보다 더 많이 있다면 OnReceiveTRData() 이벤트에서 5번째 인자 값(sPrevNext)에 "2"가 전달됩니다. 이때 더 많은 데이터를 요청하고자 할 때는 CommRqData("일별 데이터 조회", "OPT10086" , 2, "0001"); 위처럼 3번째 인자 값을 2로 설정해서 조회하시면 됩니다. 그리고 OnReceiveMsg 함수를 통해서 연속 데이터가 존재한다면 바로 확인할 수 있습니다. OnReceiveTrData 함수의 sPrevNext를 통해서 연속 조회 유무를 판단할 수 있습니다.

 

정리하면 다음과 같습니다.

 

OpenAPI.CommRqData("일별데이터조회", "OPT10086" , 0, "0001"); // 처음 조회 시 혹은 연속데이터가 없을 때
OpenAPI.CommRqData("일별데이터조회", "OPT10086" , 2, "0001"); // 연속 조회 시 (필요에 따라 요청)

 

※ 주의할 점: 중간에 다른 TR 요청이 있는 경우 연속 조회가 되지 않습니다.

 

KOA StudioSA에서 하나의 탭을 차지할 정도로 많은 TR이 있습니다. 사진에서도 확인하실 수 있지만 TR목록은 키움API에서 제공하는 수많은 TR요청을 정리해둔 것입니다. 

 

 

예를 들어서 주식일봉차트조회요청(opt10081)의 경우 아래와 같이 파이썬으로 활용할 수 있을 겁니다. 전체 코드 중에서 TR요청의 흐름만 정리해봤습니다. 이해하는데 도움이 되셨으면 좋겠습니다.

 

1. SetInputValue

# 전문 조회할 종목코드
self.SetInputValue("종목코드", sCode)
# 연도4자리, 월 2자리, 일 2자리 형식
self.SetInputValue("기준일자", yyyymmdd)
# 0 or 1, 수신데이터 1:유상증자, 2:무상증자, 4:배당락, 8:액면분할, 16:액면병합, 32:기업합병, 64:감자, 256:권리락
self.SetInputValue("수정주가구분", sGubun)

 

2. CommRqData

if self.remained_data:
	self.CommRqData("주식일봉차트조회요청", "opt10081", 2, SCREEN_NUM['주식일봉차트조회요청'])
    
else:
	self.CommRqData("주식일봉차트조회요청", "opt10081", 0, SCREEN_NUM['주식일봉차트조회요청'])

 

3. OnReceiveTrData

def _ReceiveTrData(self, sScrNo, sRQName, sTrCode, sRecordName, sPrevNext, nDataLength, sErrorCode, sMessage, sSplmMsg):
	try:
		if sPrevNext == '2' or sPrevNext == 2:
			self.remained_data = True
		else:
			self.remained_data = False

		if sRQName == "주식일봉차트조회요청":
			self._opt10081(sRQName, sTrCode)

	except AttributeError:
		self.logger.critical("조회|TR데이터 수신 함수에서 문제가 생겼습니다.")

	finally:
		self.tr_event_loop.exit()  # TR요청은 EventLoop 필수

 

4. CommGetData

def _opt10081(self, sRQName, sTrCode):
	if 'opt10081' not in self.output:
        self.output['opt10081'] = {}
        self.output['opt10081']['일자'] = []
        self.output['opt10081']['시가'] = []
        self.output['opt10081']['고가'] = []
        self.output['opt10081']['저가'] = []
        self.output['opt10081']['현재가'] = []
        self.output['opt10081']['거래량'] = []
        self.output['opt10081']['거래대금'] = []

	nRows = self.GetRepeatCnt(sTrCode, sRQName)

	for i in tqdm(range(nRows), leave=False):
        self.output['opt10081']['일자'].append(abs(int(self.CommGetData(sTrCode, "", sRQName, i, "일자"))))
        self.output['opt10081']['시가'].append(abs(int(self.CommGetData(sTrCode, "", sRQName, i, "시가"))))
        self.output['opt10081']['고가'].append(abs(int(self.CommGetData(sTrCode, "", sRQName, i, "고가"))))
        self.output['opt10081']['저가'].append(abs(int(self.CommGetData(sTrCode, "", sRQName, i, "저가"))))
        self.output['opt10081']['현재가'].append(abs(int(self.CommGetData(sTrCode, "", sRQName, i, "현재가"))))
        self.output['opt10081']['거래량'].append(abs(int(self.CommGetData(sTrCode, "", sRQName, i, "거래량"))))
        self.output['opt10081']['거래대금'].append(abs(int(self.CommGetData(sTrCode, "", sRQName, i, "거래대금"))))

 

 

다음 시간에는 이번 시간에 이어서 실시간 데이터 처리를 어떻게 하는지 한번 살펴볼 예정입니다. TR조회와 실시간은 조금 결이 다릅니다. 개인적으로 TR조회 연습을 많이 해보셔야 실시간을 활용하실 수 있을 거라고 생각됩니다.


 

키움증권 API와 관련된 자세한 내용을 확인하고 싶으신 분들은 PDF를 확인해보시면 좋을 것 같습니다.

 

마지막으로 같이 트레이딩 하는 분들과 소통하고 싶습니다. 언제든지 트레이딩이나 인공지능과 관련된 내용을 함께 공유하고 토론하고 싶으시다면 아래의 오픈 카카오톡 링크로 연락 주세요.
https://open.kakao.com/me/minsuksung

 

성민석님의 오픈프로필

안암에서 인공지능을 연구하고 있습니다

open.kakao.com

 

728x90
반응형