전문가로가는길

[Python] 주식 일별 시세(과거 데이터) 적재(JSON, pandas_datareader) 본문

Programming/Python

[Python] 주식 일별 시세(과거 데이터) 적재(JSON, pandas_datareader)

EstenPark 2016.04.20 16:45

이번에는 한국 거래소 종목 데이터를 기준으로 종목별 과거 데이터(일별 시세)를 가져오는 방법을 만들어 보도록 하겠습니다. 우선 가장 먼저 필요한 항목은 한국 거래소에서 제공하는 주식 현황 데이터를 다운 받아서 적절한 위치에 업로드 해야 합니다. 코스피에 속한 종목만 포함 되어있습니다.


그리고  JSON Table Type를 활용하기 위해서는 디렉토리에 퍼미션 변경하고 파일을 다른 소유주도 사용할 수 있도록 권한을 변경 합니다.


Pandas Data Reader 사용 가이드 : 바로가기


1. JSON Format File 생성 및 권한 변경(퍼미션)

# MariaDB estdb 데이터베이스가 설치된 디렉토리에 outer 권한을 부여 합니다.
# *중요* 실제로 MariaDB를 운영하는 회사에서는 아래와 같이 데이터베이스 디렉토리를 절대로 변경해서는 안됩니다. 
[root@localhost estdb]# chmod 715 /var/lib/mysql/estdb

# MariaDB estdb 데이터베이스가 설치 된 디렉토리에서 Yahoo Stocks Daily Data를 일시적으로 저장할 파일 권한을 부여합니다.
# 아래와 같이 권한을 부여하는 이유는 MariaDB에서 JSON Type Table을 SELECT 할 때 퍼미션 문제로 로딩 되지 않아서 입니다.
[root@localhost estdb]# pwd
/var/lib/mysql/estdb
[root@localhost estdb]# touch stock_data.json
[root@localhost estdb]# chown python.python stock_data.json
[root@localhost estdb]# chmod 755 stock_data.json

2. 전체 종목 대상 과거 데이터 가져오는 방법

#-*- coding: utf-8 -*-
import pandas_datareader.data as web
import datetime
import csv
import socket
import pymysql
import sys
 
# 현재 데이터 일자 지정 
end   = datetime.datetime.now() 
# 과거 데이터 일자 지정
start = '1970-01-01'            


IpAddr = socket.gethostbyname(socket.gethostname())
jsonFile = '/home/python/stock_data.json'
 
#Database 연결
conn = pymysql.connect(host=IpAddr, port=3306, user='root', passwd='maria', db='estdb',charset='utf8',autocommit=True)
cur = conn.cursor()
 
#종목 코드 데이터 불러오기
 
stock_code = open('/home/python/source/stocks/krx_issues_master.csv', 'r')
csvReader = csv.reader(stock_code)
 
 
#주식 데이터 호출 및 데이터베이스 INSERT
for st in csvReader:
     print(st[0],st[1],st[2], datetime.datetime.now())
     EventCode = st[1]
     CompanyNm = st[2]
 
     #yahoo
 
     try: 
        stock_data = web.DataReader("%s.KS" %st[1],'yahoo',start,end)
        stock_data.loc[:,'Company'] = CompanyNm     #회사명
        stock_data.loc[:,'StockCode'] = EventCode   #종목코드
        stock_data.loc[:,'date'] = stock_data.index.astype('str') #날짜데이터
        stock_data.to_json(orient='records')
        # 데이터베이스를 생성한 디렉토리에 JSON 유형 주식 데이터를 저장 
        json = open('/var/lib/mysql/estdb/stock_data.json', 'w')
        json.write(stock_data.to_json(orient='records'))
        json.close()
 
        cur.execute("drop   table if exists est_stocks_yahoo_daily;")
        cur.execute("create table est_stocks_yahoo_daily  (Open decimal(9,2),   High decimal(9,2),   Low decimal(9,2),   Close decimal(9,2),   Volume decimal(9,2),  AdjClose decimal(9,2), Company varchar(100), StockCode varchar(100), date varchar(100)) engine=connect,table_type=json,file_name='/var/lib/mysql/estdb/stock_data.json';")
        cur.execute("insert into est_stocks_daily select * from est_stocks_yahoo_daily;")
 
     #에러 발생시 예외처리
     except :
         pass
 
stock_code.close()
 
cur.close()
 
print('데이터 통합 작업 완료')


3. 프로그램 실행
[python@localhost stocks]$ python stocks_issues_daily.py 


4. 과거 데이터 결과 확인
/* 주식 일별 시세 데이터 확인 */
MariaDB [estdb]> select count(*) from est_stocks_daily;
+----------+
| count(*) |
+----------+
|  2501684 |
+----------+
1 row in set (6.16 sec)

