🏠
AI量化交易 · 第5章
目录
Chapter 05

用AI理解市场——价格数据的获取与处理

掌握数据获取和处理的核心技能,为策略开发打下坚实基础

本章学习目标

  1. 了解主流免费和付费数据源的特点与适用场景
  2. 学会使用Python获取股票、指数和基金数据
  3. 掌握数据清洗的核心技能——处理缺失值、异常值和复权问题
  4. 理解前复权与后复权的本质区别及其对策略的影响
  5. 建立"数据质量决定策略质量"的核心认知

那个因为数据错误而亏钱的教训

2022年夏天,量化爱好者小陈终于完成了他的第一个策略——"双均线金叉做多"。回测结果非常漂亮:年化收益35%,最大回撤12%。小陈兴奋不已,投入了20万实盘资金。

两个月后,账户亏损了15%。小陈百思不得其解:回测明明很好啊?他开始逐一排查问题,最终在数据环节发现了致命错误:他使用的数据源没有正确处理分红除权

某只股票在他回测期间进行了一次大额分红,股价从50元跳到了45元。他的数据源把这5元的下跌记录为了真实的"价格下跌",策略于是在"大跌"后发出了买入信号。但在实盘中,这根本不是价格下跌,而是除权!

这个教训让小陈深刻理解了量化交易中的一条铁律:Garbage In, Garbage Out(垃圾进,垃圾出)。数据质量是一切的基础,数据错了,再好的策略也是空中楼阁。

核心提醒:数据问题不是技术细节,而是决定策略生死的核心问题。一个小时的细心数据检查,可能避免数万元的实盘亏损。

数据源全景图:从免费到付费

在开始写代码之前,我们需要先了解有哪些数据可以用、从哪里获取。以下是量化交易中常用的数据源对比。

数据源 覆盖市场 费用 数据质量 适用人群
yfinance 美股、ETF 免费 中等 美股初学者
AKShare A股、港股、期货 免费 中等 A股量化初学者
Tushare A股、港股、美股 积分制 较高 进阶A股开发者
Baostock A股 免费 中等 A股初学者
Wind 全市场 付费(昂贵) 极高 机构用户
Choice 全市场 付费 专业个人/小型机构

选择数据源的黄金法则

对于本书的读者,我们建议的学习路径是:

  1. 入门阶段:使用 yfinance(美股)或 AKShare(A股)。免费、易用、社区活跃,遇到问题容易找到答案
  2. 进阶阶段:升级到 Tushare 的积分版。数据更稳定、字段更丰富、支持更多高级接口
  3. 专业阶段:考虑 Wind 或 Choice。当你管理较大资金或需要实时数据时,付费数据源的可靠性值得投资

AI辅助的数据获取

无论你选择哪个数据源,都可以让AI帮你生成获取代码。以下是向AI询问数据获取的标准Prompt模板:

PROMPT
请帮我写一段Python代码,使用[数据源名称]获取[标的名称]
从[开始日期]到[结束日期]的[日线/分钟线]数据。

要求:
1. 数据包含开、高、低、收、成交量五个字段
2. 数据要进行前复权处理
3. 保存为CSV文件,文件名为[文件名]
4. 添加错误处理机制,如果获取失败打印友好提示
5. 代码要有注释,说明每一步在做什么

数据清洗:量化交易中最被低估的技能

获取数据只是第一步。原始数据往往充满问题:缺失值、异常值、格式不统一、时间戳错位……如果不处理这些问题,你的策略将建立在沙地上。

常见问题1:缺失值

缺失值是最常见的问题。原因包括:节假日休市、停牌、数据接口暂时故障等。处理方式取决于缺失值的性质:

常见问题2:异常值

异常值是指明显偏离正常范围的数据点。比如某只股票某天涨幅达到50%(没有涨停限制的市场),或者成交量突然是平时的100倍。

异常值可能是真实的(如重大利好/利空),也可能是数据错误(如小数点错位)。判断方法:

常见问题3:复权处理

这是A股量化中最容易出错的地方。当股票分红、送股、配股时,交易所会调整股价,使其在除权除息日出现"跳空"。如果不处理这种跳空,策略会错误地认为股价真的大跌了。

有两种复权方式:

对于策略回测,强烈建议使用前复权数据。否则,策略会在每次除权后产生错误的交易信号。

