股票数据获取与预测的全面流程:arch-garch、t-garch、多元线性回归、var模型、脉冲响应、协整关系

本文详尽涵盖了从数据准备、分析处理、数据集划分、预测到结果分析的完整流程,包括以下主要步骤:

1. 使用efinance库导入全面的股票数据,并通过时序图观察收盘价变化趋势,通过分布图了解收盘价分布特征,并对收盘价数据进行描述性统计分析。

2. 检验股票日收益率平方是否存在ARCH效应,并验证数据平稳性。通过绘制ACF与PACF图,获取p值和q值,建立ARMA-GARCH模型。在假设股票收益率服从正态分布的情况下,进行波动率预测。

3. 检验所建立的模型是否有效消除ARCH效应,并评估该模型对波动率的预测效果。

4. 探讨股票收益率是否符合student-t分布,并建立t-GARCH模型,以检验是否提高了波动率预测效果。

5. 构建股票价格与其所属行业板块指数、大盘指数的多元自回归方程。通过检验三个变量之间的协整关系,建立VAR模型,并审查回归结果以及分析脉冲响应的结果。

文中提供了全部数据集和代码,并欢迎通过gz公zh‘finance褪黑素’,回复关键字获取源代码文件。如有更多咨询,敬请联系。


目录

1. 导入股票数据并观察数据特征

1.1 使用efinance库导入全面的股票数据

1.2 绘制时序图

1.3 分布图特征

1.4 描述性分析

2. 检验该股票日收益率的平方是否存在 ARCH 效应,并建立 ARMA -GARCH 模型。
假设该股票收益率服从正态分布,预测其波动率。

2.1  ARCH 效应

2.2 建立arch-garch模型

3.检验建立的模型是否消除了 ARCH 效应,并评估该模型对波动率的预测效果

3.1 arch效应

3.2 预测效果

4.假设该股票收益率服从 student-t 分布,建立t-garch模型

5.建立股票价格与其所属行业版块的指数、大盘指数的多元自回归方程,检验三个变量间的协整关系,建立 VAR 模型,报告回归结果以及分析脉冲响应结果。

5.1 导入三个指标的数据

5.2 多元线性回归方程

5.3 协整关系

5.4 VAR模型

5.5 脉冲响应的结果


1. 导入股票数据并观察数据特征

1.1 使用efinance库导入全面的股票数据

下面代码是用于从efinance库获取股票历史报价数据的Python代码。

import efinance as ef:这一行代码是导入efinance这个Python库,并将其重命名为ef。efinance是一个用于获取中国金融数据的Python库。若没有下载这个库可以通过pip install efinance进行下载 stock_code = '000569':这一行代码定义了一个变量stock_code,并将其赋值为字符串'000569'。这个字符串是需要爬取的股票代码。
df = ef.stock.get_quote_history(stock_code):这一行代码调用ef.stock模块中的get_quote_history函数,并将之前定义的stock_code作为参数传入。这个函数的作用是获取指定股票的历史报价数据,并将这些数据返回为一个Pandas DataFrame对象,然后这个对象被赋值给变量df。

#导入股票数据
import efinance as ef
stock_code = '000569'
df = ef.stock.get_quote_history(stock_code)

1.2 绘制时序图

import matplotlib.pyplot as plt
# 绘制时序图
plt.figure(figsize=(12, 6))
plt.plot(date, data, label='Time Series Data')
plt.title('Time Series Plot')
plt.xticks(range(1,len(data),50),rotation=45) #因为日期太多,为了清晰的展示,这里设定X轴为每50个展示一个日期
plt.xlabel('Date')
plt.ylabel('Value')
plt.legend()
plt.show()

在六年里,公司的股票经历了巨大的波动。在2007年末,它的收盘价达到了历史最高点,展现出令人瞩目的增长态势。然而,到了2009年末,情况却发生了翻天覆地的变化。由于某些内部和外部因素的影响,公司的股票价格开始大幅下跌,许多投资者纷纷选择退股,以避免更大的损失。

1.3 分布图特征

#查看收盘价的分布图
import seaborn as sns
# 绘制分布图
plt.figure(figsize=(8, 5))
sns.histplot(data, bins=30, kde=True, color='blue')
plt.title('Distribution Plot')
plt.xlabel('Value')
plt.ylabel('Frequency')
plt.show()

收盘价的分布图呈现出双峰形态,其中6的价值点数量最为突出,占据了相当大的比例。这表明在特定时间段内,该收盘价水平得到了市场的广泛认可和交易活动的集中体现。进一步分析这一现象,可能与市场趋势、投资者情绪以及相关因素的影响有关。

