承上一篇: python:pykalman 卡尔曼滤波
去除 predict 方法,增加10日移动均线
希望移除代码中所有和 predict 相关的逻辑,同时在股票分析中增加10日移动均线(MA10),让图表同时展示收盘价、卡尔曼滤波股价和10日移动均线,更全面地分析股价趋势。
一、修改后的完整代码
python
# -*- coding: utf-8 -*-
""" 让图表同时展示收盘价、卡尔曼滤波股价和 10日移动均线,分析股价趋势 """
import tushare as ts
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from pykalman import KalmanFilter
import warnings
warnings.filterwarnings('ignore') # 忽略无关警告
# ---------------------- 1. 初始化tushare并获取A股数据 ----------------------
# 替换为你的tushare token
ts.set_token('your_tushare_token')
pro = ts.pro_api()
# 获取300308 中际旭创 近1年的日线数据
ticker = "300308.SZ"
start_date = "20250101"
end_date = "20260213"
# 获取日线数据
df = pro.daily(
ts_code=ticker,
start_date=start_date,
end_date=end_date,
adj='qfq' # 前复权,保证股价连续性
)
# 数据预处理:tushare返回的数据是倒序,需按日期升序排列
df['trade_date'] = pd.to_datetime(df['trade_date'], format='%Y%m%d')
df = df.sort_values('trade_date').reset_index(drop=True)
# 提取收盘价和日期(A股核心字段与美股不同)
close_price = df['close'].values # A股收盘价字段是close
dates = df['trade_date'] # 交易日期
# 检查数据是否获取成功
if len(df) == 0:
print(" 数据获取失败,请检查token有效性或日期范围!")
else:
print(f" 成功获取 {ticker} 共 {len(df)} 条日线数据")
# ---------------------- 2. 构建卡尔曼滤波器(移除predict相关逻辑) ----------------------
# 初始化卡尔曼滤波参数(针对A股波动特点微调)
transition_mat = np.array([[1]]) # 状态转移矩阵
observation_mat = np.array([[1]]) # 观测矩阵
transition_cov = np.array([[0.02]]) # 过程噪声
observation_cov = np.array([[1.5]]) # 观测噪声
initial_mean = np.array([close_price[0]]) # 初始状态均值
initial_cov = np.array([[1]]) # 初始状态协方差
# 初始化卡尔曼滤波器
kf = KalmanFilter(
transition_matrices=transition_mat,
observation_matrices=observation_mat,
transition_covariance=transition_cov,
observation_covariance=observation_cov,
initial_state_mean=initial_mean,
initial_state_covariance=initial_cov
)
# 对收盘价进行滤波(平滑降噪)
state_means, state_covariances = kf.filter(close_price)
# ---------------------- 3. 计算10日移动均线(MA10) ----------------------
# 整合数据并计算MA10
result = pd.DataFrame({
"Date": dates,
"Original_Close": close_price,
"Kalman_Smoothed": state_means.flatten()
}).set_index("Date")
# 计算10日移动均线(rolling(10):滚动窗口10天,mean():取均值)
result['MA10'] = result['Original_Close'].rolling(window=10).mean()
# ---------------------- 4. 数据可视化(新增MA10展示) ----------------------
# 绘制A股股价对比图(适配中文显示)
plt.rcParams['font.sans-serif'] = ['SimHei'] # 解决中文显示问题
plt.rcParams['axes.unicode_minus'] = False # 解决负号显示问题
plt.figure(figsize=(12, 6))
# 原始收盘价
plt.plot(result["Original_Close"], label="原始收盘价", color="gray", alpha=0.6)
# 卡尔曼滤波后股价
plt.plot(result["Kalman_Smoothed"], label="卡尔曼滤波后股价", color="#FF4500", linewidth=2)
# 10日移动均线
plt.plot(result["MA10"], label="10日移动均线", color="#1E90FF", linewidth=1.5, linestyle="--")
plt.title(f"{ticker} 中际旭创 股价分析(卡尔曼滤波,10日移动均线)", fontsize=14)
plt.xlabel("日期", fontsize=12)
plt.ylabel("价格(元)", fontsize=12)
plt.legend(fontsize=10)
plt.grid(True, alpha=0.3)
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()
# ---------------------- 5. A股交易信号生成(保留,可结合MA10优化) ----------------------
# 逻辑:滤波股价上穿原始股价=买入信号,下穿=卖出信号(A股T+1,信号仅作参考)
result["Signal"] = 0
# 买入信号:当前滤波值>原始值 且 前一刻滤波值<=原始值
result.loc[(result["Kalman_Smoothed"] > result["Original_Close"]) &
(result["Kalman_Smoothed"].shift(1) <= result["Original_Close"].shift(1)),
"Signal"] = 1
# 卖出信号:当前滤波值<原始值 且 前一刻滤波值>=原始值
result.loc[(result["Kalman_Smoothed"] < result["Original_Close"]) &
(result["Kalman_Smoothed"].shift(1) >= result["Original_Close"].shift(1)),
"Signal"] = -1
# 输出交易信号(仅展示前10条)
signal_dates = result[result["Signal"] != 0]
print("\n 交易信号汇总(1=买入,-1=卖出):")
if len(signal_dates) > 0:
print(signal_dates[["Original_Close", "Kalman_Smoothed", "MA10", "Signal"]].tail(10))
else:
print("暂无交易信号")
# 输出关键统计信息
print(f"\n 关键数据统计:")
print(f"卡尔曼滤波股价均值:{result['Kalman_Smoothed'].mean():.2f} 元")
print(f"10日移动均线最新值:{result['MA10'].iloc[-1]:.2f} 元")
print(f"最新收盘价:{result['Original_Close'].iloc[-1]:.2f} 元")
二、关键修改点解释
-
完全移除predict相关逻辑:
- 删除了所有
predicted_mean、predicted_cov的计算和输出; - 代码中不再有任何和"预测下一交易日股价"相关的内容,聚焦于现有股价的滤波和均线分析。
- 删除了所有
-
新增10日移动均线(MA10)计算:
- 使用
pandas的rolling(window=10).mean()方法:rolling(10)表示取连续10天的滚动窗口,mean()计算窗口内的均值,这是计算移动均线的标准方法; - MA10的结果存储在
result['MA10']列中,前9行因窗口不足会显示NaN(正常现象)。
- 使用
-
可视化优化:
- 图表中新增MA10的展示,用蓝色虚线(
#1E90FF+linestyle="--")区分,和卡尔曼滤波的红色实线、原始股价的灰色实线形成清晰对比; - 标题更新为包含"10日移动均线"的描述,更贴合分析内容。
- 图表中新增MA10的展示,用蓝色虚线(
-
输出信息补充:
- 交易信号表格中新增
MA10列,方便对比信号出现时的均线位置; - 新增"关键数据统计"模块,输出卡尔曼滤波股价均值、MA10最新值、最新收盘价,便于快速掌握核心数据。
- 交易信号表格中新增
三、使用说明
- MA10的特点:前9行数据为
NaN,从第10行开始才有有效数值,这是滚动窗口计算的正常结果,无需处理; - 可灵活调整均线周期:如果想计算5日/20日均线,只需将
window=10改为window=5/window=20即可; - 信号优化(可选):你可以基于"卡尔曼滤波股价 + MA10"构建更精准的信号,比如"卡尔曼滤波股价上穿MA10"作为买入信号。
总结
- 核心改动:移除所有
predict相关逻辑,新增rolling(window=10).mean()计算10日移动均线; - 可视化:图表同时展示原始股价、卡尔曼滤波股价、10日移动均线,趋势对比更直观;
- 实用性:保留了交易信号生成逻辑,且补充了关键统计数据,分析维度更完整。
