본문 바로가기

주식투자

python 으로 키움증권 Open API 호출 - 주식분봉차트조회요청

여기에 나오는 코드들은 앞서 포스팅한 "python 으로 키움증권 Open API 호출 - 기본코드" 글에 작성된 기본코드에 함수를 추가하거나 기존에 있던 함수에 내용을 추가하는 방식으로 작성하였다.

 

 

python 으로 키움증권 Open API 호출 - 기본코드

키움증권 Open API 는 OCX 모듈로 되어있다. Python 프로그램에서 OCX 를 호출하기 위해서 PyQT5 패키지의 QAXWidget 을 이용하였다. PyQt5 는 아래 명령으로 설치할 수 있다. $ pip install PyQt5 PyQt 는 주로 G..

dkgkim.tistory.com

 

조회하고자 하는 데이터 있으면 KOA Studio 에서 TR목록을 조회해보아야 한다.

 

KOA Studio 메뉴

KOA Studio 의 TR목록 탭에서 주식분봉차트조회요청을 찾아보면 위와 같이 요청과 응답 필드들을 확인할 수 있다. 그리고 오른쪽 영역에는 아래와 같이 호출 방법에 대한 설명, 파라미터에 들어가야 할 값들을 설명해주고 있다. 아래 설명을 보면 틱 범위라는 값으로 몇 분 봉에 대한 데이터를 조회할지를 지정할 수 있다.

 

KOA Studio - 주식분봉차트조회요청 설명

 

다음 코드는 주식분봉차트조회요청(opt10080) 호출 코드이다.

 

def 주식분봉차트조회요청(self, code, tick_range):
    rq_name = "주식분봉차트조회요청"
    tr_code = "opt10080"
    self.tr_data[tr_code] = None
    
    self._set_input_value("종목코드", code)
    self._set_input_value("틱범위", tick_range)
    self._set_input_value("수정주가구분", "0")
    self._comm_rq_data(rq_name, tr_code, 0, "0101")
    self._start_event_loop()

    return self.tr_data[tr_code]

주식분봉차트조회요청(opt10080) 호출 코드

 

_comm_rq_data 함수를 호출한 후 _start_event_loop 함수를 호출하여 응답이 올 때까지 event loop를 통해 멈춰있도록 한다. 그렇지 않으면 응답이 오기 전에 함수를 return 하게 되고, 응답에 대한 내용은 비동기로 처리해야 된다. event loop를 통해 대기하고 있다가 나중에 응답을 받고 데이터를 세팅한 다음 event loop에서 나오게 해 주면 된다.

 

다음 코드는 주식분봉차트조회요청(opt10080)에 대한 응답 처리 부분이다.

 

def _receive_tr_data(self, screen_no, rq_name, tr_code, record_name, prev_next, data_len, err_code, msg1, msg2):
    if rq_name == "주식분봉차트조회요청":
        repeat_cnt = self._get_repeat_count(tr_code, rq_name)
        data = []
        index = []
        for i in range(repeat_cnt):
            index.append(self._get_comm_data(tr_code, rq_name, i, "체결시간").strip()[:12])
            data.append({
                '시가': abs(int(self._get_comm_data(tr_code, rq_name, i, "시가").strip())),
                '고가': abs(int(self._get_comm_data(tr_code, rq_name, i, "고가").strip())),
                '저가': abs(int(self._get_comm_data(tr_code, rq_name, i, "저가").strip())),
                '종가': abs(int(self._get_comm_data(tr_code, rq_name, i, "현재가").strip())),
                '거래량': abs(int(self._get_comm_data(tr_code, rq_name, i, "거래량").strip()))
            })
        self.tr_data[tr_code] = DataFrame(data, columns=['시가', '고가', '저가', '종가', '거래량'],
                                          index=index).sort_index()
        self._exit_event_loop()

주식분봉차트조회요청(opt10080)에 대한 응답 처리 부분

 

GetReapeatCnt를 호출하여 응답 데이터의 건수를 받아온 후 응답 건수만큼 loop를 돌면서 _get_comm_data 함수를 이용하여 필요한 데이터를 가져온다. 필요한 모든 데이터를 가져와 변수에 저장하고나면 _exit_event_loop 를 호출해 준다. 이 함수는 앞에서 요청함수에서 event loop 를 통해 대기하고 있던 부분에서 빠져나오게 해준다.

 

