키움증권에서는 OpenAPI를 제공하고 있습니다.
개인 투자자들은 별도의 비용 없이 키움증권 계좌가 있으면 API 사용 신청을 할 수 있습니다.
전 종목 일봉데이터를 다운로드 요청하는 코드를 포스팅합니다.
1. 키움 종목코드 개수
2월 기준으로 3천 종목이 조금 넘습니다. (2/7, 3065종목)
TR5회당 20초로 시간 간격을 설정하면 3시간 30분 소요됩니다.
# 3065종목 시작 16:44 종료 20:08 소요 03:24 (204분)
2. 사용 TR함수
OPT100081 을 사용합니다.
1회 요청시 종목의 900일치 시가/고가/저가/종가/거래량을 받아옵니다.
3. 전 종목을 대상으로 특정일에 해당하는 가격정보를 받는 방법은 없는지?
없습니다.
추후 업데이트도 고려하고 있지 않는다는 답변을 받았습니다.
이 부분에 대해서는 pykrx를 이용하여 특정일의 시세데이터를 받을 수 있으나,
pykrx가 제공하는 종목수는 2천 종목으로 키움과 1:1 매칭이 안됩니다..
종목 개수가 1:1로 매칭이 안되는 것은
아마도 리츠 등 특수한 종목을 pykrx에서 제공하지 않기 때문인 것으로 생각합니다.
4. 코드
전 종목은 요청하는 메소드.
사전에 self.kw에 comm_rq_data 가 정의되어 있어야 합니다.
def get_all_daily_price(self):
""" 전 종목에 대해서 일봉 데이터 요청 및 DB저장 (3시간 정도 소요) """
file = "./CodeList.db"
if os.path.isfile(file):
con = sqlite3.connect(file)
df_codes = pd.read_sql("SELECT * FROM CodeList", con, index_col='index')
con.close()
else:
self.msgbox.setText("종목코드 생성 필요")
self.msgbox.exec_()
return
for code in df_codes.index:
ohlcv = None
input_dict = {}
input_dict['종목코드'] = code
input_dict['틱범위'] = 1
input_dict['수정주가구분'] = 1
self.kw.set_input_value(input_dict)
self.kw.comm_rq_data("opt10081_req", "opt10081", 0, "0101")
# OPT 10081 = 주식 일봉 차트 요청
ohlcv = self.kw.latest_tr_data
recieve_counter = 0
while self.kw.is_tr_data_remained == True:
recieve_counter += 1
if recieve_counter < 1:
self.kw.set_input_value(input_dict)
self.kw.comm_rq_data("opt10081_req", "opt10081", 2, "0101")
for key, val in self.kw.latest_tr_data.items():
ohlcv[key][-1:] = val
else:
break
df2 = pd.DataFrame(ohlcv, columns=['open', 'high', 'low', 'close', 'volume'], index=ohlcv['date'])
con2 = sqlite3.connect("./DailyPrice.db")
df2.to_sql(code, con2, if_exists='append')
아래는 self.kw 인스턴트에 선언되어 있는 comm_rq_data 메소드입니다.
def comm_rq_data(self, rqname, trcode, next, screen_no):
"""
서버에 조회 요청을 하는 메소드
이 메소드 호출 이전에 set_input_value 메소드를 수차례 호출하여 INPUT을 설정해야 함
"""
self.is_tr_running = 1
self.dynamicCall("CommRqData(QString, QString, int, QString)", rqname, trcode, next, screen_no)
self.tr_event_loop = QEventLoop()
self.tr_event_loop.exec_()
# 키움 Open API는 시간당 request 제한이 있기 때문에 딜레이를 줌
if self.TR_REQ_COUNTER == 1:
self.TR_LAST_TIME = datetime.datetime.now()
# 1초에 5번 RQ시 17초 대기
timenow = datetime.datetime.now()
timegap = timenow - self.TR_LAST_TIME
timegap = timegap.seconds
timerest = int(17 - timegap)
if (self.TR_REQ_COUNTER % 5) == 0:
print("{}| TRcnt {} % 5 == 0, Long sleep".format(timenow, self.TR_REQ_COUNTER))
time.sleep(18)
self.is_tr_running = 0
else:
print("{}| TRcnt {} % 5 != 0, Short sleep".format(timenow, self.TR_REQ_COUNTER))
time.sleep(self.TR_REQ_TIME_INTERVAL_SHORT)
self.is_tr_running = 0
self.TR_REQ_COUNTER += 1
5. 보완점
키움에서 종목코드 다운을 하면 3천종목이 나오는데,
솔직히 전체 종목을 분석할 일은 많지 않습니다.
시가총액 기준으로 분석할 종목을 끊어서 리스트형태로 코드를 담아둔 다음에,
리스트를 for로 돌려서 사전에 특정한 코드들 대상으로 일봉을 요청한다면,
소요되는 시간이 더욱 줄어들 것입니다.
3천 종목에 3시간이니,
1천5백 종목이면 1시간30분이면 되지 않을까 생각합니다.

'컴퓨터, IT > 프로그래밍' 카테고리의 다른 글
[파이썬] 멀티쓰레드 오류없이 종료하기 (QThread + GUI) (2) | 2021.07.04 |
---|---|
(안드로이드 앱 출시) 구글 앱 개발자 계정등록 (25$) (0) | 2021.07.03 |
(파이썬) Pandas DataReader로 야후 스크랩핑 에러해결 (DataFrame 열이름 변경) (0) | 2021.07.01 |
[파이썬] PyQt5 창 닫힐 때 이벤트 실행하기 (0) | 2021.06.24 |
(파이썬) 키움 API "에러코드표" 및 "장운영구분 FID215" 딕셔너리 선언문 (0) | 2021.06.20 |