1.4 描述性分析

# 描述性统计分析表格
stat_table = data.describe()
# 打印统计表格
print("\nDescriptive Statistics Table:")
print(stat_table)

数据集有1500个观测值,是一个相对较大的数据集。平均值和中位数都接近于3.28,这表明数据集的中心趋势大致在3.28左右。数据点与平均值的偏差大约是2.129435。根据四分位数的分析,最大的观测值10.49可能是潜在的异常值,因为它远大于上四分位数(Q3)的5.7575。

2. 检验该股票日收益率的平方是否存在 ARCH 效应,并建立 ARMA -GARCH 模型。
假设该股票收益率服从正态分布,预测其波动率。

2.1  ARCH 效应

# 计算日收益率
returns = data.pct_change().dropna()
# 计算平方收益率
squared_returns = returns**2
# 绘制平方收益率的时序图
plt.plot(squared_returns)
plt.title('Squared Returns Time Series')
plt.show()
squared_returns

通过观察股票走势图,我们可以明显看到波动的聚集现象,这初步表明收益序列存在ARCH效应。

接下来通过建立具体的模型,观察模型对数据的解释能力,判断是否具有效应,首先需要观察acf与pacf图得到模型特征:

lag_acf = ACF(data, lags=30)
lag_pacf = PACF(data, lags=30)
plt.show()      

这里ACF图缓慢下降,为拖尾,PACF在1阶后线段突然下降到标准差之内,且不再反弹,为截尾,符合AR模型特征。
p、q值是看还在标准差之外的最后一个横坐标,因此p为1,q无法判断。

# 检验平方收益率的ARCH效应
am = arch_model(returns, vol='Garch', p=1, q=0)
res = am.fit()
print(res.summary())

模型结果解释:
蓝色为迭代过程,绿色为函数评估次数,红色为负对数似然函数值,文本中提到了多次迭代,每次迭代都伴随着函数评估次数的增加。在优化的早期阶段,函数评估次数(Func. Count)快速增加,但随着迭代的进行,增加的速度减慢。负对数似然函数值(Neg. LLF):这是一个衡量模型拟合好坏的指标。随着迭代的进行,该值逐渐减小,表明模型拟合效果在逐步改善。在迭代16次后,优化过程成功终止。这表明模型已经收敛到一个稳定的状态。

结果分析:
该模型是一个常数均值-ARCH模型。R-squared(决定系数)和Adj. R-squared(调整后的决定系数)都是0.000,这表明模型对数据的解释能力很弱。AIC和BIC:这两个指标都是用于模型选择的。较低的值通常表示更好的模型。AIC和BIC分别为-6273.48和-6257.55,这两个值都很低,表明模型拟合效果很好。虽然R-squared值较低,但其他指标(如AIC和BIC)表明模型拟合效果很好。

是否具有arch效应:
omega和alpha[1]的系数估计值都显著不为0,这意味着ARCH模型对数据的波动性拟合较好。可以认为这个模型能反映具有ARCH效应。虽然模型的解释能力较弱,但ARCH模型成功地捕捉到了数据的波动聚集效应。

2.2 建立arch-garch模型

首先检验数据是否需要差分:

#检验数据是否需要差分
from statsmodels.tsa.stattools import adfuller  
print(adfuller(returns)) 

进行ADF检验以检验平稳性,由于p值为2.6286389637138668e-12<0.05,因此可以认为数据平稳,不需要差分

arma_order = (1, 0, 0) #p=1,q=0
arma_model = ARIMA(returns, order=arma_order)
arma_results = arma_model.fit() #拟合模型
# 提取模型的残差
residuals = arma_results.resid
lag_acf = ACF(residuals, lags=30)
lag_pacf = PACF(residuals, lags=30)
plt.show()   

结果里残差的自相关图(ACF图)和偏自相关图(PACF图)在0阶后都是截断,这意味着时间序列的自相关性和偏相关性都非常弱或者不存在。这可能意味着该时间序列是随机的或者符合一个简单的均值回归过程。

在这种情况下,可能不需要使用复杂的模型来拟合该时间序列。相反,可以使用简单的统计方法或技术来分析该时间序列。例如,可以使用移动平均模型或简单的线性回归模型来预测未来值。

但是,如果该时间序列的变动存在一定的周期性或趋势性,那么可以考虑使用ARIMA模型或其他时间序列模型来拟合该时间序列。选择合适的模型需要对时间序列数据进行深入分析和探索。

