3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
在 PTrade 中,get_history 的返回类型取决于Python 环境版本(Python 3.5 或 Python 3.11)、查询标的数量以及查询字段的数量。
由于 Pandas 库在更新过程中移除了 Panel 数据结构,导致不同 Python 内核下的表现不一致。
code 列,数据呈“长表”格式(Long Format),需要通过筛选(如 .query)来获取特定股票的数据。is_dict=True为了避免在不同环境(或未来升级)中处理 Panel 和 DataFrame 的差异,强烈建议在调用 get_history 时设置参数 is_dict=True。
这样无论是在 Python 3.5 还是 3.11 中,返回的都将是标准的 Python 字典 (dict),且官方文档指出这种方式取数速度相对较快。
def initialize(context):
g.security = ['600570.SS', '000001.SZ']
set_universe(g.security)
def handle_data(context, data):
# 【推荐方式】强制返回字典,无需关心是 Panel 还是 DataFrame
# 获取过去5天的收盘价和开盘价
history_data = get_history(5, '1d', ['close', 'open'], g.security, is_dict=True)
# 遍历股票池进行处理
for stock in g.security:
if stock in history_data:
# 获取该股票的数据(numpy array格式,包含时间戳和请求的字段)
stock_data = history_data[stock]
# 获取收盘价序列
close_prices = stock_data['close']
# 获取开盘价序列
open_prices = stock_data['open']
# 打印最新一天的收盘价
log.info("股票: %s, 最新收盘价: %f" % (stock, close_prices[-1]))
# 计算均值示例
avg_close = close_prices.mean()
如果您维护的是旧策略,且必须在 Python 3.5 环境下处理多股多字段返回的 Panel 数据,可以使用以下方式进行转换或切片。
def initialize(context):
g.security = ['600570.SS', '000001.SZ']
set_universe(g.security)
def handle_data(context, data):
# 未使用 is_dict=True,在 Py3.5 下多股多字段会返回 Panel
res = get_history(5, '1d', ['close', 'open'], g.security)
# 检查返回类型是否为 Panel (仅在 Py3.5 有效)
import pandas as pd
# 注意:在 Py3.11 中没有 pd.Panel,这里仅作逻辑演示
if isinstance(res, pd.Panel):
# Panel 切片方式:res[字段名][股票代码]
# 获取所有股票的收盘价 DataFrame (行: 时间, 列: 股票代码)
close_df = res['close']
log.info("Panel 转换后的 Close DataFrame:\n%s" % close_df)
# 获取特定股票的收盘价
stock_close = close_df['600570.SS']
# 也可以转换轴,将 Items(字段) 换成股票代码
# 转换后可以通过 res['600570.SS'] 获取该股票的所有字段 DataFrame
res_swapped = res.swapaxes("minor_axis", "items")
stock_df = res_swapped['600570.SS']
log.info("600570.SS 的数据:\n%s" % stock_df)
else:
# Python 3.11 或 单股情况,直接是 DataFrame
# Py3.11 多股返回的 DataFrame 包含 'code' 列
if 'code' in res.columns:
# 使用 query 筛选特定股票
stock_df = res.query('code == "600570.SS"')
log.info("Py3.11 DataFrame 筛选结果:\n%s" % stock_df)
Panel,Python 3.11 返回 DataFrame。Panel 已被 Pandas 官方弃用,代码移植性差。get_history 中使用 is_dict=True。这不仅解决了兼容性问题,还能获得更好的性能。Q: 为什么官方文档推荐使用 is_dict=True?
A: 除了解决版本兼容性问题外,返回字典格式(底层是 Numpy 数组)通常比构建 Pandas DataFrame 或 Panel 开销更小,取数速度相对较快,特别是在高频调用或处理大量数据时。
Q: 如果我在 Python 3.11 中运行旧的 Panel 代码会怎样?
A: 会报错。因为 Python 3.11 配套的 Pandas 版本较高,已经彻底移除了 pd.Panel 类。旧策略迁移到新环境时,必须重写数据获取逻辑,或者改用 is_dict=True。
Q: get_price 接口也有这个问题吗?
A: 是的,get_price 与 get_history 在多股多字段场景下的返回逻辑是一致的。同样建议使用 is_dict=True 参数。