본문 바로가기
데이터 분석/데이터 분석

[데이터 분석] ARIMA 모델을 활용한 CMA 잔고 분석

by thomasito 2021. 7. 10.
반응형

CMA 잔고를 예측할 수 있을까?

 

 최근에 데이터 분석에 관심이 많아져서 이런 저런 생각을 많이 하고 있다. 나는 부서에서 CMA 상품 관련 분석 업무를 맡고 있는데 'CMA 잔고를 통계 모델을 이용해서 예측해보면 어떨까?' 라는 호기심이 생겨서 간단한 통계모델을 돌려보기로 했다. 

 

 시계열 데이터의 경우는 과거 데이터의 영향을 많이 받으므로 AR(AutoRegession 자기상관), MA(Moving Average 이동평균) 관련된 모델을 많이 사용한다. 나는 그 중 AR과 MA를 결합한 ARIMA 모델을 선택했다. (ARIMA 모델에 대한 정보는 인터넷을 찾아보시면 훌륭한 설명들이 많이 나와있습니다!)

 

(Step 1) 잔고 데이터 전처리

 첨부파일로 첨부한 엑셀자료는 금융투자협회에서 제공하는 RP형, MF형, 종금형, 발행어음형 CMA에 대한 잔고 데이터이다. 오늘은 RP CMA의 잔고를 대체하고 있는 발행어음형 CMA 잔고에 대해 알아보겠다.

CMA_data.xlsx
0.38MB

import pandas as pd
from matplotlib import pyplot as plt

# 파이썬을 구동하는 폴더내 엑셀파일을 저장해주어야 한다
load_filename = 'CMA_data.xlsx'
data = pd.read_excel(load_filename,sheet_name="Sheet1")
print(data.head())

 우선 엑셀파일에서 데이터를 불러온다. 데이터가 잘 로드되었는지 프린트를 해본다.

# 컬럼이름을 'total'로 변경
data_pn = data["증권 발행어음형잔고"]
data_pn.columns = ['total']

# 발행어음형 CMA 잔고 그려보기
plt.figure(figsize=(15,10))
plt.plot(data_pn)
plt.xlabel('Date')
plt.ylabel('Balance')
plt.title("promissory note")

 잔고가 중간중간 튀는 게 보인다. RP형 CMA와 동일하게 최근 공모주 청약 때문에 잔고가 급증, 급락을 반복하는 것 같다. 현재는 대충 7조원 말 정도의 잔고가 있는 것으로 보인다. 

 

(Step 2) ARIMA 모형 선택

 시계열 분석을 하기 위해서는 기본적으로 시계열이 정상성(stationary)이 있다는 가정을 만족해야 한다. 일반적으로 ADF(Augmented Dickey Fuller) Test 결과 p value 가 0.05 보다 작으면 정상성이 있다고 본다.

# AD-Fuller Test : 시계열의 정상성(stationary) 한지 확인

from statsmodels.tsa.stattools import adfuller

""" 차분 방법 """
data_pn_diff = data_pn - data_pn.shift(1)
print(data_pn_diff)

y = data_pn.dropna()
y1diff = data_pn_diff.dropna()
result = adfuller(y)
print(f'원 데이터 ADF Statistic: {result[0]:.3f}')
print(f'원 데이터 p-value: {result[1]:.3f}')
result = adfuller(y1diff)
print(f'1차 차분 ADF Statistic: {result[0]:.3f}')
print(f'1차 차분 p-value: {result[1]:.3f}')

원 데이터 ADF Statistic: -0.515 원 데이터 p-value: 0.889

1차 차분 ADF Statistic: -11.387 1차 차분 p-value: 0.000

1차 차분한 결과가 정상성이 있으므로 차분모델은 정상성의 가정을 만족한다.

 

data_pn_mean = data_pn.rolling(window=30).mean()
data_pn_std = data_pn.rolling(window=30).std()

plt.figure(figsize = (15,5))
plt.xlabel('Date')
orig = plt.plot(data_pn, color='blue', label='balance')
mean = plt.plot(data_pn_mean, color='red', label='30day_mean')
plt.legend(loc='best')
plt.show()

 30일 이동평균선을 그려보면 추세가 정확하게 보이므로 MA(1) 모델을 써도 되겠다.

 

from statsmodels.graphics.tsaplots import plot_acf, plot_pacf

plot_acf(y)
plot_pacf(y)
plt.show()

diff_1=y.diff(periods=1).iloc[1:]
diff_1.plot()
plot_acf(diff_1)
plot_pacf(diff_1)
plt.show()

 또한 1번째 직전 일자 데이터와 자기상관이 뚜렷해보이므로 AR(1) 모델도 적절해보인다. 결론적으로 ARIMA(1,1,1) 모델로 AR(1), MA(1)을 결합한 모델이 적절해 보인다.

 

(Step 2) ARIMA 모델 선택

 이번에는 ARIMA 모델을 학습시킨 후에 계수(coefficient)가 유의한지 검증해본다. 

from statsmodels.tsa.arima_model import ARIMA

data_pn = data_pn.sort_index(ascending=True)
data_pn = data_pn.dropna()
model = ARIMA(data_pn.values, order = (1,1,1), dates=(data_pn.index))
model_fit = model.fit(trend='nc',full_output=True, disp=True)
print(model_fit.summary())
model_fit.plot_predict()

 P-value 가 0에 수렴하는 것으로 보아 모형선택이 적절해 보인다. 학습시킨 모형으로 파란 선을 그어본 경우 추세와 거의 유사하다. (물론 Overfitting 과최적화 상태로 보인다.)

 

result = model_fit.forecast(steps=100)
plt.figure(figsize=(20,10))
print(result)
plt.plot(result[2][0])

 과거 100일 이후로는 선형으로 잔고가 계속 상승할 것으로 예측된다. 100일뒤인 10월 중순 쯤에 실제로 잔고가 8.6조원에 근접하는 지 확인해보면 되겠다.

 

 아직 이론적인 지식과 실무 경험은 부족하지만 계속 모델을 만들고 예측하는 노력을 계속해보아야 겠다. ^^

반응형

댓글