우선 주식을 컴퓨터에게 분석 하기 위해서는 데이터가 필요하죠.

키움증권의 OpenAPI등을 사용해서 데이터를 실시간으로 가져 올 수 있으나,

그건 실제 매매 전략등을 구현해서 성공한다는 확신이 들때 해도 됩니다.

 

시스템 자동매매 만드는 방법은 아래와 같은 순서로 만드는게 보편적입니다.

  1. 주식 데이터 모으기 (tick 데이터 자체도 매매 됩니다. 해외 선물 같은 경우 거래소당 월 180달러 내야 합니다.)
  2. 주식 데이터를 기술 분석 하기 (이동평균선, 볼린저 벤드, RSI 등...)
  3. 기술 데이터를 기반으로 매매 규칙 세우기
  4. 벡테스팅 하기.
       즉 1의 주식 데이터를 기반으로 3에서 새운 매매 규칙을 적용해서 실제 이익나는 전략인지 검증
        (사실 여기서 다들 좌절 합니다....ㅠㅠ)
  5. 실제 모의 투자 계좌에서 위의 통과된 매매법을 적용하기 (최소 1개월 ~ 3개월)
  6. 실제 계좌에 돈을 넣고 보기...

 

상기의 주제들은 구글이나 네이버 등에서도 검색하면 나오는 소스들이 많습니다

여기서는 제 나름대로 주석을 붙여가서 해석을 하는거니, 참고 바랍니다.

 

우선 1번 데이터 모으기 부터 해봅시다.

 

main.py

import pandas as pd 
import dataframe
import sqlite3
import datetime
import WebStockDataGetter
import SqliteStockDB

# 메인 함수 시작
if __name__ == '__main__':
    # 설정파일. 웹페이지의 1페이지당 10일치 데이터가 있는데, 몇개 웹페이지를 긁을지 설정
    f = open("./config.txt", 'r')
    if f.readable == False:
        print("! have not config file.")
        exit
     
    maxGetPage = f.readline().strip()
    f.close()

    # 네이버 데이터 크롤러
    getter = WebStockDataGetter.naverGetter()
    stockDf = getter.getKoreaStocks()

    # Sqlite에 데이터 저장
    dayPriceDB = SqliteStockDB.dayPriceDB()
    conn = dayPriceDB.connectDB('KoreaStockData.db')
    totalCount = len(stockDf)

    with conn:
        # 주식의 일자데이터 url 가져오기 
        for idxi, rowCode in stockDf.iterrows():
            code = rowCode['code']
            name = rowCode['name']      

            # DB에 데이터가 없으면 테이블을 만듬
            tableName = dayPriceDB.tableName(code)
            if dayPriceDB.checkTable(conn, tableName) == False:
                dayPriceDB.createTable(conn, tableName)

            # 크롤러에게 code 넘기고 넷 데이터 긁어오기
            df = getter.getAllStockDays(code, maxGetPage)
            data = pd.DataFrame(df, columns=['날짜', '시가', '고가', '저가', '종가', '거래량'])
                                    
            # 데이터 저장
            dayPriceDB.save(conn, tableName, data)
            log = "====== 주식 일봉 데이터 [%s] 저장 완료 (%d/%d) =====" % (name, idxi, totalCount)
            print(log)

        conn.close()

 

SqliteStockDB.py

import pandas as pd 
import dataframe
import sqlite3
import datetime

class dayPriceDB:
    # DB 폴더가 준비 되어 있어여함.	
    def __init__(self, dbName):
        self.conn_ = sqlite3.connect('./DB/' + dbName)

    def tableName(self, code):
        name = "DayPriceTable_" + code
        return name
    
    # 테이블 이름이 있는지 확인
    def checkTable(self, tableName):
        with self.conn_:
            cur = self.conn_.cursor()
            sql = "SELECT count(*) FROM sqlite_master WHERE Name = \'%s\'" % tableName
            cur.execute(sql)
            rows = cur.fetchall()
            for row in rows:          
                if str(row[0]) == "1":
                    return True
            return False
    
    # 테이블 생성
    def createTable(self, tableName):
        with self.conn_:
            cur = self.conn_.cursor()
            sql = "CREATE TABLE %s (candleTime DATETIME PRIMARY KEY, start INT, high INT, low INT, close INT, vol INT);" % tableName
            cur.execute(sql)
    
    # 데이터 저장
    def save(self, tableName, dataframe):    
        with self.conn_:
            cur = self.conn_.cursor()
            sql = "INSERT OR REPLACE INTO \'%s\'" % tableName
            sql = sql + " ('candleTime', 'start', 'high', 'low', 'close', 'vol') VALUES(?, ?, ?, ?, ?, ?)"
            cur.executemany(sql, dataframe.values)    
            self.conn_.commit()

 

WebStockDataGetter.py

import pandas as pd 
import dataframe
import sqlite3
import datetime

class naverGetter:
    def getKoreaStocks(self):
        # 한국 주식 회사 등록 정보 가지고 오기
        stocksDataFrame = pd.read_html('http://kind.krx.co.kr/corpgeneral/corpList.do?method=download&searchType=13', header=0)[0]
        stocksDataFrame.종목코드 = stocksDataFrame.종목코드.map('{:06d}'.format)
        stocksDataFrame = stocksDataFrame[['회사명', '종목코드']] 
        stocksDataFrame = stocksDataFrame.rename(columns={'회사명': 'name', '종목코드': 'code'})
        return stocksDataFrame

    def __getURLCode(self, code):    
        url = 'http://finance.naver.com/item/sise_day.nhn?code={code}'.format(code=code)
        print("요청 URL = {}".format(url))
        return url

    # 종목 이름을 입력하면 종목에 해당하는 코드를 불러와 
    def getStockURL(self, item_name, stocksDataFrame):
        code = stocksDataFrame.query("name=='{}'".format(item_name))['code'].to_string(index=False)
        url = self.__getURLCode(code)
        return url

    def getAllStockDays(self, code, maxGetPage):
        # 일자 데이터를 담을 df라는 DataFrame 정의
        df = pd.DataFrame()

        url = self.__getURLCode(code)
        # 1페이지가 10일. 60페이지 = 600일 데이터만 가져오기 
        for page in range(1, int(maxGetPage)):
            pageURL = '{url}&page={page}'.format(url=url, page=page)
            df = df.append(pd.read_html(pageURL, header=0)[0], ignore_index=True)
        
        # df.dropna()를 이용해 결측값 있는 행 제거 
        df = df.dropna()
        return df

 

이걸로 DB 폴더안에 'KoreaStockData.db' 파일이 생성될거고요.

DB Browser for SQLite 로 열어보면 네이터 주식 게시판에서 긁어온 데이터가 제대로 저장되어 있다면 성공입니다.

 

+ Recent posts