본문 바로가기
개발일지

11. 투자지표를 활용한 매매 시점 모니터링 - 멀티코어 데이터 수집

by kirion 2022. 11. 20.
반응형

멀티 코어를 이용해 주가 데이터를 빠르게 수집하기

2022.11.01 - [개발일지] - 1. 투자지표를 활용한 매매 시점 모니터링 - 개요

2022.11.07 - [개발일지] - 2. 투자지표를 활용한 매매 시점 모니터링 - RSI, RMI

2022.11.07 - [개발일지] - 3. 투자지표를 활용한 매매 시점 모니터링 - 벡테스팅

2022.11.08 - [개발일지] - 4. 투자지표를 활용한 매매 시점 모니터링 - 시각화

2022.11.08 - [개발일지] - 5. 투자지표를 활용한 매매 시점 모니터링 - Kospi 종목 벡테스팅

2022.11.09 - [개발일지] - 6. 투자지표를 활용한 매매 시점 모니터링 - 손절선

2022.11.10 - [개발일지] - 7. 투자지표를 활용한 매매 시점 모니터링 - 다중 종목 벡테스팅

2022.11.15 - [개발일지] - 8. 투자지표를 활용한 매매 시점 모니터링 - 전략 설계 참고

2022.11.18 - [개발일지] - 9. 투자지표를 활용한 매매 시점 모니터링 - RSI 종목 추천

2022.11.19 - [개발일지] - 10. 투자지표를 활용한 매매 시점 모니터링 - PDF Reporting

 

투자지표를 활용한 매매 시점 모니터링의 번외 글 주가 데이터 수집에 관한 부분을 점검해본다.

앞서 단타 전략 모니터링 시스템도, RSI 종목 추천 모니터링 시스템도 종목을 하나하나 불러와서 계산하기 때문에 속도가 굉장히 늦다는 단점이 있다.

 

kospi종목 824개를 한 번 훑어보는데 약 25분이 걸린다. 

따라서 단타 시스템의 경우 많은 종목을 동시에 모니터링하려면 여러 개의 스크립트를 실행해놓아야 한다는 번거로움이 있었다. 그래서 어떻게 하면 빠르게 모니터링할 수 있을까 찾아보다가 멀티코어를 이용해 효율적으로 수집하는 방법이 있었다.

python 패키지중 multiprocessing을 활용하여 주가 데이터를 빠르게 수집해 보자.

 

import pandas as pd
import time 
import FinanceDataReader as fdr

df_krx = fdr.StockListing('KRX')
kospi_data = df_krx[(df_krx["Market"]=="KOSPI") & (~df_krx["Sector"].isna())]

필요한 패키지와 kospi 종목 리스트를 만든다.

 

우선 단일 종목 하나씩 수집하는 방법으로 시간을 체크해 보자.

 

 

start_time = time.time()
stock_df = None
for code in list(kospi_data.Symbol)[0:20]: 
    stock_list = fdr.DataReader(code, '2017')
    stock_df = pd.concat([stock_df,stock_list],axis = 0)
print(time.time() - start_time)

# 36.04613280296326

20개 기업의 2017년부터 현재까지의 주가를 수집하는 코드를 실행해 보면 실행 시간은 약 36초가량 걸린다.

나는 사용의 편리성을 위해 pandas를 이용해 하나의 dataframe으로 묶었지만, 속도를 더 향상하기 위해 numpy 기반으로 수집하는 것이 좋다.

 

다음으로 멀티코어를 이용한 수집 시간을 체크해보자.

 

import multiprocessing
from multiprocessing import Pool
multiprocessing.cpu_count()

우선 멀티코어를 할 수 있도록 패키지를 import 하고 사용 가능한 cpu개수를 체크한다.

나는 aws의 r5.large 인스턴스를 사용하고 있어 cpu가 2개밖에 되지 않았다.

 

def stock_data_crawler(code):
    stock_df = fdr.DataReader(code, '2017') 
    return stock_df

start_time = time.time()
stock_data= None

p = Pool(2) # 코어수 
for stock_df in p.map(stock_data_crawler, list(kospi_data.Symbol)[0:20]): 
    stock_data = pd.concat([stock_data,stock_df],axis = 0)
p.close() 
p.join()
        
print(time.time() - start_time)

# 19.188039302825928

데이터를 수집하는 stock_data_crawler를 정의해준다. 이 함수는 한 개 기업의 주가 데이터를 수집할 수 있게 정의되어있다.

사용 가능한 코어수를 입력해 주고 위의 코드를 실행시키면 약 19초가 소요되었다.

 

36초에서 19초로 절반가량 시간이 단축되었다. 코어수가 2개였기에 코어당 10개의 기업을 수집한 셈이다. 따라서 코어수(n)가 늘어날수록 시간은 n분에 1이 될 것이다. 

 

내가 사용하는 r5.large는 메모리 16gb, cpu 2개가 할당되어있는 인스턴스인데 단타 전략 시스템과, RSI 종목 추천 시스템이 잡고 있는 메모리가 약 3gb 수준임으로 컴퓨팅 최적화인 c5~6 인스턴스로 바꿔 주가 데이터 수집 시간을 줄이는 것도 좋을 것 같다.(cpu 개수가 많은 인스턴스로)

개인 pc를 쓰는 경우 최대 허용 cpu를 사용해 위의 코드를 실행하면 될 것이다.

 

멀티코어를 활용해 주가 데이터를 수집하는 것을 시스템을 만들기 전에 알았다면 실시간으로 조회할 수 있는 종목을 늘리거나, 시간을 단축할 수 있었을 텐데 지금은 단일 종목을 순차적으로 하나씩 모니터링하도록 되어있어 시간적인 측면에서 손해를 보고 있다.

주가 데이터를 수집하는 부분을 멀티코어로 단축하는 로직으로 수정해서 실시간으로 모니터링하는 텀을 줄이는 것으로 적용하면 좋을 것 같다.

반응형

댓글