위 코드에서 결과에 abs 함수를 통해 절댓값으로 변경해주는 부분이 있다. abs 함수 없이 결과를 받게 되면 아래와 같다.

 

                 시가     고가     저가     종가     거래량
202203031335  72800  72800  72700  72700   44676
202203031340  72700  72800  72700  72800   49072
202203031345  72700  72800  72600  72700  216757
202203031350  72700  72700  72600  72700   34045
202203031355  72700  72800  72600  72700  175469
...             ...    ...    ...    ...     ...
202203041500 -71500 -71700 -71500 -71600  154346
202203041505 -71700 -71700 -71600 -71600   83933
202203041510 -71700 -71700 -71600 -71700   92795
202203041515 -71700 -71700 -71600 -71600  259101
202203041530 -71500 -71500 -71500 -71500  936337

[100 rows x 5 columns]

abs 함수를 사용하지 않았을 경우 결과

 

이렇게 분봉 데이터 조회 시 - 부호가 같이 조회된다. 뭔가 전 분봉 대비 상승/하락이라던지 이전 현재가와 다음 현재가 간의 차이에 대한 결과라던지 뭔가 의미가 있을까 싶어서 주가를 비교해봐도 도저히 모르겠다.

 

혹시나 해서 키움증권 Open API+ 게시판에서 찾아보면 분봉데이터 조회 시 +부호는 전분봉 대비 상승, -부호는 전분봉대비 하락을 의미한다고 한다. 

 

하지만 이 답변을 읽고 나서 분봉 주가 데이터를 살펴봐도 도저히 모르겠다. 그래서 그냥 abs 함수를 써서 부호는 무시하고 실제 숫자 값만 사용하려고 한다.

 

def 주식분봉차트조회요청(self, code, tick_range):
    rq_name = "주식분봉차트조회요청"
    tr_code = "opt10080"
    self.tr_data[tr_code] = None
    while self.tr_data[tr_code] is None:
        self._set_input_value("종목코드", code)
        self._set_input_value("틱범위", tick_range)
        self._set_input_value("수정주가구분", "0")
        status = self._comm_rq_data(rq_name, tr_code, 0, "0101")
        if status != 0:
            self.sleep(5)
        else:
            self._start_event_loop()
    ma12 = self.tr_data[tr_code]['종가'].ewm(span=12).mean()
    self.tr_data[tr_code].insert(len(self.tr_data[tr_code].columns), 'ma12', ma12.round(1))
    ma26 = self.tr_data[tr_code]['종가'].ewm(span=26).mean()
    self.tr_data[tr_code].insert(len(self.tr_data[tr_code].columns), 'ma26', ma26.round(1))
    macd = ma12 - ma26
    self.tr_data[tr_code].insert(len(self.tr_data[tr_code].columns), 'MACD', macd.round(1))
    macd_signal = self.tr_data[tr_code]['MACD'].ewm(span=9).mean()
    self.tr_data[tr_code].insert(len(self.tr_data[tr_code].columns), 'MACD_SIGNAL', macd_signal.round(1))
    return self.tr_data[tr_code]

주식분봉차트조회요청 함수

 

앞서 분봉 차트조회를 요청하는 함수를 조금 더 손봐서 12일 지수 이평, 26일 지수 이평을 계산해주고, MACD와 MACD_SIGNAL까지 계산해주었다. 그리고 _comm_rq_data 함수 호출 결과가 0 이 아닌 경우 5초 뒤 다시 요청하도록 처리해주었다.

 

조회된 분봉 차트 데이터 및 MACD, 거래량 데이터를 그래프로 그려보았다.

삼성전자(005930) 2022년 3월 4일 5분봉 차트

 

같은 날 삼성전자의 5분 봉 차트를 키움 영웅문(HTS)에서 조회해보면 아래와 같다.

 

영웅문 5분봉 차트

 

그래프를 그리는 부분은 자동매매에 필요는 없지만 조회한 데이터와 계산한 지표 데이터가 올바른 값인지를 확인할 때 그려보면 쉽게 확인할 수 있다.