주가 일주일 예측(6주차)

 전에 크롤링한 데이터를 가지고 2020-09-14일까지의 데이터를 가지고 2020-09-21의 주가를 예측하여 값이 어느정도 차이가 있는지를 비교해 보았다.

1
2
3
4
5
6
7
8
9
import requests
from bs4 import BeautifulSoup
import traceback
import pandas as pd
import datetime
import plotly.express as px
import matplotlib.pyplot as plt
%matplotlib inline
from fbprophet import Prophet
cs

위의 라이브러리를 사용하여 진행하였다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
code = '005930'
 
url = 'http://finance.naver.com/item/sise_day.nhn?code={code}'.format(code=code)
res = requests.get(url)
res.encoding = 'utf-8'
 
soap = BeautifulSoup(res.text, 'lxml')
 
el_table_navi = soap.find("table", class_="Nnavi")
el_td_last = el_table_navi.find("td", class_="pgRR")
pg_last = el_td_last.a.get('href').rsplit('&')[1]
pg_last = pg_last.split('=')[1]
pg_last = int(pg_last)
 
def parse_page(code, page):
    try:
        url = 'http://finance.naver.com/item/sise_day.nhn?code={code}&page={page}'.format(code=code, page=page)
        res = requests.get(url)
        _soap = BeautifulSoup(res.text, 'lxml')
        _df = pd.read_html(str(_soap.find("table")), header=0)[0]
        _df = _df.dropna()
        return _df
    except Exception as e:
        traceback.print_exc()
    return None
cs

여기까지는 전과 동일하게 코드를 사용하였다.

이 다음부터는 조금 수정하거나 프로젝트를 진행함에 있어 코드가 추가되었다.

1
2
3
4
5
6
7
8
9
10
11
12
str_datefrom = datetime.datetime.strftime(datetime.datetime(year=2018, month=5, day=3), '%Y.%m.%d')
str_dateto = datetime.datetime.strftime(datetime.datetime(year=2020, month=9, day=14), '%Y.%m.%d')
 
df = None
for page in range(1, pg_last+1):
    _df = parse_page(code, page)
    _df_filtered = _df[(_df['날짜'> str_datefrom) & (_df['날짜'<= str_dateto)]
    if df is None:
        df = _df_filtered
    else:
        df = pd.concat([df, _df_filtered])
df
cs

str_dateto를 원래 사용하지 않고 현재까지 크롤링을 했지만 2020-09-14까지의 데이터를 가져오기 위해 만들어 주었다.

1
2
df['날짜'] = pd.to_datetime(df['날짜'])
df








다음과 같이 원하는 날짜의 데이터만 크롤링했다.

1
2
3
df1 = df[['날짜', '종가']]
df1.columns = ['ds', 'y']
df1
cs









fbprophet 라이브러리를 사용하기 위해 '날짜', '종가', 데이터만 가져와 컬럼의 이름을 바꾸어 주었다.

1
2
3
4
m = Prophet()
m.fit(df1)
future = m.make_future_dataframe(periods=7)
future








모델에 학습을 시켜주고 위와 같이 데이터에 일주일간의 미래 날짜를 추가하였다.

1
2
forecast = m.predict(future)
forecast[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].tail(7)
cs







위와 같이 삼성전자의 일주일간의 미래 예측값과 예측값의 하한과 상한값을 예측했다.

이렇게 하여 삼성전자를 포함하여 동일 업종의 10개 종목에 대하여 일주일 후인 2020-09-21의 예측값과 실제 종가를 비교해 보았다.

삼성전자

실제값 : 59,200

예측값 : 61,350

예측값 범위  : 59,464 ~ 63,212

SK하이닉스

실제값 : 84,500

예측값 : 79,548

예측값 범위  : 74,742 ~ 84,219

이오테크닉스

실제값 : 100,000

예측값 : 118,572

예측값 범위  : 107,700 ~ 128,729

리노공업

실제값 : 124,200

예측값 : 142,923

예측값 범위  : 138,947 ~ 146,984

DB하이텍

실제값 : 37,000

예측값 : 37,404

예측값 범위  : 35,816 ~ 38,909

유진테크

실제값 : 28,950

예측값 : 33,505

예측값 범위  : 31,576 ~ 35,307

코미코

실제값 : 38,350

예측값 : 41,284

예측값 범위  : 39,266 ~ 43,186

솔브레인

실제값 : 225,300

예측값 : 204,648

예측값 범위  : 194,152 ~ 215,131

테스나

실제값 : 43,900

예측값 : 83,764

예측값 범위  : 78,534 ~ 88,809

에스앤에스텍

실제값 : 42,600

예측값 : 49,176

예측값 범위  : 47,240 ~ 51,260


DB하이텍을 제외한 모든 종목들이 예측값 범위에도 포함되지 않았다.

이는 데이터수집 기간을 삼상전자의 주식분할에 맞추어 약 2년 4개월의 짧은 기간으로 설정하여 수집했기 때문이라는 생각이든다.





댓글

이 블로그의 인기 게시물

SQL(9)(performance tuning queries, pivoting data)

데이터 크롤링(3주차)

SQL(8)(writing subqueries, window functions)