graph LR A[原始数据] --> B{是否有缺失?} B -->|是| C[缺失值处理
前向填充/删除] B -->|否| D{是否有异常?} C --> D D -->|是| E[异常值检测
3-sigma/对比验证] D -->|否| F{是否已复权?} E --> F F -->|否| G[复权处理
前复权/后复权] F -->|是| H[清洗完成] G --> H style A fill:#0a0e1a,stroke:#f97316,color:#e8ecf4 style H fill:#0a0e1a,stroke:#06b6d4,color:#e8ecf4 style B fill:#1e293b,stroke:#7b8ba3,color:#c8cfe0 style D fill:#1e293b,stroke:#7b8ba3,color:#c8cfe0 style F fill:#1e293b,stroke:#7b8ba3,color:#c8cfe0 style C fill:#1e293b,stroke:#7b8ba3,color:#c8cfe0 style E fill:#1e293b,stroke:#7b8ba3,color:#c8cfe0 style G fill:#1e293b,stroke:#7b8ba3,color:#c8cfe0
图5-1:数据清洗流程图

与AI一起练习:数据获取与清洗实战

练习1:用AKShare获取A股数据

AKShare是目前最活跃的A股免费数据源之一。以下代码展示了如何获取某只A股的日线数据。

PYTHON
import akshare as ak
import pandas as pd

# 获取贵州茅台的日线数据
# akshare的股票代码格式:去掉后缀的纯数字
stock_code = "600519"
stock_name = "贵州茅台"

print(f"正在获取 {stock_name}({stock_code}) 的历史数据...")

# 使用 akshare 获取日线数据
df = ak.stock_zh_a_hist(
    symbol=stock_code,
    period="daily",
    start_date="20230101",
    end_date="20241231",
    adjust="qfq"  # 前复权
)

print(f"\n✅ 数据获取成功!共 {len(df)} 条记录")
print("\n数据预览:")
print(df.head(10))

# 检查数据质量
print("\n📊 数据质量报告:")
print(f"日期范围: {df['日期'].min()} 至 {df['日期'].max()}")
print(f"缺失值统计:\n{df.isnull().sum()}")
print(f"\n价格范围:")
print(f"  最高: {df['最高'].max():.2f}")
print(f"  最低: {df['最低'].min():.2f}")
print(f"  平均成交量: {df['成交量'].mean():.0f}")

# 保存为CSV
df.to_csv(f"{stock_code}_{stock_name}_daily.csv", index=False, encoding='utf-8-sig')
print(f"\n💾 数据已保存至: {stock_code}_{stock_name}_daily.csv")

练习2:数据清洗实战——异常值检测

获取数据后,我们需要对数据进行质量检查。以下代码实现了自动化的数据质量报告。

PYTHON
import numpy as np

def data_quality_report(df):
    """生成数据质量报告"""
    report = []
    
    # 1. 检查缺失值
    missing = df.isnull().sum()
    if missing.sum() > 0:
        report.append(f"⚠️ 发现缺失值:\n{missing[missing > 0]}")
    else:
        report.append("✅ 无缺失值")
    
    # 2. 检查零成交量
    zero_volume = df[df['成交量'] == 0]
    if len(zero_volume) > 0:
        report.append(f"⚠️ 发现 {len(zero_volume)} 天成交量为0(可能停牌)")
    
    # 3. 检查涨跌幅异常(超过20%的涨跌幅需要关注)
    df['涨跌幅_pct'] = df['收盘'].pct_change() * 100
    extreme_moves = df[abs(df['涨跌幅_pct']) > 20]
    if len(extreme_moves) > 0:
        report.append(f"⚠️ 发现 {len(extreme_moves)} 天涨跌幅超过20%:")
        for _, row in extreme_moves.iterrows():
            report.append(f"   {row['日期']}: {row['涨跌幅_pct']:.2f}%")
    
    # 4. 检查价格逻辑错误(最高价 < 最低价等)
    logic_errors = df[df['最高'] < df['最低']]
    if len(logic_errors) > 0:
        report.append(f"❌ 发现 {len(logic_errors)} 条逻辑错误记录!")
    
    # 5. 检查开盘价是否在开高低范围内
    open_errors = df[(df['开盘'] > df['最高']) | (df['开盘'] < df['最低'])]
    if len(open_errors) > 0:
        report.append(f"❌ 发现 {len(open_errors)} 条开盘价超出范围!")
    
    # 6. 检查收盘价是否在开高低范围内
    close_errors = df[(df['收盘'] > df['最高']) | (df['收盘'] < df['最低'])]
    if len(close_errors) > 0:
        report.append(f"❌ 发现 {len(close_errors)} 条收盘价超出范围!")
    
    # 7. 统计摘要
    report.append(f"\n📈 数据统计摘要:")
    report.append(f"  平均日收益率: {df['涨跌幅_pct'].mean():.3f}%")
    report.append(f"  收益率标准差: {df['涨跌幅_pct'].std():.3f}%")
    report.append(f"  最大单日涨幅: {df['涨跌幅_pct'].max():.2f}%")
    report.append(f"  最大单日跌幅: {df['涨跌幅_pct'].min():.2f}%")
    
    return "\n".join(report)

