财新传媒 财新传媒

阅读:0
听报道

研判银行间资金利率走势,对于分析债券市场而言非常重要。Facebook在2017年开源了一个时间序列预测的算法,叫做fbprophet,其功能包括:

  1. 为预测设置上下限;
  2. 设置趋势断点;
  3. 处理季节性和节假日效应;
  4. 允许乘法形式的季节性;
  5. 区间预测;
  6. 处理异常值;
  7. 处理非日度数据;
  8. 模型检测。

我们认为,可以用这个算法,来为银行间资金利率,做出一个基础性的预测。初步探索如下:

一、安装

我们推荐使用conda安装,由于fbprophet需要调用pyStan这个开源工具,因此安装命令为下述两条:

conda install -c conda-forge pystan
conda install -c conda-forge fbprophet

二、数据准备

fbprophet的基础输入数据只需要两列,第一列是日期,第二列是要拟合和预测的时间序列数据。在本文中,我们使用3个月的SHIBOR作为案例。要注意的一点是,数据的变量名,一定修改成dsy。原始数据如下:

  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

推荐

经纬

经纬

344篇文章 12小时前更新

经济学博士

文章