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

数据获取——免费的金融数据源大全

没有数据,你的策略只是空想;有了数据,AI才能帮你把想法变成现实

🎯 本章学习目标

欢迎来到量化交易的"弹药库"章节。如果把量化策略比作一辆赛车,那么数据就是它的燃料——没有燃料,再强的引擎也只能原地轰鸣。读完这一章,你将能够:

💬 一个真实的故事

小李是个量化新手,刚学完Python基础,兴致勃勃地想要回测一个"双均线金叉策略"。他打开Backtrader,写好策略逻辑,运行代码——结果报错了。原来,他根本没有数据。

他打开搜索引擎,输入"股票数据免费下载",结果跳出一堆广告:有的是收费的,有的需要注册复杂的API,有的数据格式乱七八糟。折腾了一整天,他终于从某个论坛下载了一份CSV文件,结果发现数据只到2022年,而且缺少成交量列。

小李气得差点放弃。他打开ChatGPT,问:"我需要一个免费的A股历史数据源,要求有日线数据,包含OHLCV,最好能直接用在Python里。"AI给了他三个选项:Tushare、AKShare和Yahoo Finance。半小时后,他已经拿到了贵州茅台从2010年至今的完整日线数据。

这个故事告诉我们:数据获取是量化交易的第一步,也是最让人头疼的一步。但有了AI的帮助,这个过程可以从"一天"缩短到"半小时"。

核心洞察:数据获取的本质不是"找数据",而是"建立一条从原始数据到策略引擎的自动化流水线"。一旦这条流水线搭好,后面的一切都会顺畅很多。

⚡ 核心知识:数据获取全景图

1. 为什么数据如此重要?

在量化交易的世界里,有一句话被反复提及:"Garbage in, garbage out"(垃圾进,垃圾出)。如果你的数据有错误、有缺失、有延迟,那么无论你的策略多么精妙,结果都可能是灾难性的。

数据质量问题的常见表现包括:价格跳空缺失(某些交易日没有数据)、复权错误(分红送股后价格没有正确调整)、时间戳混乱(不同数据源的时间格式不一致)、成交量异常(某天的成交量突然变成0或者巨大无比)。这些问题在回测中可能不明显,但一旦上实盘,就会让你付出真金白银的代价。

但好消息是,对于初学者来说,免费的金融数据已经足够支撑你学习和小规模研究。你不需要花几千块钱买Wind或者Bloomberg,先把手头能拿到的免费数据用好,才是正经事。

2. 免费数据源全景对比

下面的表格整理了目前最主流的免费金融数据源。你可以把它当成"数据采购指南",根据自己的需求对号入座。

数据源覆盖市场数据类型获取方式限制推荐指数
TushareA股、港股、美股、基金日线、分钟线、财务数据Python API积分制,高频数据需付费⭐⭐⭐⭐⭐
AKShareA股、期货、期权、宏观日线、实时行情、基本面Python API部分接口不稳定⭐⭐⭐⭐
Yahoo Finance美股、港股、A股(ADR)日线、分钟线、财务数据yfinance库A股数据有延迟⭐⭐⭐⭐
JoinQuant(聚宽)A股日线、分钟线、财务数据平台内置需注册,数据不能导出⭐⭐⭐
BaostockA股日线、复权数据Python API数据更新较慢⭐⭐⭐
CCXT加密货币现货、合约K线Python API各交易所限制不同⭐⭐⭐⭐

3. 数据获取流程:从需求到落地

很多人在获取数据时犯的第一个错误是:上来就写代码。正确的流程应该是"先规划,后执行"。下面是一个标准化的数据获取流程,你可以把它当成 checklist 来用。

flowchart LR A[明确数据需求] --> B[选择数据源] B --> C[获取API密钥] C --> D[下载数据] D --> E[数据清洗] E --> F[质量检查] F --> G[存储数据] G --> H[策略使用] style A fill:#f97316,stroke:#fff,color:#fff style H fill:#06b6d4,stroke:#fff,color:#fff

第一步:明确数据需求。你需要回答几个问题:我要交易什么市场?需要日线还是分钟线?需要哪些字段(开盘价、收盘价、成交量等)?数据要回溯到什么时候?这些问题决定了你选哪个数据源。

第二步:选择数据源。如果你做A股,首选Tushare或AKShare;如果你做美股,Yahoo Finance是最简单的;如果你做加密货币,CCXT几乎覆盖了所有主流交易所。

第三步:获取API密钥。大部分免费数据源都需要注册账号并获取API Token。这一步通常只需要5分钟,但很多人会卡在这里——别怕,AI可以一步步教你。

第四步:下载数据。用Python调用API,把数据拉取到本地。这里要注意频率限制,不要一股脑发太多请求,否则会被封IP。

第五步:数据清洗。这是最容易被忽视但最关键的步骤。你需要处理缺失值、调整复权价格、统一时间格式、去除异常值。

第六步:质量检查。用简单的统计方法检查数据是否合理。比如,检查是否有某天的收盘价为0,或者成交量突然暴增100倍。