对残差建立garch模型:

print(adfuller(residuals)) #残差的p值为4.254754073573142e-12<0.05,不需要进行差分
# 拟合GARCH模型(示例中为GARCH(1,1),你可以根据实际情况调整)
garch_order = (1, 1)
garch_model = arch_model(residuals, vol='Garch', p=garch_order[0], q=garch_order[1])
garch_results = garch_model.fit()
# 输出ARMA和GARCH模型的结果
print("ARMA模型结果:")
print(arma_results.summary())
print("\nGARCH模型结果:")
print(garch_results.summary())

使用模型对未来进行预测:

# 预测未来一年的波动率
forecast_horizon = 250  # 一年大致有250个交易日
forecasts = garch_results.forecast(horizon=forecast_horizon)
weilai = forecasts.variance.dropna()
lumber = weilai.iloc[0]
# 绘制波动率预测图,预测未来一年
plt.plot(lumber)
plt.title('Volatility Forecast for the Next Year (ARMA-GARCH)')
plt.xticks(range(1,len(lumber),50),rotation=45) #为了横坐标显示清楚,通过间隔50个显示一个值
plt.show()

3.检验建立的模型是否消除了 ARCH 效应,并评估该模型对波动率的预测效果

3.1 arch效应

# 检验残差序列是否还存在ARCH效应
arch_test_result = garch_results.arch_lm_test(lags=5)
print("\nARCH效应检验结果:")
print(arch_test_result)

原假设是残差是同方差的,而备择假设是残差是有条件异方差的。由于p-value小于0.05,可以拒绝原假设,即在这个模型中存在ARCH效应,即残差是有条件异方差的。这表明在时间序列中,波动率不是固定的,而是会随着时间的推移而发生变化,存在一定的波动。

3.2 预测效果

这里为了评估模型的预测效果,我们选择提取数据集第一天至倒数第250天中间的数据为测试集,用来训练模型,后250天为测试集,用于检验模型效果:

data2 = data[:-250]
# 计算日收益率
returns = data2.pct_change().dropna()
# 拟合ARIMA模型(示例中为ARIMA(1,0,1),你可以根据实际情况调整)
arma_order = (1, 0, 0)
arma_model = ARIMA(returns, order=arma_order)
arma_results = arma_model.fit()
# 提取ARMA模型的残差
residuals = arma_results.resid
# 拟合GARCH模型(示例中为GARCH(1,1),你可以根据实际情况调整)
garch_order = (1, 1)
garch_model = arch_model(residuals, vol='Garch', p=garch_order[0], q=garch_order[1])
garch_results = garch_model.fit()
# 预测未来一年的波动率
forecast_horizon = 250 # 一年大致有252个交易日
forecasts = garch_results.forecast(horizon=forecast_horizon)
lum2 = forecasts.variance.dropna().iloc[0] #提取拟合值
returns = data[-251:].pct_change().dropna() #提取测试集的真实值
date = df['日期']
# 计算实际波动率(使用平方收益率)
actual_volatility = returns**2
# 绘制波动率预测图
plt.plot(date[-250:],lum2, label='Forecasted Volatility')
plt.plot(date[-250:],returns, label='Actual Volatility (Squared Returns)')
plt.legend()
plt.xticks(range(1,len(date[-252:]),20),rotation=45) #为了横坐标显示清楚,通过间隔50个显示一个值
plt.title('Volatility Forecast vs Actual Volatility')
plt.show()
from sklearn.metrics import mean_squared_error

# 计算MSE
mse = mean_squared_error(lum2, returns)
# 打印MSE
print("均方误差 (MSE):", mse)

为了计算模型预测与实际值之间的均方误差(MSE)等类似的值,可以使用相应的性能评估指标。

均方误差(MSE)是评估预测模型性能的一种指标,它衡量了模型的预测值与实际观测值之间的平方差的平均值。MSE越小,说明模型的预测值越接近实际观测值,模型性能越好。

在这里,得到的均方误差为0.0007670950374335474,这是一个较小的值,表明您的模型在对未来波动率的预测方面表现较好。然而,具体的评估需要结合具体的应用场景和数据特点进行,可以将MSE与其他性能指标一起考虑,以全面评估模型的表现。

4.假设该股票收益率服从 student-t 分布,建立t-garch模型

可以使用t-GARCH模型来拟合这种分布。这是因为t分布相比于正态分布具有更重的尾部,能更好地捕捉极端事件。
假设股票收益率服从t分布可以更好地捕捉尾部的厚尾特性,相对于正态分布,这在面对极端事件时可能提高模型的预测效果。然而,效果的提升并非总是保证的,因为股票市场波动性受多种因素影响,而分布的假设仅是其中之一。

