구글에 보면 구글 시트라고 웹에서 작성이 가능한 엑셀 시트가 있습니다.

웹에 연동된 엑셀 시트의 장점은 데이터를 실시간으로 받아올 수 있습니다.

 

이를 이용해서 주식 포트폴리오를 구성하면 상당히 편한데, 저는 미국주식을 예로 설명 드리고자합니다.

 

필요한건 구글 계정 정도입니다.

 

우선 제가 설정해 놓은 포트폴리오 입니다.

전 5개정도는 함수를 사용했고, 나머진 + / - 입니다.

 

먼저 구글에 로그인 해서 구글 시트에 접속을 하고 몇몇 부분에 필요한 함수를 정리해 보도록 하겠습니다.

 

https://docs.google.com/spreadsheets/u/0/

 

Google 스프레드시트 - 온라인에서 무료로 스프레드시트를 만들고 수정해 보세요.

Excel과 호환 Chrome 확장 프로그램 또는 앱을 사용하여 Microsoft Excel 파일을 열고 수정하고 저장할 수 있습니다. Excel 파일을 Google 스프레드시트로, Google 스프레드시트를 Excel 파일로 변환할 수 있습니다. 더 이상 파일 형식은 신경쓰지 마세요.

www.google.com

 

우선 관심 있으신 종목 티거(기호)를 찾아야 합니다. 

애플은 AAPL, 테슬라는 TSLA 같은 종목 코드가 있습니다.

한국 주식을 할때는, KRX:[코드번호] 로 입력해야 합니다.

 

가령 삼성전자 같은경우 코드 번호가005930 이므로 KRX:005930 으로 입력해야 합니다.

이제부터 B열을 종목 티거가 들어가 있다고 가정하고 작성합니다.

 

1. 현재 가격

=GOOGLEFINANCE(B7)

 

2. 전일대비상승율

=GOOGLEFINANCE(B7,"changepct")

 

3. 시가총액

=GOOGLEFINANCE(B7,"marketcap" )/100000000

 

4. 최근가격추이

k2에 몇개월간을 적어놓았습니다. (전 2년 = 24개월을 씁니다)

=SPARKLINE(GoogleFinance(B7, "price", today()-(30*$K$2), today()))

 

5. 현재 환율

=GOOGLEFINANCE(("CURRENCY:USDKRW"))

 

함수 도움말을 보면 배당도 얻어 올 수 있을거 같은데, 이건 잘 안되네요 ㅠㅠ

이 정도만 해도, 대략 최근 주가 흐름이나 포트폴리오 작성하는데 큰 도움이 될걸로 생각합니다.

 

추가로 제가 현재 보고 있는 종목 공유 합니다.

2020년 초반 시총 30위 + 배당 잘 주는 종목 + 관심 종목으로 되어 있습니다.

 

배당 / 배당월 / 배당금 정보는 "더 리치" 란 앱을 통해 일일히 입력했습니다.

아래 열만 적당히 수정해 주시면 됩니다.

 

현재가격 열 : =GOOGLEFINANCE(B7)
전일대비 상승율 : =GOOGLEFINANCE(B7,"changepct") 
시가총액 : =GOOGLEFINANCE(B7,"marketcap" )/100000000

 

 

'재테크 > 주식 투자' 카테고리의 다른 글

한국 주식을 그만 둔 이유  (0) 2020.07.12
ARK 에 대해서  (0) 2020.07.11
AMD에 투자한 이유에 대해서  (0) 2020.07.11
MS에 투자한 이유에 대해서  (0) 2020.07.11
테슬라에 투자한 이유에 대해서  (0) 2020.07.11

최근 테슬라 주식이 폭등이니, MS 시총이 1000조를 넘었다느니,

FAANG 주식은 승승장구니 뭐니 미국 주식에 대한 많은 이야기가 들립니다.  (대부분 글로벌을 상대하는 회사들)

 

실제로 미국 주식을 보면 확실한 우상향을 이루고 있습니다.

주식 책에 자주 보이는 장기 투자를 하게 되면 먹는 시장이니,

안목을 보고 좋은 주식을 골라야 하니, 이건 모두 미국 주식에 대한 이야기라고 볼 수 있겠죠. (왜냐면 우상향)

 

Tesla's stock recently skyrocketed, Microsoft's market cap exceeded 1,000 trillion,
FAANG stocks are a winning game, and there are many stories about US stocks. (Most global companies)