第七步:存储数据。清洗后的数据要保存到合适的位置。对于小规模数据,CSV就够了;对于大规模数据,建议使用Parquet或HDF5格式。

4. 数据质量:免费数据的"坑"与"避坑指南"

免费数据虽然香,但也有一些常见的坑。作为一个负责任的量化学习者,你必须知道这些坑在哪里,以及如何避开它们。

🤖 与AI一起练习

练习1:让AI帮你选择数据源

Prompt模板:

我想做A股量化交易,策略是双均线交叉,需要日线数据(OHLCV),
时间范围是2020年至今。请推荐3个免费数据源,并对比它们的:
1. 数据覆盖范围
2. 获取难度
3. 数据质量
4. 使用限制
请以表格形式输出。

练习2:让AI帮你写数据获取代码

Prompt模板:

请用Python写一段代码,使用AKShare获取贵州茅台(600519)
从2020年1月1日到今天的日线数据,要求:
1. 包含前复权价格
2. 保存为CSV文件
3. 处理可能的缺失值
4. 添加一列"涨跌幅"
请给出完整可运行的代码,并逐行解释。

练习3:让AI诊断数据质量问题

Prompt模板:

我下载了一份股票数据,怀疑其中有质量问题。
请写一个Python函数,自动检测以下问题:
1. 缺失的交易日
2. 收盘价为0或负数的情况
3. 成交量异常(单日成交量超过均值10倍)
4. 涨跌幅超过±20%的情况(非ST股票)
函数应该返回问题清单和对应的行号。

🔧 动手实践:编写你的第一个数据获取脚本

光说不练假把式。下面是一段完整的Python代码,展示了如何用yfinance获取美股数据、用AKShare获取A股数据,并进行基础的数据清洗和质量检查。

PYTHON data_downloader.py
import pandas as pd
import akshare as ak
import yfinance as yf
from datetime import datetime, timedelta
import numpy as np

# ==========================================
# 第一部分:获取A股数据(使用AKShare)
# ==========================================

def get_a_stock_data(stock_code, start_date, end_date):
    """
    获取A股历史日线数据(前复权)
    stock_code: 如 "600519"(贵州茅台)
    """
    print(f"正在获取 {stock_code} 的数据...")
    
    # 使用AKShare获取数据
    df = ak.stock_zh_a_hist(
        symbol=stock_code,
        period="daily",
        start_date=start_date.replace("-", ""),
        end_date=end_date.replace("-", ""),
        adjust="qfq"  # qfq = 前复权
    )
    
    # 重命名列,统一格式
    df.columns = ['date', 'open', 'close', 'high', 'low', 'volume', 
                  'amount', 'amplitude', 'pct_change', 'change_amount', 'turnover']
    
    # 转换日期格式
    df['date'] = pd.to_datetime(df['date'])
    df.set_index('date', inplace=True)
    
    print(f"获取完成,共 {len(df)} 条记录")
    return df

# 获取贵州茅台2020年至今的数据
maotai = get_a_stock_data("600519", "2020-01-01", "2024-12-31")
print(maotai.head())

# ==========================================
# 第二部分:获取美股数据(使用yfinance)
# ==========================================

def get_us_stock_data(ticker, period="5y"):
    """
    获取美股历史数据
    ticker: 如 "AAPL", "TSLA", "SPY"
    """
    print(f"正在获取 {ticker} 的数据...")
    
    stock = yf.Ticker(ticker)
    df = stock.history(period=period)
    
    # yfinance返回的列名已经是标准格式
    # 只保留我们需要的列
    df = df[['Open', 'High', 'Low', 'Close', 'Volume']]
    df.columns = ['open', 'high', 'low', 'close', 'volume']
    
    print(f"获取完成,共 {len(df)} 条记录")
    return df

# 获取苹果公司5年数据
apple = get_us_stock_data("AAPL")
print(apple.head())

# ==========================================
# 第三部分:数据质量检查
# ==========================================