#为了评估是否有提升模型效果,和上面一样将数据集划分为训练集和测试集
data1 = data[:-250]
data2 = data[-250:]
# 计算日收益率
returns = data1.pct_change().dropna()

# 拟合ARIMA模型(示例中为ARIMA(1,0,1),你可以根据实际情况调整)
arma_order = (1, 0, 9)
arma_model = ARIMA(returns, order=arma_order)
arma_results = arma_model.fit()

# 提取ARMA模型的残差
residuals = arma_results.resid

# 拟合t-GARCH模型(示例中为GARCH(1,1),你可以根据实际情况调整)
t_garch_order = (1, 1)
t_garch_model = arch_model(residuals, vol='Garch', p=t_garch_order[0], q=t_garch_order[1], dist='t')
t_garch_results = t_garch_model.fit()

# 预测未来一年的波动率
forecast_horizon = 250  # 一年大致有252个交易日
t_forecasts = t_garch_results.forecast(horizon=forecast_horizon)

# 提取预测的波动率
t_volatility_forecast = np.sqrt(t_forecasts.variance.dropna().iloc[0])

return2 = data2.pct_change().dropna()
# 计算实际波动率(使用平方收益率)
actual_volatility = return2**2

# 绘制波动率预测图
plt.plot(range(len(t_volatility_forecast)),t_volatility_forecast, label='t-GARCH Forecasted Volatility')
plt.plot(range(len(actual_volatility)),actual_volatility, label='Actual Volatility (Squared Returns)')
plt.legend()
plt.title('t-GARCH Volatility Forecast vs Actual Volatility')
plt.show()

# 计算MSE
mse = mean_squared_error(t_volatility_forecast[1:], actual_volatility)
# 打印MSE
print("均方误差 (MSE):", mse)
均方误差 (MSE): 0.009756220648004233

对比均方误差,并没有提升模型效果

5.建立股票价格与其所属行业版块的指数、大盘指数的多元自回归方程,检验三个变量间的协整关系,建立 VAR 模型,报告回归结果以及分析脉冲响应结果。

5.1 导入三个指标的数据

stock_code = '931008'
df2 = ef.stock.get_quote_history(stock_code)
stock_code = '399001'
df3 = ef.stock.get_quote_history(stock_code)
#这里因为前面的长城已经退市了,股票数据不全,这里选取另一个日期完整的股票
stock_code = '002594'
df1 = ef.stock.get_quote_history(stock_code)
industry_index = df2['收盘'][-1500:].tolist()
market_index = df3['收盘'][-1500:].tolist()
stock_prices = df1['收盘'][-1500:].tolist()
dates = df1['日期'][-1500:].tolist()
# 创建DataFrame
data = pd.DataFrame({
    'Stock_Price': stock_prices,
    'Industry_Index': industry_index,
    'Market_Index': market_index
}, index=dates)

5.2 多元线性回归方程

import statsmodels.api as sm

# 定义因变量和自变量  
X = data[['Industry_Index', 'Market_Index']]  # 自变量  
y = data['Stock_Price']  # 因变量  
  
# 添加常数项(截距项)  
X = sm.add_constant(X)  
  
# 拟合多元自回归方程  
model = sm.OLS(y, X)  
results = model.fit()  
  
# 输出回归结果  
print(results.summary())

这是一个OLS(最小二乘法)回归的结果,用于分析股票价格(Stock_Price)与行业版块指数(Industry_Index)和大盘指数(Market_Index)之间的关系。以下是对结果的详细解释:

R-squared 和 Adj. R-squared:这两个值都是0.835,表示模型中自变量对因变量的解释力度很高。

F-statistic 和 Prob (F-statistic):F统计量是用于检验模型整体显著性的统计量,这里为3797.0。其对应的p值为0.00,小于常用的显著性水平(如0.01或0.05),说明模型整体上是显著的。

const:截距项的系数,为-142.6678。 Industry_Index:行业版块指数的系数,为0.0525。这表示当行业版块指数增加1单位时,股票价格预期会增加0.0525单位。 Market_Index:大盘指数的系数,为-0.0070。这表示当大盘指数增加1单位时,股票价格预期会减少0.0070单位。 Std err:标准误差,用于估计回归系数的精度。

5.3 协整关系

from statsmodels.tsa.vector_ar.vecm import coint_johansen

