[python] 일별 주가정보를 이용해 이동평균선 데이타 만들기

개요

퀀트투자 하시는 분들은 주가정보와 기타 지표들을 모두 수집하고, 또 그 데이터를 정제해서 본인만의 데이터를 구축합니다. 그리고 그 데이터를 이용해 전략을 수립하고 백테스팅 툴을 이용해 전략을 시뮬레이션 해보고 실전 매매에 적용해보는 순서를 가지는데요.

 

저 역시 퀀트투자를 위한 데이터를 데일리로 수집하는 시스템을 구축해서 사용하고 있습니다. 

백테스팅은 python 라이브러리 backtrader 를 이용해 구성한 전략을 2000종목 이상 대입해보면서 전략의 가치를 판단해보고 있습니다. 

 

오늘은 이동평균선 매매를 위한 전략을 세울때 그 이동평균선 데이터를 정제하는 방법을 소개해드리려고 합니다. 

 

 

본문

 

주가정보 데이터는 키움 api를 통해 받아오고 있습니다. 실시간 데이터 수집과 스케줄러를 통한 데이터 수집을 위해 2개의 아이디를 이용해서 2개의 모듈로 수집하고 있으며 그외 한국투자증권 KIS API 통해서 추가적인 데이터도 쉽게 수집이 가능합니다.

그외 다른 증권사에서도 api를 통해 다양한 기능을 제공하고 있으며 증권사마다 제공하는 기능에 차이가 있으니 필요한 기능을 제공하는 증권사 api를 택하시면 됩니다.

 

주가정보 수집한 데이타는 DB 테이블에 저장해둡니다. OHLCV 데이터라고 하죠. 

일별, 주별, 월별 데이타를 구성해서 테이블에 저장해둡니다. 

그리고 이동평균선 데이타를 만들어줍니다. 

 

저의 경우 월별 차트데이타는  3선, 5선, 10선, 20선, 60선을 만들어둡니다. 일별은 더 길게 확장해서 만들어서 사용합니다.

이 데이타를 python 에서 제공해주는 DataFrame 에 넣어 정제를 해줍니다.

 

이동평균의 사이즈를 정해주는 rolling() 함수와 평균값을 만들어주는  mean() 그리고 소수점 반올림을 위한 round() 함수를 이용해줍니다.

 

rolling함수 상세정보는 아래 도큐먼트를 참고하시면 됩니다.

https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.rolling.html

 

pandas.DataFrame.rolling — pandas 2.0.1 documentation

If 'right', the first point in the window is excluded from calculations. If 'left', the last point in the window is excluded from calculations. If 'both', the no points in the window are excluded from calculations. If 'neither', the first and last points i

pandas.pydata.org

 

 

DataFrame 의 c_price 컬럼을 rolling 시켜서 나온 Window 객체로 mean() 평균함수를 적용시켜주면 이동 평균이 계산되어 나오게 됩니다.

 

5일 이동 평균 데이타를 소수점 3자리 반올림해서 할당해준다면 아래와 같이 코드를 짜볼 수 있습니다.

ma5 = df['c_price'].rolling(window=5).mean().round(3)

 

 

Window 객체가 제공하는 함수는 더 많습니다. 단순히 합계를 계산하고자 한다면 sum() 함수를 사용하셔도 됩니다.

 

Window객체를 더 다양하게 활용하시려면 아래 도큐먼트를 참고하세요

https://pandas.pydata.org/docs/reference/window.html

 

Window — pandas 2.0.1 documentation

Window Rolling objects are returned by .rolling calls: pandas.DataFrame.rolling() and pandas.Series.rolling(). Expanding objects are returned by .expanding calls: pandas.DataFrame.expanding() and pandas.Series.expanding(). ExponentialMovingWindow objects a

pandas.pydata.org

 

 

 

이렇게 나온 이동평균 값을 DataFrame객체에 컬럼명과 함께 다시 할당해줍니다. DB에 넣기 편한 구조로 만드는 과정입니다.

 

df.fillna(0) 함수는 이동평균 계산이 되지 않는 구간의 데이터에 None 대신 0을 할당해주는 작업입니다. DB에 넣을 때 오류가 나지 않게 하기 위함입니다. 

 

for code in list:
	df = dbAgent.getMontChartListToDf(code)
    
	ma3 = df['c_price'].rolling(window=3).mean().round(3)
	ma5 = df['c_price'].rolling(window=5).mean().round(3)
	ma10 = df['c_price'].rolling(window=10).mean().round(3)
	ma20 = df['c_price'].rolling(window=20).mean().round(3)
	ma60 = df['c_price'].rolling(window=60).mean().round(3)

	df.insert(len(df.columns), "MA3", ma3)
	df.insert(len(df.columns), "MA5", ma5)
	df.insert(len(df.columns), "MA10", ma10)
	df.insert(len(df.columns), "MA20", ma20)
	df.insert(len(df.columns), "MA60", ma60)

	df.fillna(0, inplace=True)
    
	dbAgent.updateMonthChartMA(df)

 

dbAgent.updateMonthChartMA(df) 호출을 통해 DB에 데이터를 넣습니다. mysql 워크벤치를 통해 데이터가 잘 정제되었는지 확인을 해봅니다. 다음과 같이 3, 5, 10, 20, 60선 이동평균 데이터가 만들어졌습니다. 

이 데이터를 가지고 와서 화면에 그려주면 그게 HTS에서 바라보는 차트가 되는 것입니다.

 

마무리

백테스팅에 활용이 가능한 이동평균 데이터를 만들어 보았는데요. 데이터의 활용도는 사용하기 나름일것입니다. 저는 직접 만든 백테스팅 툴이 데이터를 정제하는 과정을 보여주려고 예제 코드를 작성해 본것인데요. BackTrader를 사용하면 이런 과정을 거치지 않아도 됩니다. 일별 주가 데이터를 csv 파일로 만들어서 백트레이더에 지정만 해주면 알아서 다 진행해줍니다. 

전략구현을 통한 검증을 목표로 한다면 백트레이더 처럼 시중에 나와있는 오픈소스를 잘 활용하는게 맞을 것이고 백트레이더와 같은 툴을 만들겠다면 이런 과정을 거치는게 맞을 것입니다.