def check_data_quality(df, stock_name="Unknown"):
    """
    检查数据质量,返回问题报告
    """
    issues = []
    
    # 1. 检查缺失值
    missing = df.isnull().sum()
    if missing.any():
        issues.append(f"发现缺失值: \n{missing[missing > 0]}")
    
    # 2. 检查零值或负值的价格
    price_cols = ['open', 'high', 'low', 'close']
    for col in price_cols:
        if col in df.columns:
            invalid = df[df[col] <= 0]
            if len(invalid) > 0:
                issues.append(f"{col} 有 {len(invalid)} 条非正值记录")
    
    # 3. 检查成交量异常
    if 'volume' in df.columns:
        mean_vol = df['volume'].mean()
        extreme = df[df['volume'] > mean_vol * 10]
        if len(extreme) > 0:
            issues.append(f"发现 {len(extreme)} 条成交量异常记录(超过均值10倍)")
    
    # 4. 检查价格连续性(是否有跳空缺失)
    if len(df) > 1:
        # 计算相邻交易日的间隔
        if isinstance(df.index, pd.DatetimeIndex):
            gaps = df.index.to_series().diff().dt.days
            # A股通常间隔1-3天(周末+节假日)
            long_gaps = gaps[gaps > 5]
            if len(long_gaps) > 0:
                issues.append(f"发现 {len(long_gaps)} 个超过5天的数据缺口")
    
    # 5. 检查涨跌幅异常
    if 'close' in df.columns:
        daily_return = df['close'].pct_change()
        extreme_moves = daily_return[abs(daily_return) > 0.2]
        if len(extreme_moves) > 0:
            issues.append(f"发现 {len(extreme_moves)} 天涨跌幅超过20%")
    
    # 输出报告
    print(f"\n{'='*40}")
    print(f"数据质量报告: {stock_name}")
    print(f"{'='*40}")
    print(f"总记录数: {len(df)}")
    print(f"日期范围: {df.index[0]} 至 {df.index[-1]}")
    print(f"发现问题数: {len(issues)}")
    
    if issues:
        for i, issue in enumerate(issues, 1):
            print(f"\n问题 {i}: {issue}")
    else:
        print("\n数据质量良好,未发现明显问题!")
    
    return len(issues) == 0

# 运行质量检查
check_data_quality(maotai, "贵州茅台(600519)")
check_data_quality(apple, "苹果(AAPL)")

# ==========================================
# 第四部分:保存数据
# ==========================================

def save_data(df, filename):
    """保存数据到CSV"""
    df.to_csv(filename)
    print(f"\n数据已保存至: {filename}")

save_data(maotai, "maotai_daily.csv")
save_data(apple, "apple_daily.csv")

print("\n✅ 全部完成!你现在可以用这些数据来运行策略了。")

运行这段代码,你会得到两个CSV文件,分别包含贵州茅台和苹果公司的历史日线数据。更重要的是,你建立了一套"获取-检查-保存"的标准化流程,以后每获取一个新数据,都可以复用这套流程。

交互式数据获取模拟器

在下面这个模拟器中,你可以体验不同参数对数据获取结果的影响。虽然它不会真的去下载数据,但可以帮助你理解各个参数的含义。

🤔 思考题

知识自测
1. 以下哪种情况最可能导致回测结果失真?
  • A. 使用了前复权数据
  • B. 使用了不包含停牌日的数据
  • C. 使用了不复权数据进行长线回测
  • D. 数据时间范围太短
答案是C。不复权数据在遇到分红送股时会出现价格跳空,导致均线等技术指标计算错误,从而使策略信号完全失真。前复权数据是回测的标准做法;停牌日缺失通常影响较小;数据时间范围短会降低统计显著性,但不会直接导致信号失真。
2. Tushare的积分制是什么意思?
  • A. 积分越高,数据质量越好
  • B. 积分是用来排名的,不影响使用
  • C. 积分越高,可以访问的数据接口越多
  • D. 积分需要花钱买,没有免费获取途径
答案是C。Tushare采用积分制来管理API访问权限:基础数据(日线行情)只需要很少积分或零积分;高频数据、财务数据等高级接口需要更多积分。积分可以通过注册、邀请好友、贡献代码等方式免费获取,不是必须购买的。
3. 如果你要同时回测A股和美股策略,最佳的数据获取方案是?
  • A. 只用Tushare,因为它数据最全
  • B. 只用Yahoo Finance,因为它最简单
  • C. A股用AKShare/Tushare,美股用Yahoo Finance
  • D. 手动从财经网站复制粘贴
答案是C。不同数据源有各自的优势领域:Tushare和AKShare在A股数据上最全面准确,Yahoo Finance在美股数据上最便捷。混合使用可以发挥各自优势。手动复制粘贴效率极低且容易出错,完全不可取。
深入思考
  1. 如果你发现某只股票在某一天的成交量为0,但价格有变化,可能是什么原因?应该如何处理?
  2. 为什么加密货币的数据获取比股票更复杂?交易所之间的价格差异会带来什么问题?
  3. 假设你有一份2015-2024年的数据,但发现2020年3月有一段数据缺失(正好是新冠崩盘期间),这对你的策略回测会有什么影响?

🚀 下一章预告

数据已经到手,但你真的会用AI来帮你处理数据吗?下一章《AI Prompt工程——如何让AI听懂你的交易逻辑》,我们将彻底告别"AI听不懂我说话"的困境。

你将学会:如何写出高质量的Prompt,让AI一次就生成你需要的代码;如何避免"差Prompt生成bug代码,好Prompt生成完美代码"的尴尬;以及一套实用的"量化Prompt模板库",以后每次写Prompt直接套模板就行。

如果你曾经对着AI输入"帮我写个量化策略",然后看着它生成一堆不知所云的代码发呆——下一章就是为你准备的。

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

上一章
第9章:Backtrader——用对话的方式理解回测框架
理解Backtrader的核心概念和工作流程,运行你的第一个回测。
下一章
第11章:AI Prompt工程——如何让AI听懂你的交易逻辑
掌握与AI协作编写量化代码的核心技巧,写出高质量的Prompt。

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

赞赏二维码