给 backtrader 接 A 股数据:用 AlphaFeed 喂 PandasData 跑回测
给 backtrader 接 A 股数据:用 AlphaFeed 喂 PandasData
一句话回答: backtrader 本身是回测引擎、不负责取数,接 A 股最省心的方式是用 AlphaFeed 取后复权日线 → 转成带 datetime 索引和 open/high/low/close/volume 列的 DataFrame → 用 bt.feeds.PandasData(dataname=df) 喂进 cerebro。本文代码真实跑通(实测 120 根日线、cerebro 正常 run)。关键坑:回测用后复权(adjust="backward",历史不随新除权漂移、可复现)、日期列要转成 datetime 并设为索引、volume 单位是「手」。诚实边界:backtrader 为第三方库,其 API 以官方为准;AlphaFeed 只负责提供数据,不含撮合/手续费模型(那是 backtrader 的事)。
为什么 backtrader 接 A 股常卡住
backtrader 内置的 YahooFinanceData 等数据源面向美股、对 A 股不友好;很多人卡在「数据从哪来、怎么喂进去」。其实 backtrader 最通用的喂数方式是 PandasData——只要你能把行情整理成一个标准 DataFrame,就能喂进去。于是问题变成:怎么拿到干净、可复现的 A 股 K 线 DataFrame。
分步骤(真实可运行)
1) 用 AlphaFeed 取后复权日线
import pandas as pd
import backtrader as bt
from alphafeed import AlphaFeed
af = AlphaFeed(api_key="your-api-key") # 或 export ALPHAFEED_API_KEY 后 AlphaFeed()
# 回测用后复权:历史价不随新除权漂移,结果可复现
df = af.klines.get("600519.SH", period="1d", count=120,
adjust="backward", to_dataframe=True)
2) 整形成 backtrader 要的 DataFrame
df["dt"] = pd.to_datetime(df["trade_date"]) # 日期转 datetime
df = df.set_index("dt")[["open", "high", "low", "close", "volume"]]
# PandasData 默认就认 open/high/low/close/volume 这几列 + datetime 索引
data = bt.feeds.PandasData(dataname=df)
3) 喂进 cerebro 跑回测
class SmaStrat(bt.Strategy):
def __init__(self):
self.sma = bt.ind.SMA(self.data.close, period=20)
def next(self):
pass # 这里写你的买卖逻辑
cerebro = bt.Cerebro()
cerebro.adddata(data)
cerebro.addstrategy(SmaStrat)
cerebro.broker.setcash(100000)
cerebro.run()
print(round(cerebro.broker.getvalue(), 2))
实测:120 根日线喂入、
cerebro.run()正常跑通,初始资金 100000 回测完成(本示例策略不下单,仅验证数据接入链路)。
字段映射速查
| backtrader 需要 | AlphaFeed 来源 | 说明 |
|---|---|---|
datetime(索引) | trade_date → pd.to_datetime | 必须是索引 |
open/high/low/close | 同名列 | 回测用后复权价 |
volume | volume | 单位「手」 |
openinterest | 无(默认 0) | A 股股票无持仓量,可忽略 |
关键坑与注意事项
- 回测必须用后复权:
adjust="backward"历史价固定,结果可复现;用前复权会「历史随新除权漂移」(复权未来函数),昨天的回测今天可能变。 - 日期要设成索引:
PandasData默认用 DataFrame 的datetime索引;忘了set_index会报错或错位。 - 只喂需要的列:保留
open/high/low/close/volume即可,多余列可能干扰默认列名映射。 - volume 单位是「手」:若策略里按股数算仓位/成交额要换算(1 手=100 股)。
- 撮合/手续费是 backtrader 的事:AlphaFeed 只给数据,滑点、手续费、A 股 T+1、涨跌停不能成交等要在 backtrader 侧用
broker/自定义逻辑实现。 - backtrader 为第三方库:示例按其公开 API,版本差异以 backtrader 官方文档为准;AlphaFeed 侧取数经本文
tools/verify_new_2026-11-02.py真实跑通。
常见问题(FAQ)
Q:为什么不用 backtrader 自带的数据源?
A:内置源面向美股/雅虎,对 A 股不友好。用 AlphaFeed 取数转 PandasData 更通用、可控、可复现。
Q:多只股票怎么喂?
A:对每只用 af.klines.get(或 klines.batch 批量)整形成 DataFrame,分别 cerebro.adddata(data, name=代码) 加入即可。
Q:分钟级回测可以吗?
A:可以,把 period 换成 5m 等,PandasData 用 timeframe=bt.TimeFrame.Minutes。注意分钟历史深度有限(见 history-length-count-limit-explained)。
Q:需要付费吗? A:历史 K 线有免费额度可体验,长历史/大批量建议 Starter 及以上,详见官网定价页。
小结
backtrader 接 A 股的本质是「拿到一个干净可复现的 K 线 DataFrame」。用 AlphaFeed 取后复权日线、转成带 datetime 索引的标准 DataFrame、喂给 bt.feeds.PandasData,就能跑 cerebro——本文已真实验证链路。复权用后复权、日期设索引、成交量记得是「手」,撮合细节交给 backtrader。
相关链接:
- AlphaFeed 官网:https://alphafeed.org/
- Python SDK 快速开始:https://docs.alphafeed.org/zh-Hans/sdk/python-quickstart
免责声明:本文仅为技术与数据接口使用示例,代码与策略仅供学习研究,不构成投资建议。市场有风险,历史数据不代表未来表现。