一、项目简介

本文利用Python对股票历史行情数据进行时间序列分析,完成数据清洗、多维度可视化(均线走势、K 线图、成交量、涨跌幅分布),并分别使用线性回归ARIMA 时间序列模型实现收盘价预测,对比两种模型效果。

环境:Jupyter Notebook / Python 3.8+ 数据源:本地 Excel 股票行情数据(包含日期、开盘价、收盘价、最高价、最低价、成交量、涨跌幅、5/10/20 日均线等字段)

二、环境依赖安装

运行代码前,先安装所需第三方库,复制执行:

bash

运行

# 数据分析、绘图、Excel读取
pip install pandas numpy matplotlib openpyxl
# 交互式K线图
pip install pyecharts
# 机器学习、时间序列模型
pip install scikit-learn statsmodels

三、完整代码实现

3.1 导入库 + 读取并预处理数据

解决 Matplotlib 中文乱码、负号显示问题,读取 Excel 数据并做日期转换、排序、字段筛选。

python

运行

# 导入数据分析与绘图库
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# 解决图表中文、负号显示异常
plt.rcParams["font.family"] = "SimHei"
plt.rcParams["axes.unicode_minus"] = False

# 读取Excel股票数据(修改为你的文件路径)
df = pd.read_excel("D:\LXY\股价数据.xlsx")
# 查看前5行数据
df.head()

# 查看数据基本信息、缺失值
df.info()
df.isnull().sum()

# 1. 将日期列转为标准时间格式
df['date'] = pd.to_datetime(df['date'])
# 2. 按时间升序排序(时间序列必须保证时序正确)
df.sort_values(by='date', inplace=True)
# 3. 保留核心分析字段
df = df[['date', 'open', 'close', 'high', 'low', 'volume', 'p_change', 'ma5', 'ma10', 'ma20']]
# 4. 重置索引
df.reset_index(drop=True, inplace=True)
df.head()

3.2 绘制收盘价 + 5/10/20 日均线走势图

直观查看股价整体走势与均线趋势:

python

运行

plt.figure(figsize=(14,6))
# 绘制收盘价与三条均线
plt.plot(df['date'], df['close'], label='收盘价')
plt.plot(df['date'], df['ma5'], label='5日均线', linestyle='--')
plt.plot(df['date'], df['ma10'], label='10日均线', linestyle='--')
plt.plot(df['date'], df['ma20'], label='20日均线', linestyle='--')

# 图表美化
plt.grid(alpha=0.3)
plt.legend()
plt.title('收盘价与均线')
plt.show()

3.3 基于 pyecharts 绘制交互式 K 线图

K 线是股票分析核心图表,支持缩放、下载、还原等交互操作:

python

运行

from pyecharts.charts import Kline
from pyecharts import options as opts

# 构造K线数据:[开盘, 收盘, 最高, 最低]
y = df[['open','close','high','low']].values.tolist()

# 构建K线图
kline = (
    Kline()
    .add_xaxis(df['date'].tolist())
    .add_yaxis('K线图', y)
    .set_global_opts(
        title_opts=opts.TitleOpts(title='股票K线图'),
        toolbox_opts=opts.ToolboxOpts(is_show=True)  # 开启工具箱
    )
)
# Jupyter中直接展示;普通py文件使用 kline.render("股票K线图.html")
kline.render_notebook()

3.4 绘制成交量柱状图

分析成交量变化规律:

python

运行

plt.figure(figsize=(14,6))
plt.bar(df['date'], df['volume'])
plt.title('成交量柱状图')
plt.show()

3.5 绘制涨跌幅分布直方图

统计每日涨跌幅分布,红色虚线区分涨跌分界:

python

运行

plt.figure(figsize=(14,6))
# 绘制涨跌幅直方图,分为40个区间
plt.hist(df['p_change'], bins=40)
# 绘制涨跌分界线(0轴)
plt.axvline(0, color='red', linestyle='--', label='跌涨分界线')
plt.legend()
plt.title('涨跌幅直方图')
plt.show()

3.6 构造特征 + 划分训练集 / 测试集

构建滞后特征(前一日收盘价),按照时间顺序划分数据集(时序数据禁止随机打乱):