/* 주식 종목별 데이터 확인 */
MariaDB [estdb]> select StockCode, count(*) from est_stocks_daily group by StockCode;
| 161000    |     4095 |
| 161390    |      922 |
...생략....
| 225440    |      120 |
| 226320    |       82 |
| 227840    |      127 |
| 900050    |     1774 |
| 900140    |     1392 |
+-----------+----------+
766 rows in set (6.35 sec)


/* 삼성전자(005039) 주식 일별 시세 데이터 확인 
     - AdjClose(수정주가)는 Yahoo Stock에서 "Adj Close"와 같이 띄워쓰기를 해서 주기 때문에 JSON를 가져오지 못하고 있습니다.(추후 개선 할 예정)
     - Company 컬럼은 현재 기본 캐릭터 셋을 제대로 설정하지 않아서 들어갈 때 깨지는 것입니다.
*/
MariaDB [estdb]> select a.* from est_stocks_daily a where a.StockCode='005930' order by a.date desc limit 1, 10;
+------------+------------+------------+------------+-----------+----------+-----------------------------+-----------+------------+
| Open       | High       | Low        | Close      | Volume    | AdjClose | Company                     | StockCode | date       |
+------------+------------+------------+------------+-----------+----------+-----------------------------+-----------+------------+
| 1295000.00 | 1305000.00 | 1292000.00 | 1299000.00 | 128400.00 |     NULL | 삼성전자                | 005930    | 2016-04-18 |
| 1309000.00 | 1310000.00 | 1290000.00 | 1300000.00 | 136500.00 |     NULL | 삼성전자                | 005930    | 2016-04-15 |
| 1300000.00 | 1302000.00 | 1289000.00 | 1300000.00 | 335300.00 |     NULL | 삼성전자                | 005930    | 2016-04-14 |
| 1275000.00 | 1275000.00 | 1275000.00 | 1275000.00 |      NULL |     NULL | 삼성전자                | 005930    | 2016-04-13 |
| 1270000.00 | 1281000.00 | 1266000.00 | 1275000.00 | 134000.00 |     NULL | 삼성전자                | 005930    | 2016-04-12 |
| 1246000.00 | 1271000.00 | 1246000.00 | 1266000.00 | 120600.00 |     NULL | 삼성전자                | 005930    | 2016-04-11 |
| 1269000.00 | 1269000.00 | 1240000.00 | 1246000.00 | 251800.00 |     NULL | 삼성전자                | 005930    | 2016-04-08 |
| 1300000.00 | 1300000.00 | 1258000.00 | 1269000.00 | 258700.00 |     NULL | 삼성전자                | 005930    | 2016-04-07 |
| 1269000.00 | 1291000.00 | 1268000.00 | 1285000.00 | 184200.00 |     NULL | 삼성전자                | 005930    | 2016-04-06 |
| 1299000.00 | 1299000.00 | 1260000.00 | 1260000.00 | 236000.00 |     NULL | 삼성전자                | 005930    | 2016-04-05 |
+------------+------------+------------+------------+-----------+----------+-----------------------------+-----------+------------+


5. 한국 거래소 종목 현황 데이터 파일

krx_issues_master.csv





4 Comments
  • 프로필사진 김민철 2016.11.04 10:07 신고 진심 짱이시네요.
    Python 관련 글이 많이 없어 아쉽습니다.
    좋은 정보 감사합니다.
  • 프로필사진 Favicon of http://estenpark.tistory.com EstenPark 2016.11.07 10:03 신고 네. 좋은 정보라니 다행입니다. 나중에 포스팅 하게 되면 다양한 댓글 남겨주세요.
  • 프로필사진 이승섭 2016.12.11 17:36 신고 # MariaDB estdb 데이터베이스가 설치된 디렉토리에 outer 권한을 부여 합니다.
    # *중요* 실제로 MariaDB를 운영하는 회사에서는 아래와 같이 데이터베이스 디렉토리를 절대로 변경해서는 안됩니다.
    [root@localhost estdb]# chmod 715 /var/lib/mysql/estdb

    제가 무지하여,, 선생님의 글을 실행하려다가 outer권한이 무엇을 뜻하는건지, 그리고 outer권한으로 설정을 chmod 715 /var/lib/mysql/estdb로 바꿀려해도 되지 않았습니다. 경로가 없다고 나타나는데 estdb같은 경우는 사용자가 직접 만들어 주고 실행하여야 하나요?
  • 프로필사진 Favicon of http://estenpark.tistory.com EstenPark 2016.12.12 10:02 신고 /var/lib/mysql/estdb 디렉토리 경로는 Mysql이나 MariaDB에서 만드신 데이터베이스에 따라 경로가 다릅니다. 저는 데이터베이스를 estdb로 만들었기 때문에 해당 경로에 존재하는 것 입니다.
    [ Mysql/MariaDB 데이터베이스 경로 확인 ]
    mysql> show variables like 'datadir';
댓글쓰기 폼