研判银行间资金利率走势,对于分析债券市场而言非常重要。Facebook
在2017年开源了一个时间序列预测的算法,叫做fbprophet
,其功能包括:
-
为预测设置上下限; -
设置趋势断点; -
处理季节性和节假日效应; -
允许乘法形式的季节性; -
区间预测; -
处理异常值; -
处理非日度数据; -
模型检测。
我们认为,可以用这个算法,来为银行间资金利率,做出一个基础性的预测。初步探索如下:
一、安装
我们推荐使用conda安装,由于fbprophet
需要调用pyStan
这个开源工具,因此安装命令为下述两条:
conda install -c conda-forge pystan
conda install -c conda-forge fbprophet
二、数据准备
fbprophet
的基础输入数据只需要两列,第一列是日期,第二列是要拟合和预测的时间序列数据。在本文中,我们使用3个月的SHIBOR作为案例。要注意的一点是,数据的变量名,一定修改成ds
和y
。原始数据如下:
ds | y | |
---|---|---|
3547 | 2020-12-16 | 2.952 |
3548 | 2020-12-17 | 2.905 |
3549 | 2020-12-18 | 2.855 |
3550 | 2020-12-21 | 2.818 |
3551 | 2020-12-22 | 2.796 |
三、初步处理
fbprophet
算法的大概步骤是,先生成一个Prophet
实例,然后调用fit
方法进行拟合,调用predict
方法进行拟合。代码如下:
m = Prophet()
m.fit(data)
future_time = m.make_future_dataframe(periods=365)
forecast = m.predict(future_time)
fig1 = m.plot(forecast)
fig2 = m.plot_components(forecast)
下图就是模型预测的初步结果,其中黑色表示原始数据的离散点,深蓝色线表示通过时间序列模型拟合的值,浅蓝色区域表示预测的置信区间。
我们来看看模型提取出的时间序列分项,从下图可以看到,模型自2018年之后,对资金利率的趋势预测是线性向下的。从年内各月份的资金利率规律来看,呈现出上半年下行、下半年上行、年中短暂跳升的W型。从周内的规律来看,周五有一个明显的跳升。
四、进一步修正
1、趋势项预测方法的选择。 fbprophet
模型中,对趋势项的预测有两种方法,第一种是基于逻辑回归函数(logistic function
),一般用来拟合单向增长或下降,但是增长或者下降有界限的数据,第二种是基于分段线性函数(piecewise linear function
)。我们在本案例中选择第二种方法,这也是fbprophet
模型的默认方法,不需要单独设定。
2、趋势变点的设定和检测。 时间序列数据中,趋势的方向可能会出现变化,这就是所谓的“变点”。fbprophet
模型会自动识别变点,而且为了避免过拟合的问题,模型默认在前80%的样本中识别变点。下图用红色竖线标识出模型自动识别的变点,根据最新识别的变点,整体趋势预测是下行的:
我们可以用changepoint_range
来调整设置变点的范围,比如我们修改设置changepoint_range=1
,可以看到,模型将5月份以来的资金面边际收紧,识别为未来的趋势,对未来资金利率的预测整体上行,这就产生了过拟合的问题。
我们也可以手动设置变点的位置,比如我们认为,银行间资金利率,受到准备金率调整的影响特别大,那么就可以把调整准备金率的时间,作为变点进行输入,结果如下:
3、节假日调整。 在很多时间序列中,节假日是很常见的影响因子,我们可以在模型中添加下述语句,来纳入中国的节假日,fbprophet
模型中纳入的中国节假日有:元旦、春节、清明节、劳动节、端午节、中秋节 国庆节。由于这些假日银行间市场一般都不交易,所以我们在本案例中不予处理。
m.add_country_holidays(country_name='CN')
id holiday |
---|
0 New Year's Day |
1 Chinese New Year |
2 Tomb-Sweeping Day |
3 Labor Day |
4 Dragon Boat Festival |
5 Mid-Autumn Festival |
6 National Day |
4、季节性设置。 fbprophet
模型中,默认识别的季节性是周度和年度,但是对于银行间资金利率而言,周度的季节性特征并不明显,但是月度和季度的季节性比较明显,因此我们需要把周度季节性调整成月度和季度季节性。
从季节性分解图上可以看到,资金利率在月内有比较明显的季节性,月初缴准是一个高点,下旬税期是一个高点,月末是一个高点。资金利率在每个季度的最后一个月,利率偏高。
5、工作日调整。 因为银行间资金利率,只有工作日有数据,因此我们需要对预测的工作日进行调整:
future_time = m.make_future_dataframe(periods=365,freq='B')
五、优缺点分析
fbprophet
模型速度比较快,而且有一定的灵活度,可以自行设置节假日、淡旺季、工作日、季节性特征、变点等,是一个功能很强大的模型。
但是缺点也比较明显,就是模型仅基于历史数据进行预测,无法引入外部变量,比如央行降准,或者大额超量续作MLF等,都会对资金利率带来明显影响,但是模型无法捕捉这种外生变量。因此笔者认为,fbprophet
模型可以基于时间序列特征,提供一个很好的基准情形,然后我们再根据其他外部因素进行调整。
我们对未来1年的资金利率的预测结果和代码如下:
m = Prophet(changepoints=rrr.index.astype(str).tolist(),weekly_seasonality=False)
m.add_seasonality(name='monthly', period=30.5, fourier_order=5)
m.add_seasonality(name='quarterly', period=90, fourier_order=7)
future_time = m.make_future_dataframe(periods=365,freq='B')
forecast = m.fit(data).predict(future_time)
fig1 = m.plot(forecast)
fig2 = m.plot_components(forecast)
0
推荐