# 运行质量检查
print(data_quality_report(df))

练习3:让AI帮你调试数据问题

当你遇到数据问题时,最有效的求助方式就是直接把问题描述和数据样本发给AI。

PROMPT
我在获取股票数据时遇到了以下问题:
[描述你的问题,比如"某天的收盘价高于最高价"]

以下是我的数据样本:
[粘贴出问题的几行数据]

以下是我的代码:
[粘贴相关代码]

请帮我:
1. 分析问题的原因
2. 给出修复代码
3. 建议如何预防类似问题

这个Prompt模板几乎可以解决80%的数据问题。关键是提供足够的信息:问题描述、数据样本、相关代码。信息越完整,AI的诊断越准确。


动手实践:建立你的数据工作流

现在,轮到你了。请完成以下任务,建立属于你自己的数据获取和清洗工作流。

数据工作流搭建任务
  1. 选择数据源:根据你关注的股票市场,选择合适的数据源(A股推荐AKShare,美股推荐yfinance)
  2. 获取数据:下载3只你感兴趣的股票最近两年的日线数据
  3. 运行质量检查:使用上面的data_quality_report函数检查数据质量
  4. 处理缺失值:如果发现缺失值,用合适的方法处理(前向填充或删除)
  5. 验证复权:检查数据中是否包含分红除权事件,确认复权处理是否正确
  6. 保存清洗后的数据:将清洗后的数据保存为CSV,作为后续策略开发的"原料"

建立标准化的数据工作流,是专业量化交易者和业余玩家的重要区别。每次获取数据都按同样的流程检查,可以避免90%的数据问题。


思考题

自测环节
1. 为什么量化回测中必须使用复权数据?
  • A. 复权数据看起来更美观
  • B. 除权会导致价格跳空,不复权会产生错误的交易信号
  • C. 交易所要求必须使用复权数据
  • D. 复权数据更容易获取
解析:分红、送股等除权事件会导致股价在除权日出现"跳空下跌"。如果不进行复权处理,策略会误以为股价真的下跌了,从而产生错误的买入信号。前复权以当前价格为基准调整历史价格,是回测的标准做法。
2. 数据清洗中发现某只股票连续5天成交量为0,最可能的原因是什么?
  • A. 市场崩盘,没人交易
  • B. 数据接口故障
  • C. 该股票停牌
  • D. 计算错误
解析:连续多日成交量为0最常见的原因是股票停牌(如因重大事项、重组、退市整理等)。也有可能是数据接口问题,但如果是连续多天且其他股票正常,停牌的可能性最大。处理方式是直接排除该时间段的数据。
3. "Garbage In, Garbage Out"在量化交易中的含义是?
  • A. 输入数据质量差,无论策略多么精妙,输出结果也不会好
  • B. 垃圾数据应该直接删除
  • C. 只有付费数据才是好数据
  • D. 数据清洗是浪费时间
解析:这是计算机科学的一句名言,在量化交易中尤为重要。如果输入的历史数据有错误(如未复权、缺失值处理不当、包含未来函数等),那么即使你的策略逻辑再完美,回测结果也是误导性的。数据质量是策略质量的基石。
动手思考题
  1. 找一只你持有的股票,下载它过去一年的日线数据,运行数据质量检查。你发现了什么问题?
  2. 对比前复权和后复权的数据,计算同一时间段的总收益率。两种复权方式的结果是否相同?为什么?
  3. 思考:如果你用未复权的数据回测一个"跌破20日均线卖出"的策略,除权事件会对策略产生什么影响?

下一章预告
你是哪种交易者?——交易风格自我诊断
数据基础已经打好。在进入具体策略之前,我们需要先回答一个重要问题:你适合什么样的交易风格?是追求高胜率的小额止盈,还是承受大回撤博取超额收益?是日内交易的快节奏,还是趋势跟踪的耐心等待?下一章,我们将通过一个互动测试,帮你找到最适合自己的量化交易风格。

觉得有收获?分享给同样对量化交易感兴趣的朋友

上一章
K线图背后的故事——价格是如何形成的
理解市场价格形成机制,读懂K线图的语言
下一章
你是哪种交易者?——交易风格自我诊断
找到最适合自己的量化交易风格

如果这本书对你有所启发,欢迎支持我继续创作

赞赏二维码