python

运行

# 构造滞后特征:前一日收盘价
df["close_lag1"] = df["close"].shift(1)
# 删除因偏移产生的空值
df = df.dropna()

# 按8:2划分训练集、测试集
split = int(len(df) * 0.8)
train = df.iloc[:split]
test = df.iloc[split:]

# 定义特征列与预测标签
feature_cols = ["close_lag1", "open", "ma5"]
X_train = train[feature_cols]
y_train = train["close"]
X_test = test[feature_cols]
y_test = test["close"]

# 输出数据集大小
print(f"训练集: {len(train)} 条 | 测试集: {len(test)} 条")

3.7 模型评估通用函数

封装 MAE、RMSE、R² 三大回归评价指标,复用至两个模型:

python

运行

from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score

def eval_model(y_true, y_pred):
    """模型评估函数"""
    mae = mean_absolute_error(y_true, y_pred)
    rmse = np.sqrt(mean_squared_error(y_true, y_pred))
    r2 = r2_score(y_true, y_pred)
    print(f"MAE(平均绝对误差): {mae:.2f}")
    print(f"RMSE(均方根误差): {rmse:.2f}")
    print(f"R²(拟合度): {r2:.2f}")

3.8 线性回归模型预测股价

使用线性回归做收盘价预测,并可视化真实值与预测值:

python

运行

from sklearn.linear_model import LinearRegression

# 初始化并训练模型
lr = LinearRegression()
lr.fit(X_train, y_train)

# 测试集预测
y_pred_lr = lr.predict(X_test)

# 模型评估
print("==== 线性回归模型评估 ====")
eval_model(y_test, y_pred_lr)

# 可视化:真实值 VS 预测值
plt.figure(figsize=(14, 6))
plt.plot(test["date"], y_test, label="真实收盘价", linewidth=2)
plt.plot(test["date"], y_pred_lr, label="线性回归预测", linestyle="--")
plt.title("线性回归预测结果")
plt.xlabel("日期")
plt.ylabel("股价")
plt.legend()
plt.grid(alpha=0.3)
plt.show()

3.9 ARIMA 时间序列模型滚动预测

采用滚动一步预测方式,适配经典时间序列预测场景:

python

运行

from statsmodels.tsa.arima.model import ARIMA

# 初始化历史数据与预测列表
history = list(train["close"])
predictions = []

# 滚动预测:逐行预测,动态更新历史数据
for i in range(len(test)):
    # ARIMA(p,d,q) = (10,1,0)
    model = ARIMA(history, order=(10,1,0))
    model_fit = model.fit()
    # 预测未来1个时间步
    yhat = model_fit.forecast()[0]
    predictions.append(yhat)
    # 将当日真实值加入历史数据集
    history.append(test["close"].iloc[i])

# 转为数组
y_pred_arima = np.array(predictions)

# 模型评估
print("\n==== ARIMA模型评估 ====")
eval_model(y_test, y_pred_arima)

# 可视化ARIMA预测效果
plt.figure(figsize=(14, 6))
plt.plot(test["date"], y_test, label="真实收盘价", linewidth=2)
plt.plot(test["date"], y_pred_arima, label="ARIMA预测", linestyle="--", color="orange")
plt.title("ARIMA时间序列预测结果")
plt.xlabel("日期")
plt.ylabel("股价")
plt.legend()
plt.grid(alpha=0.3)
plt.show()

四、结果分析

  1. 数据可视化

    • 均线图可清晰观察短期、中期、长期股价趋势;
    • K 线图支持交互式查看单日行情,是股票分析主流图表;
    • 成交量与涨跌幅分布可以辅助判断市场活跃度与涨跌规律。
  2. 模型效果对比

    • 线性回归:MAE、RMSE 更低,R² 接近 0.98,拟合效果优秀,运算速度快;
    • ARIMA 模型:纯基于历史收盘价做时序预测,R² 为 0.97,效果略逊于线性回归,单步滚动预测耗时更长。
  3. 总结 针对该股票数据集,结合多特征的线性回归预测表现更优;纯时序 ARIMA 模型适合仅依赖历史序列、无额外特征的场景。

更多推荐