본문 바로가기

Programming/Python Program

주식 정보 데이터베이스(db) 구축하기 by using python | storing stock data into database(DB) by using python

몇 년 전부터 db에 저장된 데이터를 이용해서 종목 발굴 알고리즘을 돌려놓고 있으며, 이를 이용해 특이점이 발견된 종목은 바로바로 문자 or email 등을 통해서 알려주고 관련 데이터를 저장하게 하는 시스템을 구축해 놓은 상황이다. 관련해서 문의 글이나 메일 혹은 문자를 통해 방법을 문의하는 글이 있어 개략적이나마 기본 개념을 작성해 두려고 한다.

우선 파이썬을 이용해서 주식 데이터를 데이터베이스(db)에 저장하는 작업을 하려고 한다. 이를 위해 기본 개념 몇몇을 알고 있어야 하지만, 관심이 있으신 분들은 관련 정보를 공부해 보시길 바란다. 가장 먼저 파이썬이라는 프로그램의 기본 개념을 익혀야 할 것이다. 그런 다음 관련 모듈을 설치, 기본 문법등을 차근차근 학습하면 될 것이다.

아래 코드는 완전한 코드가 아닌 일부분만을 짬을 내어 만들어 보았다. json, pandas, numpy, csv, socket, pymysql,mysql 등등의 모듈을 알아두면 도움이 될 것이다.

import json
import datetime
import pandas_datareader.data as web
import sys
import csv
import socket
import pymysql
import pandas as pd
import mysql.connector
from sqlalchemy import create_engine

# Crawling for C_DAYS
C_DAYS = 1200
end = datetime.datetime.now().date()
start = end - datetime.timedelta(days=C_DAYS)

passcode = True
while passcode:
    #print("1. KOSPI DATA ")
    #print("2. KOSDAQ DATA ")
    #selection=int(input("Which one do you want to download? : "))
    selection = str(1)
 
    if selection == str(1):
        stock_code = open('/Users/sh/Documents/_iPython/Stock_Data/KOSPI.csv','r')
        passcode = False
    elif selection == str(2):
        stock_code = open('/Users/sh/Documents/_iPython/Stock_Data/KOSDAQ.csv','r')
        passcode = False
    else:
        print("Wrong Number !! Try again !!!" )
csvReader = csv.reader(stock_code)


#jsonFile = '/Users/sh/Documents/_iPython/Stock_Data/test_run.json'
  
#Database 연결
conn = pymysql.connect(host='localhost', port=3306, user='root', passwd='pw', db='stock',charset='utf8',autocommit=False)
cur = conn.cursor()



for st in csvReader:
        
    StockCode = st[1]
    CompanyName = st[2]
    print(st[0],StockCode,CompanyNamem)
    try:
        if selection == str(1):
            stock_data = web.DataReader("%s.KS" %st[1],'yahoo',start,end)
        if selection == str(2):
            stock_data = web.DataReader("%s.KQ" %st[1],'yahoo',start,end)

        stock_data.loc[:,'Company'] = CompanyName
        stock_data.loc[:,'StockCode'] = StockCode
        stock_data.loc[:,'Date'] = stock_data.index.astype('str')
        json = open('/Users/sh/Documents/_iPython/Stock_Data/DAILY_STOCK_DATA.json','a')
        #StockData.append(stock_data)
        #json.dumps(stock_data, ensure_ascii=False, sort_keys=False, separators=(',', ':')).encode('utf-8')
        # force_ascii=False for korean
        json.write(stock_data.to_json(orient='records',force_ascii=False))
        json.close()
        engine = create_engine('mysql+mysqlconnector://root:pw@localhost:3306/YourDB_NAME', echo=False)
        stock_data.to_sql(name='stock_records', con=engine, if_exists = 'append', index=False)
        print(stock_data)


    except:
        pass

    
    
stock_code.close()
conn.commit()
conn.close()
print("Complete the task !! ")

개략적으로 작업스케쥴을 기록하자면, 한국 주식 시장은 코스피 종목, 코스닥 종목으로 구분할 수 있다. 물론 코넥스나 다른 여타 시장이 있지만, 여기서는 이 두 시장만을 다룬다.

1. 코드에서는 선택을 무력화해서 코스피 종목만 다루게 selection 을 1로 고정해 놓았다. KOSPI.csv 데이터는 한국 거래소를 방문하면 전체 혹은 코스피, 코스닥 시장에 상장되어 있는 상장회사목록을 다운 받으면 된다. 

번호,종목코드,기업명,업종코드,업종,상장주식수(주),자본금(원),액면가(원),통화구분,대표전화,주소,총카운트

1,095570,AJ네트웍스,126903,산업용 기계 및 장비 임대업,"46,822,295","46,822,295,000","1,000",원(KRW),02-6240-0800,"서울특별시 송파구 정의로8길 9 (문정동,AJ빌딩)",770

2,068400,AJ렌터카,126901,운송장비 임대업,"22,146,300","11,073,150,000","500",원(KRW),1544-1600,서울특별시 구로구  서부샛길 822 ,770

3,006840,AK홀딩스,137105,"회사본부, 지주회사 및 경영컨설팅 서비스업","13,247,561","66,237,805,000","5,000",원(KRW),02-6923-2921,서울특별시 구로구 구로중앙로 152(구로동) ,770

4,027410,BGF리테일,074701,종합 소매업,"49,547,625","49,547,625,000","1,000",,1577-3663,서울특별시 강남구 테헤란로 405 ,770

