지난달 30일, 가족문제로 대만에 갔다 왔습니다.

잘 방역 하는 대만이지만, 공항은 다른 외국 사람들이 왔다갔다 하는곳이라 방심 할 수 없었지만...

생각보단 사람들이 많이 없었습니다.

 

혹시 모르니, 잠복기 2주동안은 가능하면 집에 있으라고 하더군요.

회사일이야 재택근무를 하면 되는데, 역시 집안에서는 너무 심심했습니다.

 

그래서 준비한 레고... 는 너무 비싸서 짝퉁 레고 부카티 시론을 조립 하였습니다.

저는 킹핀이라는 곳을 보내 주셨는데, 블록 양이 역시나 많습니다. 3500~4000개쯤 한다고 하네요.

이걸 자세히 보면 봉투에 숫자가 써있습니다.

설명서에는 1파트, 2파트, 3파트 ... 총 13파트 까지 있습니다.

봉투의 숫자는 그 파트에 사용되는 블럭들 이므로 각 숫자별로 묶어 놓아야 합니다.

 

첫날 1,2 파트까지 조립하는데 보통 3시간 정도 소요 됩니다.

이거 거의 회사까지 출퇴근 시간을 쏟는다라고 생각하면 딱 그 시간이네요

 

제 경우엔 재택근무 끝나고 저녁 먹는데, 그 이후 하루에 2파트씩 진행했습니다.

1파트가 변속기, 2파트가 차량 운전휠쪽

3파트가 엔진파트 등 파트를 조립하다 보면 차량 내부에 대해 대략적으로 가늠할 수 있습니다.

중국산 블릭이라 가끔 제대로 안깍인 블럭들이 있습니다.

낄때 제대로 안깍인 날카로운 부분이 손가락을 찌를때가 많습니다.

여기까지가 지금 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

이제는 작년이 된 12월 말, 나 자신에게 주는 크리스마스 선물을 마련하고 싶었습니다.

그리고 아이도 가지고놀 선물도 필요 했고요.

 

그렇게 알리 익스프레스 보던 중, 레고 테크닉에 페라리가 있더군요.

 

원래는 유명한 레고 부가티를 조립 하고 싶었으나...

경제적 여유가 없고, 양도 많다고 하길래 그것보다 부품이 좀 적은 페라리를 주문 했습니다 (1359 pcs 라 적혀 있네요.)

쿠팡 https://coupa.ng/blJllS 에서도 보니 비슷한 가격에 팔고 있네요.

 

그리고 도착하고 몇일이 지난 토요일 조립을 시작했습니다.

일단 알리에서 주문한거 답게 박스는 없고 블록 주머니만 왔습니다. 
누락된 부품이 있을꺼 같은 기분도 들고... 레고는 조립 단계별로 블록이 나눠 포장된다고 한다던데, 이녀석은 종류별로 포장되어 있습니다.

 

 

처음에는 봉지 하나 뜯고 하나씩 조립하다가

 

결국 블록을 다 쏟고 하나 하나 조립 하게 됩니다.
원래 1주일잡고 천천히 만들려고 헀는데, 이렇게 블록이 쏟아지고 정리가 안되는 이상 다 조립을 해야 합니다. 

이거 그냥 둔다면 블록 몇개 잃어버리고 미완성품이 되겠죠.

 

하체 조립 완성환 시점입니다.

엔진 블록을 설치한 시점입니다. 이때 뭔가 있어보이기 시작 합니다.

 

저기 의자 조립하는 부분이 있는데, 아무리 봐도 부품이 없는데신 튜브가 좀 긴 느낌이었습니다.

아무래도 직접 잘라서 넣어야 하는거 같습니다만... 무시하고 끼어 넣었습니다.

 

 

조립하고 조립해도 끝나지 않는 이 느낌... 바퀴를 붙이고 

외관을 하나 하나 조립한 이 시간은 새벽 3시...

 

완성된 사진입니다.

저 남은 부품들이 있는데... 분명 중간에 집중력을 잃고 몇군대 빼먹은거 같습니다.

 

허나 그런거 치고는 완성도 높은 모습

시저 도어도 잘 되고 

뒤에 엔진블록도 제대로 동작 합니다.

의자 부분이 조금 불만족이지만, 그래도 장식용도나 나중에 아이 장난감으로 주기엔 안성 맞춤입니다.

 

그리고 오늘 유튜브에서 본 영상..

이게 레고에서 발매된적이 있는 모델이었군요.

실제 레고는 아니지만 그래도 만족감 높은 조립이었습니다.

https://www.youtube.com/watch?v=q0a0tvVuRVM

 

[해외] 테크닉 Enzo Ferrari (1359pcs) 레고호환블록

+ Recent posts