# 检验协整关系
coint_test_result = coint_johansen(data, det_order=0, k_ar_diff=1)
print("协整关系检验结果:")
print(coint_test_result.cvm)
print(coint_test_result.lr1)

上面的矩阵表示各变量之间的协整关系所对应的方差比。如果这个矩阵的某些元素非常大,那么对应的变量与其余变量之间的协整关系可能很弱。
[15.37067127 6.52429296 2.64345578]这是LR1统计量的值。在给定的数据中,该值对应于假设的协整向量数量。例如,如果假设有1个协整向量,那么这个值会对应于第一个元素。LR1统计量用于确定协整向量的数量。较大的值倾向于拒绝较少的协整向量假设,而较小的值倾向于接受较少的协整向量假设。

这里说明存在协整关系。

5.4 VAR模型

from statsmodels.tsa.api import VAR

# 建立VAR模型
model = VAR(data)
var_results = model.fit(maxlags=1, ic='aic')

# 打印VAR模型的结果
print("VAR模型结果:")
print(var_results.summary())

这个VAR模型的结果显示了Stock_Price和Industry_Index之间的动态关系,特别是在滞后一期的变量之间。从结果来看,Stock_Price对其自身滞后一期的影响非常显著(p值接近于零),而Industry_Index对Stock_Price的影响也相当显著(p值接近于零)。然而,Market_Index对Stock_Price的影响虽然统计上是显著的(p值小于常见的显著性水平如0.1或0.05),但其影响程度较小(t统计量较小)。

5.5 脉冲响应的结果

# 绘制脉冲响应图
# 创建一个图表,并设置尺寸
plt.figure(figsize=(2, 2))
irf = var_results.irf(10)  # 10期的脉冲响应
irf.plot(impulse='Market_Index', response='Stock_Price')
plt.show()

图形在特定期数内升高,表示Market_Index脉冲在该期对Stock_Price有正向影响

# 绘制脉冲响应图
irf = var_results.irf(10)  # 10期的脉冲响应
irf.plot(impulse='Industry_Index', response='Stock_Price')
plt.show()

图形在特定期数内降低,表示Industry_Index脉冲在该期对Stock_Price有正向影响

文中提供了全部数据集和代码,并欢迎通过gz公zh‘finance褪黑素’,回复关键字获取源代码文件。如有更多咨询,敬请联系。

  • 22
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
以下是一个简单的21支股票日收益数据的GARCH-Copula-VaR模型的Python代码示例: ```python import pandas as pd import numpy as np import scipy.stats as st import arch # 导入数据 data = pd.read_csv('stock_returns.csv', index_col=0) # 计算每支股票的收益率 returns = data.pct_change().dropna() # 计算协方差矩阵和相关系数矩阵 cov_matrix = returns.cov() corr_matrix = returns.corr() # 估计每支股票的GARCH模型 garch_models = [] for i in range(len(returns.columns)): stock_return = returns.iloc[:, i] garch_model = arch.arch_model(stock_return, vol='GARCH', p=1, q=1) garch_models.append(garch_model.fit()) # 计算每支股票的残差 residuals = pd.DataFrame(index=returns.index, columns=returns.columns) for i in range(len(returns.columns)): stock_return = returns.iloc[:, i] garch_model = garch_models[i] residuals.iloc[:, i] = garch_model.resid # 拟合Copula模型 copula = arch.copula.GaussianCopula() copula.fit(residuals) # 估算VaR alpha = 0.01 n_days = 1 portfolio_value = 1000000 icdf = st.norm.ppf(alpha) simulated_returns = [] for i in range(n_days): # 生成标准正态残差 u = copula.simulate(len(returns)) z = st.norm.ppf(u) # 计算每支股票的条件方差 cond_var = np.zeros(len(returns)) for j in range(len(returns.columns)): garch_model = garch_models[j] cond_var += garch_model.conditional_volatility**2 # 计算组合收益率和组合方差 port_return = np.dot(np.sqrt(cond_var), z) port_var = np.dot(np.dot(z, cov_matrix), z) # 计算VaR simulated_returns.append(port_return) var = -portfolio_value * port_return - icdf * np.sqrt(portfolio_value * port_var) print('Day {}: VaR is {}'.format(i+1, var)) ``` 注意:本代码示例仅仅提供了一个简单的GARCH-Copula-VaR模型,实际应用中还需进行更加全面数据分析、模型检验和风险控制。同时,代码中用到的收益率数据模型参数均为示例数据,实际应用中需要进行相应的修改。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值