In fact, looking at U.S. stocks, there is a clear upside.
The long-term investments often seen in stock books are beneficial, so you have to look at your eyes and pick good stocks, so this is all about American stocks. (Because it's upward)

 

반면 한국 주식을 보면 박스권에 갇혀있다란 이야기를 많이 들으셨을 껍니다.

물론 우상향을 보이기는 하지만, 최근 10년을 보면 미국주식은 달려 나가는데, 한국 지수는 2000에서 벗어나지 못하고 있죠.

 

On the other hand, if you look at Korean stocks, you may have heard a lot about being trapped in a box.
Of course, it shows an upward trend, but in the last 10 years, US stocks are running out, but the Korean index has not escaped 2000.

그래서 최근에 한국 주식에 염증을 느끼고, 미국 주식으로 들어가는 사람들이 많아지고 있습니다.

정부도 그렇기 때문에 외화반출 이유를 들어서 이익금의 22%를 양도세율을 올렸습니다. (250만원까지는 공제)
전에는 양도세율이 10% 였을껍니다 ㅠㅠ..

So, recently, Korean stocks are inflamed, and more and more people are entering into US stocks.
The government is also doing so, raising the transfer tax rate of 22% of the profits for reasons of foreign currency export. (Deduction up to 2.5 million won)
Transfer tax rate would have been 10% before.

 

 

어쨋든 저도 처음엔 한국 주식을 좀 하다가 이게 잘 안되서

요즘 미국 주식을 보고 있습니다. 그리고 신중하게 일개 저같은 사람이 알 정도의 회사라면, 전세계적으로 장사를 하는거니 망하지 않고 장기투자시 어쨋든 오르는 주식이 아닐까 생각합니다.

(아마존, 구글, 애플, 페이스북, 넷플릭스, MS, 테슬라, 비자, 스타벅스, JP모건, AMD, NVIDA, 디즈니, 코스트코 등등)

 

Anyway, I did some Korean stock at first, but this didn't work
I'm looking at US stocks these days. And, carefully, if a company like me knows enough, I think that it is a stock that rises in the long-term investment without ruin because it is a business worldwide.
(Amazon, Google, Apple, Facebook, Netflix, Microsoft, Tesla, Visa, Starbucks, JP Morgan, AMD, NVIDA, Disney, Costco, etc.)

 

미국 주식은 종목수만 5000여개가 넘습니다. 이 많은 주식중에 어떤게 아직 발굴되지 않은 옥석인지 확인하는건 언어 장벽도 있고 어려움이 많죠. 

 

그래서 앱을 하나 만들었습니다.

나스닥 100에 등록된 대표 종목과, S&P500 의 500 개 종목에 대해서 머신러닝 예측을 써서 다음날 주식 가격 예측을 통해 추세를 판단 할 수 있는 앱입니다.

 

There are more than 5000 stocks in the United States. There are language barriers and difficulties in identifying which of these stocks is an unexplored boulder.

So I created an app.
It is an app that can determine the trend through the stock price prediction of the next day by writing machine learning forecasts for the 500 stocks of S & P 500 and the representative stocks registered in the NASDAQ 100.

 

https://play.google.com/store/apps/details?id=com.lucas.usstockcaster

 

루카스 미국 주요 주식 예측기 - Google Play 앱

미국 주식에 대해 막막한 투자를 도와드립니다. 미국 나스닥과 S&P500 에 편입된 우량주만을 선별하여, 1년치 데이터를 머신 러닝으로 학습 시켜서 다음날 주식 종가를 예측합니다. 투자에 많은 참고가 되시길 바랍니다. ---- 개발자 연락처 : Lucas Co. 금융 시스템 트레이딩 연구소 lucaslabs12@gmail.com

play.google.com

앱을 설치 하면 아래와 같은 리스트가 뜹니다.

1. Web trend

  이건 야후 파이넨셜에서 미국 사람들이 최근 많이 보는 Trend ticker 페이지의 목록을 불러 왔습니다.

 

When you install the app, the following list appears.
1. Web trend
   This brings up a list of Trend ticker pages that Americans see a lot recently.

 

목록을 클릭하면 그 주식의 예측가격이 나옵니다.

Click on the list to get the forecast price of the stock.

 

2. 추천 주식은 예측 값이 상승이고, ema 차트상 골든 크로스 된 주식의 목록을 출력합니다.

오늘은 퍼블릭 스토리지 이거 하나만 있군요.

 

2. Recommended stocks have a higher forecast value, and output a list of stocks with golden crosses on the ema chart.
Today there is only one public storage.

 

3. my stock 은 원하는 목록에 대해서 예측값을 볼 수 있습니다.

입력은 Ticker 라고 하는 코드명을 입력해 주셔야 합니다. APPLE = (AAPL)

 

3. my stock allows you to see the predictions for the desired list.
You must enter the code name Ticker. APPLE = (AAPL)

 

미국 주식 투자를 함에 있어서 여러 도움이 되었으면 합니다.

I hope this will help you in investing in US stocks.

3년전 알파고가 바둑계를 평정하고, 딥러닝이란 개념이 알려 졌을때,

왠지 컴퓨터가 바둑 말고 주식을 보게 하면 어떨까란 생각이 들었습니다.

 

실제로 알아 보니 이미 증권가에서는 많이 사용하고 있더군요.

물론 워낙 변수들이 많은 곳이다 보니 참고 자료 정도로만 쓰는 팀도 있고,

전적으로 맏기는 팀도 있는걸로 알고 있습니다.

 

그래서 저도 이것 저것 도전 하는김에 앱을 만들어 보았습니다.

 

우선 안드로이드 전용이고, 아래의 플레이 스토어로 설치 할 수 있습니다.

https://play.google.com/store/apps/details?id=com.lucas.krstockcaster

 

한국 주식 캐스터 - Google Play 앱

이 앱은 현재 상장된 한국의 각 주식들 1일봉 데이터를 1년치를 학습시켜, 다음날 주식의 종가를 예측 한 데이터를 보여줍니다. 신규 상장 주식에 대해서는 학습 데이터가 적어서 예측을 할 수 없는 단점이 있습니다. 또한 어디까지나 기술적 지표로 나온 데이터 이므로, 여타 기술 지표인 이평선, 볼린저 밴드, 스톡케스틱 과 같이 실제 뉴스 / 이슈에 따라 예측 오차가 발생합니다. 주식 투자 참고하는 하나의 지표로서 활용하시길 바랍니다. ---- 개발자 연락처

play.google.com

주식 장이 마감되면 그떄부터 크롤링 / 예측 / 데이터 취합 / 적용까지 시간이 있어서

보통 오후 8시쯤 되어야 다음날 예측치가 적용이 됩니다. (제 PC의 한계...)

 

앱을 실행하면 아래와 같이 3개의 리스트가 있습니다.

1. 현재 인기주

   네이버 검색상 그날 검색량이 많았던 주식 20개를 추려 리스트 업 합니다.

   Update는 예측한 날짜를 기록한 것이고, Predic 이 다음날 종가 예측치 입니다.

   아이콘은 종가 예측치를 따라,

  -10% 이하는 휴지, -10 ~ -3%는 비, -3~3%는 구름, 3~10%는 해, 10%이상은 로켓으로 표기 했습니다.

   해당 종목을 누르면 예측한 그래프가 표시 되고,

   간략하게 그 회사가 무슨 회사인지 표시 하였습니다.

   회사 설명을 클릭하면 그 회사의 홈페이지로 이동합니다.

   밑에 노란 아이콘 2개가 있는데, 왼쪽에 있는건 이 주식을 내 모니터닝으로 추가 / 삭제 하는 버튼이고

   오른쪽의 버튼은 네이버 증권으로 연결해서 네이버 증권 페이지가 열리며,

   여기서 더 자세한 정보를 얻거나, 증권 App 연결로 주문을 좀 더 쉽게 하도록 하였습니다.

 

2. 내일 추천주

   머신 러닝으로 예측치를 통계내서 다음날 15~10%이내의 상승을 보여 줄 거 같은 종목 15개를 로드 합니다.

3. 내 관심주

   모니터링 리스트로 최대 15개까지 저장 할 수 있습니다.

4. APP 정보는 말 그대로 그냥 정보고,

   아이콘 출처등을 표기 했습니다.

   대박을 기원하기 위해 로또번호 5천원어치를 출력 하게 했는데, 숫자 클릭할때마다 숫자들을 다시 랜덤하게 뽑아 줍니다.

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

위의 사진은 트레이딩 뷰(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)

 

+ Recent posts