共计 4921 个字符,预计需要花费 13 分钟才能阅读完成。
自 2018 年末以来,寰球金融根本盘由晚期的稳步回升变得起伏不定。因为投资者对市场走向和将来瞻望的不确定,这样的市场情绪带动着大盘和指数起起伏伏。同时中美贸易战给批发带来的微小关税压力让市场情绪再度低迷;2020 年初,新冠肺炎疫情在寰球肆虐蔓延,造成医疗资源缓和,疫情防控措施使商品和人员流动速度减慢,多地商店开业甚至开张,大大影响了人们的经济生存,进一步导致寰球各地股票市场呈现熔断甚至跌停的情况。面对动荡的金融市场,政府和金融监管机构推广了各式各样的政策以应答疫情造成的影响,稳住经济与股票根本盘。
对于许多金融从业者而言,市场的动荡意味着新的投资时机,而 2008 年金融危机的教训也时刻揭示着人们,时机背地往往随同着微小的危险。驰名的《巴塞尔协定 III》就是在应答寰球金融危机、强化金融监管的背景下应运而生的,它也是现阶段被宽泛使用于各大金融机构的寰球金融监管规范之一。如何辨认危险、保障资产平安并放弃其相应的流动性始终都是风险管理中重要的组成部分。在股票市场的风险管理中,金融从业者须要先查看价格变动是否在预期范畴内,并判断这样的变动是由零碎危险还是政策变动或重大事件所产生。如非零碎危险,金融从业者则须要在对政策或重大事件充沛的理解后,决定是否须要调整当下的策略,买入或发售相应的资产来保障机构金融层面的平安。判断零碎危险的办法有多种,其中较为风行的办法是通过历史价格信息来预测将来价格,并比拟实在价格与预测后果的差距。在本篇中,咱们将应用这样的办法进行股价预测,并与实在价格进行比照。
解决方案构造
为了实现对历史数据进行建模来预测将来价格,本篇采纳如下构造的解决方案,同时大部分数据迷信的我的项目也都能够应用相似的构造来实现:
- 确定预测指标
- 数据收集
- 探索性数据分析
- 数据预处理
- 特色工程
- 模型抉择和训练
- 模型评估
- 模型预测
确定预测指标
在股票市场中,稳定较大的股票不占多数。为理解市场情况,金融从业人员会偏向于钻研剖析股票指数而非单个股票的价格。因为指数绝对于单个股票来说更稳固,也更利于精准地建模。指数通常由多种股票形成,个别反映市场绩效的是广基指数,如道琼斯指数、标普 500 指数、日经指数、恒生指数等。这样的指数既能够反映出股票根本盘情况,又能够反映出投资人对经济现况的敏感度。在本篇中,咱们抉择的指标预测指数是标普 500 指数,是寰球最具标志性的追踪美国高市值公司的股票指数之一。
数据收集
收集金融数据的平台泛滥,其中像 Bloomberg、Qliq、Quandl 这样的国外市场平台,抑或是如同花顺、万德这样的国内平台都受到公众的青睐。大部分企业为了保证数据的准确性、安全性和时效性,在生产环境下会应用成熟的免费平台。在本篇中,咱们应用的是 Yahoo Finance,一个收费的公开金融数据平台,它不仅蕴含了大部分公开股票的实时数据,还提供了 Python API,能够通过股票代码和工夫区间间接查问历史价格。
import yfinance as yf
df_sp = yf.download('^GSPC',start="2012-11-01",end="2022-11-01")
Pandas 数据集“df_sp”蕴含了从 2012 年 11 月 1 日至 2022 年 10 月 31 日十年以来的标普 500 指数数据,记录了每个日期所对应的开市价格、最高价格、最低价格、闭市价格、闭市调整价格和交易量。
探索性数据分析
在收集完须要的数据后,首先能够查看数据集中可能存在的空缺记录和须要调整的字段。咱们应用以下函数来理解数据集中蕴含多少条记录、是否有空缺值以及每个字段所对应的数据类型。
df_sp.info()
能够看到,数据集中没有须要解决的空缺值,并且每个字段的类型都是对立的。除日期以外(Python Datetime 类型格局),其余字段都是数字类型。价格相干的都为浮点数,交易量相干的为整数。接下来,咱们通过以下函数查看数据的统计类信息。
df_sp.describe()
能够看到,指数数据都是负数,大部分以千为单位。惟一在单位上与其余列有所区别的是交易量数据。交易量的相对数值与价格相比相差微小,为了更有可比性,咱们须要调整交易量的相对数值大小。在本步骤中,咱们抉择先将交易量除以 1000000,使其变成以百万为单位,那么在数值上,交易量数值大小放大至千,与价格类似。
初步剖析数据后,咱们能够将价格信息的工夫序列可视化,更加直观地理解价格趋势。
通过图像,咱们发现开市、闭市、最高、最低和闭市调整的价格在趋势上十分类似;交易量和价格之间也有肯定的分割。咱们须要对交易量和价格做进一步的剖析来明确两者之间的关系。这里,咱们应用相关性矩阵(correlation matrix)来钻研变量之间的关系。
由此能够看出,交易量与价格之间没有十分高的相关性,但这并不能证实交易量不应该在价格预测中被思考。从另一个角度来说,各价格变量之间的相关性十分高,咱们只需筛选其中一个(闭市调整价格)进行预测即可。在下一步中,咱们只保留须要用到的信息即可。
df = df_sp[['Adj Close','Volume_in_M']]
另一个值得注意的特色是,相比于 2020 年之前总体回升的趋势,指数价格在 2020 至 2021 年间呈降落趋势。咱们须要放大这段时间的数据图像来理解具体情况。
2020 年 3 月,因为疫情的蔓延,寰球多个国家都开始履行封控政策。从后果能够看出市场对封控政策的反应微小,但与此同时多地政府也采取了各式各样的经济政策来稳固市场,人们的生产生存在疫情后开启了新的模式。在这里,咱们假如疫情的一系列政策会在短时间内继续上来。依据公共信息的评估,大家能够酌情调整模型和假如。在本我的项目中,咱们的指标是应用自 2020 年 2 月 15 日起的历史数据,预测将来 1 个工作日的调整后闭市指数价格。
至此,咱们实现了从原数据集中提取后续建模所需数据的全副步骤。为了施展提取数据的最大价值,咱们须要对现有的两个变量进行一些解决,从而尽可能残缺地展示数据的个性。特地是对于工夫序列数据而言,季节性和周期性都是十分重要的信息,而这些信息是能够从工夫序列自身提取的。必要的数据处理尽管会减少计算量,但能够换来更精准更欠缺的模型后果。
数据预处理
因为指数数据是工夫序列,相比于大多数回归预测,咱们不仅要思考模型须要什么样的变量,也须要思考工夫程序。在本篇中,回归预测的数学公式如下,对于须要预测的将来工夫为 t+1:
即使用 n 条历史记录来预测将来的价格。
为了提取无效信息辅助预测,咱们将数据预处理大抵分为四步:
- 将工夫转换为变量
- 更改价格数据
- 寻找周期和季节性
- 依据周期调整交易量数据
1. 将工夫转换为变量
首先,咱们须要将工夫信息从索引中提取进去。
df_mod_forecast = df_mod.reset_index()
df_mod_forecast.info()
从日期信息中,提取年、月、日和工作日信息,通过解决后的数据如下:
df_mod_forecast.head()
2. 更改价格数据
本篇的预测指标是将来价格,对于指数而言,金融从业者绝对看重的是价格变动而非是其数值的大小。咱们能够抉择预测价格,也能够抉择预测价格变动。咱们将依据数据自身的个性来决定二者当中谁更适宜建模。
首先,咱们能够将每日和前一个工作日的价格差百分比计算出来。
df_mod_forecast['AdjPricePctDelta'] = df_mod_forecast['Adj Close'].pct_change()
3. 寻找周期和季节性 — 解构工夫序列与自相干剖析
指数价格数据是以日期为单位的,且只有在工作日才有数据。咱们在尝试周期时能够有多种抉择,例如以周、月或者季度为单位。在本篇中,工夫序列合成成果最好的是月份。从 2020 年 2 月到 2022 年 11 月大概有 20 个月的工夫。适合的周期会帮忙咱们更好的寻找数据中的季节性。留神,在之前的工夫序列图像中咱们留神到,寰球疫情蔓延之后,股票市场体现出高于平时的稳定。咱们须要应用 multiplicative 模型来解决这个问题。咱们首先尝试合成价格的工夫序列。
通过以上图像能够看出,每 100 天大概有 5 个周期,每个周期大概有 20 天。除此之外,价格数据残差(residual)局部体现并不佳,彷徨在 1 左右。在这个根底上,咱们再进行自回归剖析,价格的 ACF 和 PACF 图像如下:
ACF 和 PACF 显示近 30 天的历史价格都对当下的价格有影响,而太多的信息会影响模型的效率,甚至带来过拟合的危险。咱们再来看看每日价格变动的解构后果。留神,因为价格差有负值,multiplicative 模型并不实用,咱们须要应用 additive 模型来进行工夫序列合成。
价格百分比差也体现出相似的季节性。残差比之前体现略有提高,彷徨在 0 左右,然而能够看出 2 月份左右的数据波动性远高于平时。价格变动的 ACF 和 PACF 如下:
价格差的 ACF 和 PACF 中,咱们能够看到近两天的历史价格变动对当天价格的影响比拟大。在本我的项目中,前两天的历史信息将纳入模型中思考。依据本节的发现,咱们能够在原先的根底上进一步解决数据,退出节令信息。咱们先计算出大抵须要多少个周期,以 0-20 的正整数为一周期填充数列,就能够失去代表周期性的变量。
n_seasonal_cycles = math.ceil(df_mod_forecast.shape[0]/20)
df_mod_forecast['seasonality']=(list(range(0,20))*n_seasonal_cycles[:df_mod_forecast.shape[0]]
4. 依据周期调整交易量数据
工夫序列较为传统的模型为 ARIMA 模型,这类模型只须要一条工夫序列,依据数据周期性等特色调试参数。工夫序列也能够应用机器学习进行建模,这样的模型能够输出更多的变量,但须要对数据进行调整。和 ARIMA 类型的模型不同,咱们须要应用 t-1 的价格稳定和 t-2 的价格稳定作为变量的一部分,输出模型进行训练。
在这里咱们须要使用 Pandas 的 shift 方程,将价格变动数据别离下移一个和两个工夫距离。Shift 方程须要索引作为工夫的根据,因而咱们须要将日期设为索引。依据日期,将价格变动数据下移。
df_model['t_1_PricePctDelta']=df_model['AdjPricePctDelta'].shift(periods=1)
df_model['t_2_PricePctDelta']=df_model['AdjPricePctDelta'].shift(periods=2)
以此类推,咱们将交易量数据别离下移一个和两个工夫距离,两者求差即可失去每个交易日昨天(t-1)与前天(t-2)之间的交易量差。
df_model['t-1volume'] = df_model['Volume_in_M'].shift(periods=1)
df_model['t-2volume'] = df_model['Volume_in_M'].shift(periods=2)
df_model['t_1_VolumeDelta'] = df_model['t-1volume'] - df_model['t-2volume']
通过交易日前一天的价格变动,咱们能够将其转换为涨跌符号来作为模型输出的一部分。
df_model['sign_t_1']=np.where(df_model['t_1_PricePctDelta']>0,1,0*df_model['t_1_PricePctDelta'])
至此,咱们实现了标普 500 指数数据从下载到转换的全过程。
在下篇中咱们将着手实现模型训练和预测步骤,依据模型来预测将来一个工作日的价格变动,并将预测后果与真实情况进行比对。
参考资料
- Time series into supervised learning problem
- Tuning Ada Boost
- S&P 500 historical data
- Bloomberg News
- 阿布(2021)。《量化交易之路 用 Python 做股票量化剖析》。机械工业出版社。