[키움API]파이썬 주식 종가정보 불러오기1: 종목코드 목록 입수
종목리스트 입수 함수 확인
이제 아래 그림 1의 "기간별 종가 데이터 입수" 버튼 기능을 만들어보자.(버튼 이름의 뜻이 명확하지 않아서 바꿨다.)
주식 종목의 기간별 종가 데이터 입수 작업은 "주식코드의 입수 및 목록화 -> 기준일자의 주식코드별 종가 데이터 수집 -> 일자를 바꿔가면서 종가 데이터 반복 수집-> DB저장"으로 나눌 수 있다. 먼저 주식코드의 입수 및 목록화부터 진행해 보자. 키움 API 개발 가이드를 보면 아래 그림 2와 같이 GetCodeListByMarket이라는 함수를 써서 주식코드 목록을 받을 수 있다는 것을 확인할 수 있다.
여기에서 함수에 패러미터로 "0"을 넣으면 장내, "3"을 넣으면 ELW, "4"를 넣으면 뮤추얼펀드 등이 나오는 방식이다.
코스피 종목 리스트 불러오기
아래 코드와 같이 "btn_dataget"이라는 버튼에 btn_datagetFunc 라는 함수를 연결해 주고, btn_datagetFunc 안에서 키움 API로 종목정보 목록을 요청하는 GetCodeListByMarket이라는 구조로 코드를 짜면 된다.
import sys
from PyQt5.QtWidgets import *
from PyQt5.QAxContainer import *
from PyQt5 import uic
#UI파일 연결
form_class = uic.loadUiType("UI 파일의 경로 입력")[0]
# PyQt5의 QMainWindow 클래스와 UI 폼 클래스를 상속받은 사용자 지정 클래스 정의
class KiwoomAPIform(QMainWindow, form_class):
def __init__(self):
# 부모 클래스의 초기화 메서드 호출
super().__init__()
# UI 폼을 현재 창에 설정
self.setupUi(self)
# 창의 제목 설정
self.setWindowTitle("KiwoomTest")
# 키움 API Active X 호출
self.ocx = QAxWidget("KHOPENAPI.KHOpenAPICtrl.1")
# 로그인 버튼 클릭 시 작동 함수 정의(UI 생성시 오브젝트 명이 "btn_login"이어야 함)
self.btn_login.clicked.connect(self.btn_loginFunc)
# 데이터 입수 클릭 시 작동 함수 정의(UI 생성시 오브젝트 명이 "btn_dataget"이어야 함)
self.btn_dataget.clicked.connect(self.btn_datagetFunc)
...(생략)...
# btn_datagetFunc 함수
def btn_datagetFunc(self):
# 아래 GetCodeListByMarket 함수를 호출해서 API로 종목정보 받아옴(패러미터로 "0")
data = self.GetCodeListByMarket("0")
# 입수된 데이터가 있으면 상태창에 Success!!, 아니면 Failed 반환
if data is not None and len(data) > 0:
self.drawresult("Success!!")
else:
self.drawresult("Failed")
print(data)
# drawresult 함수
def drawresult(self, data: object):
# 화면에서 "txt_result"라는 오브젝트를 찾은 뒤 txt_result로 객체화
txt_result = self.findChild(QTextEdit, "txt_result")
# txt_result에 data를 받아서 data를 set 함
txt_result.setPlainText(str(data))
...(생략)...
# GetCodeListByMarket 함수
def GetCodeListByMarket(self, mkcode: str):
# 키움 API로 종목 정보 입수
return self.ocx.dynamicCall("GetCodeListByMarket(Qstring)", mkcode)
if __name__ == "__main__":
# PyQt5 어플리케이션 생성
app = QApplication(sys.argv)
# KiwoomAPIform 클래스의 인스턴스 생성
window = KiwoomAPIform()
# 창을 화면에 표시
window.show()
# 어플리케이션 실행 및 이벤트 루프 시작
sys.exit(app.exec_())
위 코드를 실행할 때 주의할 점은 반드시 화면상 로그인 버튼을 통해서 로그인을 한 이후에 데이터를 입수해야 한다는 점이다.( [키움API]python API로그인(Qt Designer 사용) 참조)
입수된 종목 리스트 가공
코드를 실행하면 아래 그림 3과 같은 데이터가 print 된다. API 함수를 통해서 종목정보를 받아오면 종목코드를 ";"로 구분해서 하나의 통문자열로 데이터를 뿌려주는 것이다. 이런 데이터로는 n 번째 종목코드를 뽑아낼 수도 없고, 조작도 힘들어서 입수된 데이터를 적어도 List 형식으로는 바꿔주는 작업이 필요하다.
기본적인 방법은 종목코드가 세미콜론(;)을 기준으로 나눠져 있기 때문에 split(";") 함수를 써서 세미콜론(;)을 기준으로 list를 만드는 것이다. 주의할 점은 데이터 마지막이 "900140;" 로(세미콜론으로 끝남) 끝나므로 세미콜론을 기준으로 list를 만들 경우 리스트에 빈 항목이 하나 생기기 때문에 "데이터의 마지막이 공란(if data[-1] == "") 이면 데이터를 마지막 직전항까지로 재정의(data[:-1]) 아니면 그대로 data 갖다 쓰는 조건문"을 추가해 준다. 완성된 코드는 아래와 같다.
import sys
from PyQt5.QtWidgets import *
from PyQt5.QAxContainer import *
from PyQt5 import uic
#UI파일 연결
form_class = uic.loadUiType("UI 파일의 경로 입력")[0]
# PyQt5의 QMainWindow 클래스와 UI 폼 클래스를 상속받은 사용자 지정 클래스 정의
class KiwoomAPIform(QMainWindow, form_class):
def __init__(self):
# 부모 클래스의 초기화 메서드 호출
super().__init__()
# UI 폼을 현재 창에 설정
self.setupUi(self)
# 창의 제목 설정
self.setWindowTitle("KiwoomTest")
# 키움 API Active X 호출
self.ocx = QAxWidget("KHOPENAPI.KHOpenAPICtrl.1")
# 로그인 버튼 클릭 시 작동 함수 정의(UI 생성시 오브젝트 명이 "btn_login"이어야 함)
self.btn_login.clicked.connect(self.btn_loginFunc)
# 데이터 입수 클릭 시 작동 함수 정의(UI 생성시 오브젝트 명이 "btn_dataget"이어야 함)
self.btn_dataget.clicked.connect(self.btn_datagetFunc)
...(생략)...
# btn_datagetFunc 함수
def btn_datagetFunc(self):
# 아래 GetCodeListByMarket 함수를 호출해서 API로 종목정보 받아옴(패러미터로 "0")
data = self.GetCodeListByMarket("0")
# 세미콜론을 기준으로 데이터를 List 형식으로 변경
data = data.split(";")
# 마지막항이 비어있으면 직전항까지만 List로 사용하도록 data 를 재정의
data = data[:-1] if data[-1] == "" else data
# 입수된 데이터가 있으면 상태창에 Success!!, 아니면 Failed 반환
if data is not None and len(data) > 0:
self.drawresult("Success!!")
else:
self.drawresult("Failed")
print(data)
# drawresult 함수
def drawresult(self, data: object):
# 화면에서 "txt_result"라는 오브젝트를 찾은 뒤 txt_result로 객체화
txt_result = self.findChild(QTextEdit, "txt_result")
# txt_result에 data를 받아서 data를 set 함
txt_result.setPlainText(str(data))
...(생략)...
# GetCodeListByMarket 함수
def GetCodeListByMarket(self, mkcode: str):
# 키움 API로 종목 정보 입수
return self.ocx.dynamicCall("GetCodeListByMarket(Qstring)", mkcode)
if __name__ == "__main__":
# PyQt5 어플리케이션 생성
app = QApplication(sys.argv)
# KiwoomAPIform 클래스의 인스턴스 생성
window = KiwoomAPIform()
# 창을 화면에 표시
window.show()
# 어플리케이션 실행 및 이벤트 루프 시작
sys.exit(app.exec_())
최종적으로 아래와 같이 결과가 출력되면 정상이다.