DATA 전문가로 가는 길

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

Programming/Python

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

EstenPark 2016. 4. 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





Comments