python:pykalman 卡尔曼滤波, 与10日移动均线比较

承上一篇: 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} 元")

二、关键修改点解释

  1. 完全移除predict相关逻辑

    • 删除了所有 predicted_meanpredicted_cov 的计算和输出;
    • 代码中不再有任何和"预测下一交易日股价"相关的内容,聚焦于现有股价的滤波和均线分析。
  2. 新增10日移动均线(MA10)计算

    • 使用 pandasrolling(window=10).mean() 方法:rolling(10) 表示取连续10天的滚动窗口,mean() 计算窗口内的均值,这是计算移动均线的标准方法;
    • MA10的结果存储在 result['MA10'] 列中,前9行因窗口不足会显示 NaN(正常现象)。
  3. 可视化优化

    • 图表中新增MA10的展示,用蓝色虚线(#1E90FF + linestyle="--")区分,和卡尔曼滤波的红色实线、原始股价的灰色实线形成清晰对比;
    • 标题更新为包含"10日移动均线"的描述,更贴合分析内容。
  4. 输出信息补充

    • 交易信号表格中新增 MA10 列,方便对比信号出现时的均线位置;
    • 新增"关键数据统计"模块,输出卡尔曼滤波股价均值、MA10最新值、最新收盘价,便于快速掌握核心数据。

三、使用说明

  1. MA10的特点:前9行数据为 NaN,从第10行开始才有有效数值,这是滚动窗口计算的正常结果,无需处理;
  2. 可灵活调整均线周期:如果想计算5日/20日均线,只需将 window=10 改为 window=5/window=20 即可;
  3. 信号优化(可选):你可以基于"卡尔曼滤波股价 + MA10"构建更精准的信号,比如"卡尔曼滤波股价上穿MA10"作为买入信号。

总结

  1. 核心改动:移除所有 predict 相关逻辑,新增 rolling(window=10).mean() 计算10日移动均线;
  2. 可视化:图表同时展示原始股价、卡尔曼滤波股价、10日移动均线,趋势对比更直观;
  3. 实用性:保留了交易信号生成逻辑,且补充了关键统计数据,分析维度更完整。
相关推荐
赵谨言2 小时前
基于Python的汽车CAN总线报文格式转换系统的设计与实现
大数据·开发语言·经验分享·笔记·python
坚持就完事了2 小时前
Python各种命名规则
开发语言·python
郝学胜-神的一滴2 小时前
Python中的del语句与垃圾回收机制深度解析
服务器·开发语言·网络·python·算法
DanCheng-studio2 小时前
信息安全毕设易上手课题怎么选
python·毕业设计·毕设
DanCheng-studio2 小时前
毕设开源 大数据B站数据分析与可视化
python·毕业设计·毕设
那个松鼠很眼熟w2 小时前
python fastapi 快速创建web应用
python·fastapi
速易达网络2 小时前
AI学习路径 python到openclaw
人工智能·python·学习
Java后端的Ai之路2 小时前
在一个 Python 脚本中导入另一个脚本的功能
服务器·开发语言·python
SeatuneWrite2 小时前
**手机专业写剧本软件哪家可靠2025推荐,适配多场景创作与
人工智能·python·智能手机