키움 증권 API를 이용하여 주식 자동 매매 프로그램 개발하기 - sqlite3 DB에 일봉 데이터를 저장하는 방법 [Python]
저번 시간에는 그랜빌의 매수 신호 제4법칙을 이용하여 포트폴리오를 구성하는 방법에 대해서 알아 보았습니다. 오늘은 sqlite3을 이용하여 DB에 일봉 데이터를 저장하는 방법을 설명하겠습니다.
SQLite3이란?
SQLite는 MySQL나 PostgreSQL와 같은 데이터베이스 관리 시스템이지만, 서버가 아니라 응용 프로그램에 넣어 사용하는 비교적 가벼운 데이터베이스입니다. 특히, 파이썬에서는 이 SQLite3가 자동으로 설치가 되어 있습니다.
따라서, 우리는 데이터 베이스의 구조를 보기 위해서 GUI 프로그램만 하나 설치하겠습니다. 이곳에서 자신의 OS 환경에 해당하는 인스톨러를 통해 DB 브라우저를 설치하시면 됩니다.
그리고 기본적인 문법은 이 포스팅에서 소개하지 않을 것이니, 이 포스팅에서 꼭 기초 문법을 익히고 오시길 바랍니다.
환경변수 설정
64비트의 파이썬 환경에서는 별도로 설정해 줄 것이 없지만, 우리는 32비트 파이썬 환경에서 개발 중이므로 환경변수 설정을 추가로 해야 SQLite3을 정상적으로 사용할 수 있습니다.
이 링크에 들어가셔서 아래 사진에서 빨간색 네모 박스 친 두 개의 파일을 다운로드해 줍니다.
그리고 이 두 개의 압축 파일을 해제하셔서 하나의 폴더에 옮기고, 이 폴더의 경로를 환경 변수의 사용자 변수든 시스템 변수든 하나를 선택해서 Path 안에 추가해야 합니다.
일봉 데이터를 SQLite3 DB에 저장
처음에 DB를 연결해 주고, 연결한 DB로부터 cursor(커서)를 받아 옵니다. 그리고 이 커서는 멤버 변수에 추가하였다고 가정하겠습니다.
우선, 인자에 있는 종목 코드와 GetMasterCodeName()을 이용하여 종목 이름을 얻어 냅니다. 그리고 이 이름이 곧 DB에 들어갈 테이블 이름이 될 것입니다. 이때, 이 문자열의 앞뒤를 큰 따옴표로 묶어주지 않으면 오류가 생깁니다. 단순히 알파벳이나 한글이면 오류가 나지 않는데, 숫자나 특수문자가 들어가면 OptionError가 발생하는 것을 확인하였습니다. 구글링을 하다 보니 자세한 이유는 모르겠으나, 문자열의 앞뒤를 큰 따옴표로 묶어주면 문제가 생기지 않는다고 하였습니다. 또한, 테이블에 들어갈 때 따옴표는 빠진 상태로 저장되는 것을 확인하였습니다. 가령, 테이블의 이름이 "이산전자"라면 DB에 저장된 테이블의 이름은 이산전자가 되는 것입니다.
그리고 그 아래 쿼리문인 "SELECT name FROM sqlite_master WHERE type='table'"은 DB에 있는 테이블의 목록을 뽑아내는 것입니다. 이를 이용하여 테이블에 동일한 종목 이름이 들어가지 않도록 하였습니다.
그 아래 쿼리문은 테이블을 생성하는 것인데, 쿼리문을 자세히 들여다 보면 중간에 중괄호가 있고, 마지막에 format() 함수를 사용하는 것을 보실 수 있습니다. 이것은 c언어치면 %d와 비슷한 기능으로 중괄호에 안에 들어갈 값을 format() 함수의 인자가 정해주는 것입니다.
마지막 쿼리문은 데이터를 삽입하는 것인데 마찬가지로 테이블의 이름을 정하기 위하여 format() 함수를 사용합니다. 그리고 물음표에 들어갈 자리도 format()과 비슷하게 인자로 튜플을 넘기면 됩니다. 여기서 테이블의 이름도 물음표를 사용하여 인자를 넘겨주면 안 되나 생각할 수 있는데, 구글링해 보니까 자세한 이유는 모르겠으나 허용하지 않는다는 답변이 있었습니다.
그리고 이 함수는 tr_slot()에서 주식일봉데이터조회요청 작업 부분의 else에 넣어주면 됩니다. sPrevNext의 값이 "0"이라서 연속 조회가 불가능할 경우 모든 데이터를 읽어들인 것이므로 DB에 저장하면 되는 것이죠. 나중에 전체 소스코드에서 확인해 보시면 됩니다.
SQLite3 DB에서 일봉 데이터 조회
똑같이 처음에는 모든 테이블의 이름을 가져오고, 그 안에서 전체 데이터를 조회하면 됩니다. 다만, 이때도 테이블의 이름을 큰 따옴표로 묶은 다음에 조회를 해야 오류가 발생하지 않습니다.
14번째 줄에는 reverse() 함수를 사용하였는데, 현재 DB에는 날짜를 기준으로 내림차순이 아니라 오름차순 정렬되어있는 상태이기때문에 이를 뒤집어 주어야 합니다.
그리고 마지막에 calculator() 함수를 사용하였는데, 저번 포스팅에서 사용한 것과는 다릅니다. 자세한 건 아래에서 다루겠습니다.
전체 소스코드
__init__()
__init__() 함수에는 코스닥 종목을 저장하는 딕셔너리가 추가되었고, DB를 연결하는 코드가 추가되었습니다. 마지막으로 코스닥 종목을 저장하거나 일봉 데이터를 저장하는 함수와 주석 처리된 그랜빌의 매수 법칙을 이용하는 함수를 분리하였습니다. 즉, DB에 저장 따로 DB에서 조회 따로 하는 것이죠.
get_stock_list_by_kosdaq()
인자가 isHavaDayData라는 것이 추가되었는데, 이것이 False면 일봉 데이터를 DB에 저장하는 작업을 합니다. 그리고 그 전에 코스닥 딕셔너리를 정의하는데, key는 종목의 이름, value는 종목의 코드가 되겠습니다. 또한, 굳이 코스닥 전체 종목 코드를 분리할 필요는 없어 보여서 기존의 있던 함수를 제거하였습니다.
그리고 day_kiwoom_db()의 날짜 인자로 '202101027'을 넘겼는데, 제가 이 코드를 작성할 당시 주식 장 중이었어서 전날까지의 데이터만 유효하기때문이었습니다. 이 인자는 자유롭게 설정하시면 됩니다.
calculator()
저번 시간에 사용하였던 그랜빌의 매수 신호 4법칙 코드와 같습니다. 다만 calculator_list는 멤버 변수가 아닌 인자에 있는 것을 이용한다는 점만 주의하시길 바랍니다.
DB 브라우저 사용
위와 같이 소스코드를 작성하고 실행하면 db 폴더 안에 day_stock.db라는 파일이 생깁니다. (사전에 미리 db라는 폴더를 만들어 두시길 바랍니다.) 그리고 DB 브라우저를 실행하여 이 파일을 열면 DB의 구조를 볼 수 있습니다.
자세한 데이터는 [데이터 보기]에서 확인할 수 있습니다.
정리
지금까지 DB를 구축하는 방법에 대해서 알아 보았습니다. 한 번 DB에 일봉 데이터를 저장만 해 둔다면 그 다음에는 업데이트를 하기도 쉽고 그랜빌의 매수 신호 제4법칙을 통해 유망한 종목을 뽑아내는 데도 오래 걸리지 않습니다. 다만, 초기 저장 작업은 굉장히 오래 걸리기때문에 인내심을 갖고 쭉 데이터를 받아오셔야 합니다.
다음 시간에는 DB 데이터를 업데이트하는 방법을 다뤄보겠습니다.
댓글