본문 바로가기

Project/BOAZ

[BOAZ] ADV 프로젝트 - 특정 시간대의 주가 변동 패턴을 이용한 실시간 주가 예측 (1)

BOAZ 활동을 시작한지 벌써 반 년이 지났습니다.

 

지난 6개월은 Base 세션으로 머신러닝과 딥러닝의 이론적인 부분들에 집중했다면,

앞으로 6개월은 Adv 세션으로 본인이 선택한 하나의 프로젝트에 집중하게 됩니다!

(종합설계(?), 캡스톤디자인(?) 과 같은 성격이라고 볼 수 있어요)

 

아무튼 저는 어떤 주제를 가지고 프로젝트를 진행해볼지 고민을 많이 했는데,

아무래도 평소 관심있는 주제를 가지고 지금까지 배운 내용을 적용해보고 싶은 마음이 가장 컸습니다.

 

특히 데이터 공부를 하며 꼭 해보고 싶었던 프로젝트가 있었는데 그게 바로 "주식 프로젝트" 였고, 

'이번 기회에 마음 맞는 친구들과 열심히 한 번 해보자' 해서 팀을 꾸리고 Adv 프로젝트를 시작하게 되었습니다.

 

앞으로 이 프로젝트의 포스팅이 얼마나 이어질지는 모르겠지만,

성공하고 실패하는 과정을 제 블로그에 천천히 담아볼까 합니다!

한 번 시작해 볼게요 :)

 


1. 주제 구체화

구체적인 주제 선정에 앞서,

일반적인 주가 예측 프로젝트는 현실적으로 불가능 하다는 생각이 들었습니다.

만약 100% 수익을 보장하는 그런 예측 모델이 있었다면 지금쯤 난리가 났겠죠..

 

그럼 주가 예측이 왜 불가능한 것일까요?

아마 독립변수들의 다양성, 불규칙성, 불확실성 등이 있을 것 같습니다.

 

예를 들어 최근 SK이노베이션과 LG화학의 배터리 분쟁 판결에 따라 주가가 변동한 사례가 있습니다.

만약 주가를 제대로 예측할 수 있다면 위 판결을 예측하여 모델의 학습에 사용되어야 하는데, 

이는 현실적으로 어려운 일입니다.

 

또한 수많은 투자자들의 매매 심리, 실시간으로 발생하는 새로운 이슈 등

예측할 수 없는 변수들을 예측할 수 있어야 주가를 예측할 수 있으니, 불가능한 것이 아닐까 하는 생각입니다.  

 

그래서 제가 생각한 것은 "매매 패턴 분석" 이었습니다.

최근 어떤 이슈가 있었든, 어떤 투자 심리가 반영되었든, 9시부터 9시30분까지 주가 변동이 다음과 같다면,

가까운 시간대의 주가는 비교적 높은 확률로 예측할 수 있지 않을까? 

 

2021.02.18 09:00~09:26 삼성전자 분봉 차트

 

예를 들어,

"위와 같은 주가 변동을 보인다면, 지난 데이터들의 패턴을 토대로 9시 40분까지는 주가가 상승할 것으로 예측된다"

이런 식으로 할 수 있지 않을까? 하는 의문이 들었습니다.

 

2. 프로젝트의 현실 가능성 파악

데이터 분석에 있어 가장 중요한 것은 데이터를 구할 수 있는지 여부입니다.

일별 주가 데이터는 쉽게 찾을 수 있는데, 분별 주가 데이터는 어떻게 구할 수 있을까요?

 

대부분의 금융 사이트에서는 용량 문제 때문인지 분별 주가 데이터를 따로 보관하지 않는 듯 했고,

영웅문(?) 사이트에서 API 를 활용하여 받을 수 있다는 정보를 찾았지만 너무 복잡했습니다.

 

그래서 제가 찾아낸 방법은 바로 네이버 금융의 url을 이용하는 것이었습니다.

동적 크롤링을 경험해 보신 분이라면 모두 아시겠지만, 

대부분 url은 직관적으로 해석이 가능하기 때문에 숫자만 몇 개 바꿔주면 원하는 url 주소를 찾을 수 있습니다. 

 

자! 이제 데이터를 구하는 방법을 찾았으니 프로젝트가 가능하겠다 싶었습니다.

 

import pandas as pd
import datetime
from selenium import webdriver
from tqdm.notebook import tqdm
import os
from pathlib import Path

current_path = Path(os.getcwd()) # 현재 경로를 객체화
os.chdir(current_path / 'data')

stock_code_list = ['원하는 종목 코드 리스트']

for stock_code in tqdm(stock_code_list):
    # 날짜 정하기
    start_date = datetime.datetime(2021,2,8) # 포함
    end_date = datetime.datetime(2021,2,10) # 포함
    ymd_list = [x.strftime('%Y%m%d') for x in pd.date_range(start_date, end_date, freq='B')]

    real_container_num = [2,3,4,5,6,10,11,12,13,14]
    big_box = [['체결날짜','체결시각','체결가','변동량']]

    for ymd in ymd_list:
        thistime = ymd + '180000'
        page = 0
        
        while page < 40:
            page += 1
            url = 'https://finance.naver.com/item/sise_time.nhn?code={}&thistime={}&page={}'.format(stock_code, thistime, page)

            driver = webdriver.Chrome('/chromedriver.exe')
            driver.implicitly_wait(1)
            driver.get(url)
            container = driver.find_elements_by_css_selector('tr')

            # 주말 건너뛰기
            if page==1 and container[2].find_elements_by_css_selector('td')[0].text == ' ':
                driver.implicitly_wait(0.1)
                driver.close()
                break
            
            # 중첩 for문을 빠져나오기 위한 Breaker
            Breaker = True

            for i in real_container_num:
                driver.implicitly_wait(0.1)
                box = []
                data = container[i].find_elements_by_css_selector('td')
                time_value = data[0].text
                price_value = data[1].text
                amount_value = data[6].text
                
                if time_value=='09:00':
                    box.append(ymd)
                    box.append(time_value)
                    box.append(price_value)
                    box.append(amount_value)   
                    big_box.append(box)
                    Breaker = False
                    break
                    
                else:
                    if time_value == ' ':
                        continue
                    else:
                        box.append(ymd)
                        box.append(time_value)
                        box.append(price_value)
                        box.append(amount_value)

                    big_box.append(box)
                    
            if Breaker == False:
                break

            driver.implicitly_wait(0.5)
            driver.close()
            
    data = pd.DataFrame(big_box[1:], columns=big_box[0])
    data.to_csv('%s_0208_0210.csv' %stock_code, index=False, encoding='euc-kr')

 

 

** 해당 방법으로는 일주일치 데이터만 구할 수 있습니다 (아마 용량 문제 때문에).

따라서 저는 매주 팀원들과 종목을 나눠 크롤링을 진행했습니다.

 

3. 전반적인 계획 세우기

지금 당장 생각하고 있는 큰 틀은 다음과 같습니다.

 

1. 데이터 크롤링 및 전처리 + 패스트캠퍼스 시계열 강의 수강

2. EDA

3. 유사한 패턴 분석 및 클러스터링

4. 머신러닝/ 딥러닝을 이용한 모델링

5. 오차 확인 및 피드백

6. 투자

 

현재 팀원들과 첫 번째 단계를 진행 중이며,

EDA에 힘을 많이 쏟으며 프로젝트의 방향이 변경되거나 구체화 될 것 같습니다.

 

결과물이 유의미하든 무의미하든 저에겐 흥미로운 프로젝트가 될 것 같네요 :)

화이팅 입니다!