주식의 차트들을 보면, 기본 정보인 분봉이외에 여러 값들이 있습니다.

위의 사진은 트레이딩 뷰(https://kr.tradingview.com/chart/m9TGPsC1/) 라는 차트 전문 사이트에서 갖고 온 차트입니다.

캔들로 이루어진 분봉 이외에 선으로 그어져 있는데, 각각 MA (Move Average) 5, 20 즉 평균 이평선 5, 20일선 입니다.

 

그런데 전에 크롤링 해온 데이터는 기본값 (시간, 시가, 고가, 저가, 종가, 거래량) 뿐이고, 그 이외의 지표들은 각각 계산해야 합니다.

 

계산식이야 하기와 같은 공식 설명 및 엑셀 구현 을 찾아보면서, 파이썬으로 수식을 옮겨도 되지만

여기서 버그가 나기라도 하면 (물론 식을 완성하고 검증해서 엑셀 출력 결과물과 맞는지 확인 해야겠죠!)

문제가 많고...
https://school.stockcharts.com/doku.php?id=technical_indicators:moving_averages

 

Moving Averages - Simple and Exponential [ChartSchool]

Moving Averages - Simple and Exponential Introduction Moving averages smooth the price data to form a trend following indicator. They do not predict price direction, but rather define the current direction, though they lag due to being based on past prices

school.stockcharts.com

 

무엇보다 이런 바퀴 만드는 작업을 다른 사람들이라고 똑같이 안했을리가 없습니다.

그래서 누군가 이런 라이브러리 만들어서 공개해놓은게 있는데, 그것이 TA-Lib(Technical Analysis Library) 입니다.

아래에서 여러 공식을 뽑아내는 함수를 확인 할 수 있습니다.

https://ta-lib.org/function.html

 

Function List

 

ta-lib.org

파이썬으로 와핑한 라이브러리가 있는데 아래에서 확인 할 수 있습니다.

https://github.com/mrjbq7/ta-lib

 

mrjbq7/ta-lib

Python wrapper for TA-Lib (http://ta-lib.org/). Contribute to mrjbq7/ta-lib development by creating an account on GitHub.

github.com

이제 이 talib를 사용해서 주식 데이터를 관리할 클래스를 만들어 보겠습니다.

calcIndicator 함수를 주목해 주세요

 

<StockData.py>

# pip install ta-lib
#
# OR 실패시 라이브러리 다운받아서 직접 해보기
# pip install .\TA_Lib-0.4.17-cp37-cp37m-win_amd64.whl
#
# OR
# 아나콘다를 사용해서 인스톨 방법
# conda install -c quantopian ta-lib 
# conda install -c masdeseiscaracteres ta-lib
# conda install -c developer ta-lib 

from enum import Enum
import os

import talib
import talib.abstract as ta
from talib import MA_Type
import dataframe

import pandas as pd 
import numpy as np

class BuyState (Enum):
    없음 = 0
    매수 = 1
    
class stockData:
    buyCount_ = 0
    buyPrice_ = 0
    position_ = BuyState.없음

    def __init__(self, code, name, dataFrame):
        self.code_ = code
        self.name_ = name
        self.indicators_ = dataFrame

    # 지금 캔들(갱신될 수 있음)
    def candle0(self):
        rowCnt = self.indicators_.shape[0]
        if rowCnt == 0:
            return None
        return self.indicators_.iloc[-1]

    # 완전히 완성된 캔들 (고정된 가장 최신 캔들)
    def candle1(self):
        rowCnt = self.indicators_.shape[0]
        if rowCnt < 1:
            return None
        return self.indicators_.iloc[-2]

    # 완성된 캔들의 직전 캔들 (지표간 cross 등 판단을 위함.)
    def candle2(self):
        rowCnt = self.indicators_.shape[0]
        if rowCnt < 2:
            return None
        return self.indicators_.iloc[-3]

    def calcProfit(self):
        if self.buyCount_ == 0:
            return 0
     
        profit = self.buyCount_ * self.buyPrice_
        return profit    

    # 각종 보조지표, 기술지표 계산
    def calcIndicator(self):        
        arrClose = np.asarray(self.indicators_["close"], dtype='f8')
        arrHigh = np.asarray(self.indicators_["high"], dtype='f8')
        arrLow = np.asarray(self.indicators_["low"], dtype='f8')
     
        # 이평선 계산
        self.indicators_["sma5"] = ta._ta_lib.SMA(arrClose, 5)
        self.indicators_["sma10"] = ta._ta_lib.SMA(arrClose, 10)
        self.indicators_["sma20"] = ta._ta_lib.SMA(arrClose, 20)
        self.indicators_["sma50"] = ta._ta_lib.SMA(arrClose, 50)
        self.indicators_["sma100"] = ta._ta_lib.SMA(arrClose, 100)
        self.indicators_["sma200"] = ta._ta_lib.SMA(arrClose, 200)

        self.indicators_["ema5"] = ta._ta_lib.EMA(arrClose, 5)
        self.indicators_["ema10"] = ta._ta_lib.EMA(arrClose, 10)
        self.indicators_["ema20"] = ta._ta_lib.EMA(arrClose, 20)
        self.indicators_["ema50"] = ta._ta_lib.EMA(arrClose, 50)
        self.indicators_["ema100"] = ta._ta_lib.EMA(arrClose, 100)
        self.indicators_["ema200"] = ta._ta_lib.EMA(arrClose, 200)

        self.indicators_["wma5"] = ta._ta_lib.WMA(arrClose, 5)
        self.indicators_["wma10"] = ta._ta_lib.WMA(arrClose, 10)
        self.indicators_["wma20"] = ta._ta_lib.WMA(arrClose, 20)
        self.indicators_["wma50"] = ta._ta_lib.WMA(arrClose, 50)
        self.indicators_["wma100"] = ta._ta_lib.WMA(arrClose, 100)
        self.indicators_["wma200"] = ta._ta_lib.WMA(arrClose, 200)
  
        #볼린저 계산
        upper, middle, low = ta._ta_lib.BBANDS(arrClose, 20, 2, 2, matype=MA_Type.SMA)
        self.indicators_["bbandUp"] = upper
        self.indicators_["bbandMid"] = middle
        self.indicators_["bbandLow"] = low

        # 기타 자주 사용되는 것들
        self.indicators_["rsi"] = ta._ta_lib.RSI(arrClose, 14)
        self.indicators_["cci"] = ta._ta_lib.CCI(arrHigh, arrLow, arrClose, 14)
        self.indicators_["williumR"] = ta._ta_lib.WILLR(arrHigh, arrLow, arrClose, 14)
        self.indicators_["parabol"] = ta._ta_lib.VAR(arrClose, 5, 1)
        self.indicators_["adx"]  = ta._ta_lib.ADX(arrHigh, arrLow, arrClose, 14)
        self.indicators_["plusDI"]  = ta._ta_lib.PLUS_DI(arrHigh, arrLow, arrClose, 14)
        self.indicators_["plusDM"]  = ta._ta_lib.PLUS_DM(arrHigh, arrLow, 14)
       
        self.indicators_["atr"] = ta._ta_lib.ATR(arrHigh, arrLow, arrClose, 30)
        

이제 제대로 계산되는지 확인해 봅시다.

<main.py>

### 먼저 설치할것들
# python -m pip install --upgrade pip
# conda update -n base conda 
# conda update --all 
# pip install pandas
# pip install pandas-datareader
# pip install dataframe

import pandas as pd 
import dataframe
import sqlite3
import datetime
import WebStockDataGetter
import SqliteStockDB
import StockData
import MachineLearningPredic
import StockPredic

# 메인 함수 시작
if __name__ == '__main__':   
    # 네이버 데이터 크롤러
    getter = WebStockDataGetter.naverGetter()    
    stockDf = getter.getKoreaStocksFromFile()

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

    stockPool = {}

    # 주식의 일자데이터 크롤링 / db 에서 갖고 오기
    for idxi, rowCode in stockDf.iterrows():
        code = rowCode['code']
        name = rowCode['name']      

        maxGetPage = 3
        # DB에 데이터가 없으면 테이블을 만듬
        tableName = dayPriceDB.tableName(code)
        if dayPriceDB.checkTable(tableName) == False:
            if dayPriceDB.createTable(tableName) == False:
                continue
            else:
                maxGetPage = 100

        # 크롤러에게 code 넘기고 넷 데이터 긁어오기
        df = getter.crawlingNaverStockInfo(code, maxGetPage)
        if df is None:
            print("! 주식 [%s] 의 크롤링 실패" % (name))
            continue

        data = pd.DataFrame(df, columns=['날짜', '시가', '고가', '저가', '종가', '거래량'])
                                
        # 데이터 저장
        dayPriceDB.save(tableName, data)
        print("====== 주식 일봉 데이터 [%s] 저장 완료 (%d/%d) =====" % (name, idxi, totalCount))
        
        # db에 저장 시킨 값을 다시 갖고오지 (검증!)
        df = dayPriceDB.load(tableName)
        if df is None:
           continue

		# stockData 만들어서 pool에 담기
        sd = StockData.stockData(code, name, df)
        stockPool[name] = sd
        
        # 기술지표 계산
        sd.calcIndicator()
        print("--- [%s]" % sd.name_)
        print(sd.indicators_)
    
    # 주식데이터 각각을 백테스팅
    for name, sd in stockPool.items():      
        candle = sd.candle0()
        print( "# 주식 [%s]의 [%s] 종가 [%d]"  % (name, candle['candleTime'], candle['close']))
        
        # 여러 전략들을 조합해서 구매에 적합한 전략을 찾기

    # 괜찮은 매매 타이밍 sort 해서 텔레그램으로 전송

print(sd.indicators_) 를 통해 아래와 같이 이평선, rsi, cci 등 여러 보조 지표들이 한번에 계산되는걸 확인 할 수 있습니다.

추가로 그 이외의 소스 파일들도 소소하게 변경 되었으니 아래의 크롤러와 db 쪽 소스 파일도 바꿔 줍니다.

 

<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_:
            try:
                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)
                return True
            except:
                log = "! [%s] table make fail" % tableName 
                print(log)
                return False
    
    # 데이터 저장
    def save(self, tableName, dataframe):    
        with self.conn_:
            try:
                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()
            except:
                return None
            
    # 데이터 로드
    def load(self, tableName):
        with self.conn_:
            try:                
                sql = "SELECT candleTime, start, high, low, close, vol FROM \'%s\' ORDER BY candleTime ASC" % tableName
                df = pd.read_sql(sql, self.conn_, index_col=None)
                return df
            except:
                return None

 

<WebStockDataGetter.py>

import pandas as pd 
from pandas import Series, DataFrame
import numpy as np
import dataframe
import sqlite3
import datetime
from datetime import datetime

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

    def getKoreaStocksFromFile(self):
        with open("./targetList.txt", "r", encoding="utf-8") as f:
            targetList = f.read().splitlines()
        
        stockDf = DataFrame(columns = ("name", "code"))
        for text in targetList:
            tokens = text.split(':')
            row = DataFrame(data=[tokens], columns=["name", "code"])
            stockDf = stockDf.append(row)
            stockDf = stockDf.reset_index(drop=True)
        return stockDf

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

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

    def crawlingNaverStockInfo(self, code, maxGetPage):
        # 일자 데이터를 담을 df라는 DataFrame 정의
        df = pd.DataFrame()
        try:            
            url = self.__getNaverURLCode(code)
            # 1페이지가 10일. 100페이지 = 1000일 데이터만 가져오기 
            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()
            #print(df)
            return df
        except:
            return None

 

위에 보면 getKoreaStocksFromFile 함수에 하드코딩으로 targetList.txt 파일을 불러오고 있습니다.

이 리스트는 [종목명]:[종목코드] 로 구성되어 있고 저는 아래와 같은 주식 / ETF / ETN 에 대해서만 할 예정입니다.

<targetList.txt>

삼성전자:005930
SK하이닉스:000660
네이버:035420
카카오:035720
현대차:005380
호텔신라:008770
삼성SDI:006400
LG화학:051910
KODEX 코스닥150 레버리지:233740
KODEX 200선물인버스2X:252670
KODEX 레버리지:122630
KODEX 코스닥150선물인버스:251340
KODEX 인버스:114800
KODEX 코스닥 150:229200
KODEX 200:069500
TIGER 200선물인버스2X:252710
TIGER 200:102110
TIGER 코스닥150 레버리지:233160 
신한 레버리지 천연가스 선물 ETN(H):500031
신한 인버스 2X WTI원유 선물 ETN(H):500027
삼성 레버리지 천연가스 선물 ETN:530037
삼성 KTOP30 ETN:530013
삼성 인버스 2X WTI원유 선물 ETN:530036
신한 인버스 2X 다우존스지수 선물 ETN(H):500028
신한 레버리지 은 선물 ETN(H):500029

앞서 데이터를 가지고 오는 소스를 보시면, 

한국 주식시장에 상장된 전 종목에 대한 데이터를 갖고 오게 됩니다.

그런데 이 데이터를 웹브라우저를 사용해서 갖고오기 때문에 (이를 크롤러라고 합니다)

1종목의 100여 페이지 (1페이지당 10개 x 100 => 1000 일봉 (HTS 등에선 한번에 900봉씩 가지고 옵니다))
의 데이터 갖고오는데 1,2 분정도 걸립니다.

 

한국 주식 종목의 수가 약 2300개쯤 되는데 1종목에 1,2분이면

60분 * 24시간 = 1440분 / 2 = 720개 ~ 1000개 종목을 갖고오게 됩니다.

 

물론 이걸 주말이든 해서 다 가져와도 상관없지만...

필요없는 데이터는 추리고 의미 있는 (거래량 많은 변동성 좋은) 종목으로 하는것이 시스템 매매에 좋습니다.

 

그래서 여기서는 몇몇 대중적인 (주관적으로) 주식 데이터를 긁어볼려고 합니다.

 

물론 다 text 파일에 종목을 긁어 놓을꺼니까, text 파일만 수정하면 원하시는 종목을 더 갖고오게 됩니다.

아래와 같은 targetList.txt 파일을 만들어 줍니다.

 

아래와 같이 main.py에 targetList를 읽어 주고,

크롤링 하기전에 targetList에 있는 종목인지 확인하는 코드를 넣어 줍니다.

# 필요한 모듈 설치
# pip install pandas
# pip install pandas-datareader
# pip install dataframe

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()

    # 타켓 종목만 고르기
    f = open("./targetList.txt", "r", encoding="utf-8")
    targetList = f.read().splitlines()
    f.close()

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

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

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

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

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

 

  1. 꿀보의 비트코인 2020.04.02 18:14

    관리자의 승인을 기다리고 있는 댓글입니다

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

키움증권의 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 로 열어보면 네이터 주식 게시판에서 긁어온 데이터가 제대로 저장되어 있다면 성공입니다.

 

시스템 트레이딩을 위해서 필요한걸 적어 봤습니다.

주 목표는 ETF / ETN 종목등 몇몇 종목에 대한 그래프 그려보고 어떤식으로 만들지 고민해보도록 하겠습니다.

 

- 파이썬을 돌릴 visual code https://code.visualstudio.com/

 

Visual Studio Code - Code Editing. Redefined

Visual Studio Code is a code editor redefined and optimized for building and debugging modern web and cloud applications.  Visual Studio Code is free and available on your favorite platform - Linux, macOS, and Windows.

code.visualstudio.com

- 파이썬 설치 관련 / 메뉴얼 https://docs.python.org/ko/3/tutorial/index.html

 

파이썬 자습서 — Python 3.8.1rc1 문서

파이썬 자습서 파이썬은 배우기 쉽고, 강력한 프로그래밍 언어입니다. 효율적인 자료 구조들과 객체 지향 프로그래밍에 대해 간단하고도 효과적인 접근법을 제공합니다. 우아한 문법과 동적 타이핑(typing)은, 인터프리터 적인 특징들과 더불어, 대부분 플랫폼과 다양한 문제 영역에서 스크립트 작성과 빠른 응용 프로그램 개발에 이상적인 환경을 제공합니다. 파이썬 인터프리터와 풍부한 표준 라이브러리는 소스나 바이너리 형태로 파이썬 웹 사이트, https://www.

docs.python.org

<이 아래는 매매까지 자동으로 하고 싶을 경우>

- 키움증권 계좌  (휴대폰 비대면 계좌 개설) 및 OpenAPI 사용 등록

https://www2.kiwoom.com/nkw.templateFrameSet.do?m=m1408010100

 

키움증권-대한민국 주식시장 점유율 1위

 

www2.kiwoom.com

- C# 프로그램 설치를 위한 Visual Studio https://visualstudio.microsoft.com/

 

Visual Studio IDE, Code Editor, Azure DevOps, & App Center - Visual Studio

Visual Studio dev tools & services make app development easy for any platform & language. Try our Mac & Windows code editor, IDE, or Azure DevOps for free.

visualstudio.microsoft.com

- sqlite db 값을 볼 브라우져 https://sqlitebrowser.org/

 

DB Browser for SQLite

DB Browser for SQLite The Official home of the DB Browser for SQLite Screenshot What it is DB Browser for SQLite (DB4S) is a high quality, visual, open source tool to create, design, and edit database files compatible with SQLite. DB4S is for users and dev

sqlitebrowser.org

 

이 몇년간 개인적 사정으로 블로그를 방치 했었지만, 

이제 다시 몇개 글좀 올리고자 합니다.

 

게임 서버 프로그래머로서 나름 족적을 남기고자 노력하고 자기 개발도 해봤지만,

회사에 묶인 개인으로선 역시 한계가 있네요.

게임 회사라는 한계도 있고요.

 

당연한 이야기지만, 결국 회사원으로서는 재산 증식에 어려움이 많네요.

게임 회사에 입사한 것도 열심히 일하다가 성공하면 어느정도 인센이 나오니까, 게임을 좋아 하니까 였는데

10년 넘게하다보니, 열심히 해도 소용없다는 벽이 느껴지네요. 번인은 물론이거니와

인센도 먹을 사람들은 정해져 있고, 보이지 않는 학연, 지연, 흡연... 

 

그래서, 다른 뭔가 자신의 분야를 활용하는 재테크 분야를 찾다 보니

시스템 트레이딩 분야가 눈에 들어 왔습니다.

 

잘 될지 안될지는 모르겠으나, 이것 저것 시도 해보고 결과를 공유 하고자 합니다.

부디 경제적 자유를 얻는 그날까지...

 

 

+ Recent posts