题目及设计思路
题目
给出基于AR模型的卡尔曼滤波股票预测。
设计思路
本实验实现的是中兴通讯公司股价预测,使用AR模型预测股价,并将卡尔曼滤波应用到AR模型的预测结果上,对预测的股价进行滤波处理,可以更准确地预测股价趋势。
第一步是加载股票数据,然后将股票数据分为训练数据和预测数据,这里训练数据是前300天的股价,预测数据是301-400天的股价。
第二步是使用AR模型进行训练,使用AR模型对前300天的股价进行拟合,并使用拟合的AR模型预测接下来的100天的股价。
第三步是使用卡尔曼滤波,首先定义测量噪声协方差和过程噪声协方差矩阵,然后初始化状态转移矩阵和观测矩阵,然后分别初始化状态估计和状态估计协方差,最后使用卡尔曼滤波对状态进行迭代估计,得到估计的状态,最后将AR模型预测的股价和AR模型+卡尔曼滤波估计的股价进行比较,以观察加入卡尔曼滤波后预测股价是否得到改进。
AR模型及卡尔曼滤波预测股价原理
AR模型
AR模型是自回归模型,是一种统计学模型,它把当前时刻的观测值和之前时刻的观测值联系起来,而这种联系是满足自回归方程的。AR模型的数学表示为:
![](https://i-blog.csdnimg.cn/blog_migrate/96e05b2946d304f771249885fcfcf55d.png)
其中yt表示当前时刻的观测值,ϕ1、ϕ2、⋯、ϕp表示自回归系数,yt-1、yt-2、
⋯、yt-p表示前p个时刻的观测值,ϵt表示残差项,满足E(ϵt)=0和E(ϵt2)=σ2。
卡尔曼滤波
卡尔曼滤波(KalmanFilter)是一种基于状态空间模型的最优滤波,用于处理系统状态估计的问题,它可以对受噪声影响的随机过程进行有效的估计。卡尔曼滤波的数学原理可以用下面的公式来表示:
预测步骤:
![](https://i-blog.csdnimg.cn/blog_migrate/b55b768f930c543fa83c1d24cc8709bf.png)
更新步骤:
![](https://i-blog.csdnimg.cn/blog_migrate/c657ef8eecb03c44dfc4c7b2c7c95921.png)
其中:xk表示状态向量,Pk表示状态向量的协方差矩阵,ϕk表示状态转移矩阵,Hk表示观测矩阵,Qk表示过程噪声协方差矩阵,Rk表示测量噪声协方差矩阵,zk表示观测值。
结果分析
以中兴通讯的400天股价作为数据,前300天的股价数据用于训练模型,后100天的数据用于预测,见下图。在第301-400天的时候的AR模型预测数据为红线所示。
![](https://i-blog.csdnimg.cn/blog_migrate/4ff833345dd5e2c403337ce6a949bcb9.png)
截取301-400天的预测区域并加入原始数据作为对比,效果如下图,可见AR模型对于股价的预测是有效果的。
![](https://i-blog.csdnimg.cn/blog_migrate/3b187ad683f2800864765ce9ff4af96f.png)
从上图可知,仅使用AR模型便能够在一定程度上预测出股价。在趋势上,预测的数据与实际数据基本一致。
加入卡尔曼滤波后,预测的股价图如下图
![](https://i-blog.csdnimg.cn/blog_migrate/a54e500a4de6f4b0c83b7ec5a13ba7fd.png)
由上图可知,经过卡尔曼滤波后的股价相较于原来的股价更加的平滑,且滤除掉了一部分噪声的干扰,一定程度上让预测的股价更加准确。
下图是经过AR模型和卡尔曼滤波后的股价预测图。
![](https://i-blog.csdnimg.cn/blog_migrate/aafeca90fdb0e011416ed0edbd5d01ad.png)
由上图可知,针对于数据进行卡尔曼滤波后,数据的平滑度变高,且对于噪声造成的预测数据误差降低,因此对于整体的预测准确度是有帮助的。
关键代码
以下代码是AR模型与卡尔曼滤波的骨干代码,其余代码见附录。
AR模型与卡尔曼滤波骨干代码 |
model = ar(train_data, 50); predictions = predict(model, pred_data, 100); x_hat = x_hat_0; P = P_0; for i = 2:100 x_hat_minus = A * x_hat; P_minus = A * P * A' + Q; K = P_minus * C' / (C * P_minus * C' + R); x_hat = x_hat_minus + K * (data1(i) - C * x_hat_minus); P = (1 - K * C) * P_minus; estimated_states(i) = x_hat; end |
完整代码:
data = csvread('D:\360downloads\stockdata.csv');
train_data = data(1:300, 2);
pred_data = data(301:400, 2);
model = ar(train_data, 50);
predictions = predict(model, pred_data, 100);
% 后300天股价预测值
figure;
time = data(301:400, 1);
plot(time, pred_data, 'b', time, predictions, 'r');
legend('真实股价', '预测股价');
xlabel('时间 (天)');
ylabel('股票价格');
title('使用AR模型对中兴通讯第301-400天的股价预测');
% 后300天
figure;
plot(data(1:400,1),data(:,2),'b-',time, predictions, 'r')
legend('真实股价', '预测股价');
xlabel('时间 (天)');
ylabel('股票价格');
title('使用AR模型对中兴通讯400天的股价预测');
%% 卡尔曼滤波
data1= predictions;
R = 1;
Q = 0.1;
A = 1;
C = 1;
x_hat_0 = data1(1);
P_0 = 1;
x_hat = x_hat_0;
P = P_0;
% Kalman filter
for i = 2:100
% Predict the next state
x_hat_minus = A * x_hat;
P_minus = A * P * A' + Q;
% Update the state estimate using the measurement
K = P_minus * C' / (C * P_minus * C' + R);
x_hat = x_hat_minus + K * (data1(i) - C * x_hat_minus);
P = (1 - K * C) * P_minus;
% Store the estimated state
estimated_states(i) = x_hat;
end
time = 302:400;
figure;
plot(time, data1(2:100), 'b', time, estimated_states(2:100), 'r');
legend('AR模型预测的第301到400天的股价', 'AR模型+卡尔曼滤波得到的第301到400天的股价');
xlabel('时间 (天)');
ylabel('股价');
title('AR模型预测的股价加入卡尔曼滤波');
figure;
plot(data(1:400,1),data(:,2),'b-',time, estimated_states(2:100), 'r','linewidth',1)
legend('真实股价', 'AR+卡尔曼滤波预测股价');
xlabel('时间 (天)');
ylabel('股票价格');
title('AR模型+卡尔曼滤波对中兴通讯第301-400天的股价预测');