5,138930,BNK금융지주,116409,기타 금융업,"325,935,246","1,629,676,230,000","5,000",원(KRW),051-620-3022,부산광역시 남구 문현금융로 30(문현동) ,770

6,001460,BYC,031401,봉제의복 제조업,"624,615","4,200,000,000","5,000",원(KRW),02-840-3175,서울특별시 영등포구 도림천로21길 3 ,770

7,001040,CJ,137105,"회사본부, 지주회사 및 경영컨설팅 서비스업","29,176,998","157,914,810,000","5,000",원(KRW),02-726-8114,서울특별시 중구 소월로2길 12 (남대문로5가),770

8,079160,CJ CGV,105901,"영화, 비디오물, 방송프로그램 제작 및 배급업","21,161,313","10,580,656,500","500",원(KRW),02-371-6660,서울시 마포구 월드컵북로 434 10층(상암동) ,770

9,000120,CJ대한통운,084903,도로 화물 운송업,"22,812,344","114,061,720,000","5,000",원(KRW),02-3782-0114,서울특별시 중구  세종대로9길 53 ,770

10,011150,CJ씨푸드,031007,기타 식품 제조업,"35,930,773","18,065,386,500","500",원(KRW),031-730-9114,경기도 성남시 중원구  둔촌대로388번길 32 (상대원동),770

11,097950,CJ제일제당,031007,기타 식품 제조업,"13,164,998","72,462,155,000","5,000",원(KRW),726-8114,서울특별시 중구  동호로 330 ,770

12,037560,CJ헬로비전,106002,텔레비전 방송업,"77,446,865","193,617,162,500","2,500",원(KRW),02-1855-1000,"서울특별시 마포구 월드컵북로56길 19 6층(상암동, 드림타워) ",770

13,000590,CS홀딩스,137105,"회사본부, 지주회사 및 경영컨설팅 서비스업","1,154,482","5,772,410,000","5,000",원(KRW),02-3459-9363,경상북도 포항시 남구 괴동로 43 (장흥동),770

14,139130,DGB금융지주,116409,기타 금융업,"169,145,833","845,729,165,000","5,000",원(KRW),0537407900,대구광역시 북구 옥산로 111 대구은행 제2본점 9층,770

15,004840,DRB동일,137105,"회사본부, 지주회사 및 경영컨설팅 서비스업","19,000,000","9,500,000,000","500",원(KRW),051-520-9000,부산광역시 금정구 공단동로55번길 28 ,770

16,155660,DSR,031309,기타 섬유제품 제조업,"16,000,000","8,000,000,000","500",원(KRW),02-3420-3591,부산광역시 강서구 녹산산업중로192번길 7 ,770

다운 받은 csv 파일은 위와 같은 형태로 되어 있다. 여기에서 필요한 데이터는 종목코드와, 기업명 정도이다. 

이런 데이터를 읽어들여 csvReader에 저장을 해 둔다.

2. pymysql을 이용해서 python을 이용해서 db에 연결을 하려고 한다. 물론 이전에 db에 해당하는 프로그램이 설치 되어 있어야 한다. 본인은 mariadb 를 설치해 둔 상황이다.

mariadb를 설치하고자 한다면 다음 글을 참고하길 바란다.


install mariadb on ubuntu | mariadb 설치하기 on ubuntu


3. 1번에서 저장한 csvReader에서 종목코드 , 종목명의 데이터를 이용하기위해 반복문을 돌려서 StockCode, CompanyName 에 각각 할당한다. 그리고 KOSPI 종목이면  'Yahoo'에서 코스피에 해당하는 정보를 KOSDAQ이면 코스닥에 해당하는 데이터를 내려받게 한다.

4. json 형태로 파일을 저장한다. 물론 csv나 다른 형태로 관련 데이터를 저장할 수 있다. 그냥 2차 백업용으로 json 을 선택한 것 뿐이다.

5. json 으로 저장된 내용과 같은 데이터를  mariadb 에 저장을 한다. name='Stock_Records' 에서 Stock_Records는 db 이름이다. 이를 위해서 미리 db에 접속해서 생성해 주어야 한다. 그럴려면 DB,SQL 에 대해 조금 공부를 해야 할 것이다. if_exists = 'append'로 해 두었다. 이는 계속 누적으로 데이터를 쌓게한다. 만약 if_exists='replace'로 하면 이전에 존재하는 데이터를 삭제하고 다시 저장하게 한다. 

여기서 한 가지 문제가 발생하는데, append 로 해 두면 중복되는 데이터가 계속 쌓일 수 있다. 이를 위한 중복된 데이터를 삭제하는 방법이 있고, 애초에 중복된 데이터가 저장되지 않게 하는 방법이 있다. 혹은 중복 저장된 데이터에서 중복된 것만 제외하고 호출하는 방법등이 있다. 이는 추후에 기회가 되면 글을 써 보려고 한다.

이렇게 생성된 데이터는 아래 보이는 바와 같이 저장이 된다. 이를 불러들여 재생산, 재가공하면 제법 좋은 나만의 툴을 만들수 있을 것이다.


여기까지가 주식 종목 코드, 종목명을 가지고 yahoo finance에서 제공하는 API를 이용해서 파이썬으로 주식 데이터를 db에 저장하는 것 까지 알아보았다. 구글 파이낸스는 API가 아주~ 조금 상이하다. 위의 코드만 이해를 한다면 몇 글자만 수정해 주면 되니 크게 문제가 되지는 않으리라 본다.