Ptrade 框架的 data 对象解析
1. 什么是 data 对象
在 ptrade 量化交易框架中,handle_data(context, data) 是策略的核心回调函数之一。data 是一个 BarDict(字典容器)对象,包含了当前时间点的市场数据。
def handle_data(context, data):
# data 是 BarDict 类型
print(type(data)) # <class 'IQEngine.plugins.plugin_fly_data.local_variables.bar.BarDict'>2. BarDict 对象结构
从调试输出可以看到:
BarDict 类的方法和属性:
- __class__ # 类类型
- __contains__ # 支持 'in' 操作符
- __delattr__ # 删除属性
- __dir__ # 列出所有可用属性
- __doc__ # 文档字符串
- __eq__ # 相等比较
- __format__ # 格式化
- __ge__ # 大于等于比较
- __getattribute__ # 获取属性
- __getitem__ # 支持 [] 访问,如 data[security]
- __getstate__ # 序列化状态
- __gt__ # 大于比较
- __hash____ # 哈希值
- __init__ # 初始化
- __le__ # 小于等于比较
- __len__ # 支持 len() 获取长度
- __lt__ # 小于比较
- __module__ # 模块信息
- __ne__ # 不等比较
- __new__ # 创建实例
- __reduce__ # 序列化
- __reduce_ex__ # 序列化
- __repr__ # 字符串表示
- __setattr__ # 设置属性
- __sizeof__ # 对象大小
- __str__ # 字符串转换
- _cache # 内部缓存
- _dt # 时间信息
- _engine # 引擎引用
- _frequency # 频率信息
- dt # 当前bar的时间戳
- items # 字典的 items() 方法
- keys # 字典的 keys() 方法
- start_date_tmp # 起始时间
- update_dt # 更新时间
- values # 字典的 values() 方法3. BarData 对象(单个证券的数据)
当你通过 data[security] 访问单个证券时,得到的是 BarData 对象:
bar = data['600570.SS']
# bar 的类型: <class 'IQEngine.plugins.plugin_fly_data.local_variables.bar.BarData'>3.1 BarData 包含的字段
字段名 | 类型 | 说明 | 示例值 |
|---|---|---|---|
| datetime | 当前bar的时间戳 |
|
| int | 是否开盘(1=是,0=否) |
|
| float | 成交额(单位:元) |
|
| float | 前收盘价 |
|
| float | 当前价格 |
|
| float | 收益率(本期/上期-1) |
|
| str | 证券代码 |
|
3.2 调试输出示例
=== 600570.SS ===
类型: <class 'IQEngine.plugins.plugin_fly_data.local_variables.bar.BarData'>
dt: 2026-04-14 13:46:00
is_open: 1
money: nan
pre_close: 26.69
price: 26.57
returns: -0.0044960659423005245
sid: 600570.SS4. 常用访问方法
4.1 获取所有证券代码
def handle_data(context, data):
# 方法1: 使用 keys()
securities = data.keys()
print(list(securities)) # ['600570.SS']
# 方法2: 使用 len()
print(len(data)) # 证券数量
# 方法3: 使用 in 检查是否存在
if '600570.SS' in data:
print("600570.SS 存在")4.2 获取单个证券数据
def handle_data(context, data):
# 方法1: 直接使用证券代码访问
bar = data['600570.SS']
# 方法2: 先检查存在性再访问
if '600570.SS' in data:
bar = data['600570.SS']
# 方法3: 遍历所有证券
for security in data.keys():
bar = data[security]
print(f"{security}: {bar.price}")4.3 遍历所有证券数据
def handle_data(context, data):
# 方法1: 遍历 items()
for security, bar in data.items():
print(f"证券: {security}")
print(f"价格: {bar.price}")
print(f"时间: {bar.dt}")
# 方法2: 遍历 keys() 再访问
for security in data.keys():
bar = data[security]
print(f"{security}: {bar.price}")5. 实际使用示例
5.1 基础价格获取
def initialize(context):
g.security = "600570.SS"
set_universe(g.security)
def handle_data(context, data):
bar = data[g.security]
# 获取当前价格
current_price = bar.price
# 获取前收盘价
prev_close = bar.pre_close
# 获取收益率
returns = bar.returns
# 计算涨跌幅
if prev_close > 0:
change_pct = (current_price - prev_close) / prev_close
print(f"涨跌幅: {change_pct:.2%}")
# 获取时间
current_time = bar.dt
print(f"当前时间: {current_time}")5.2 多证券组合
def initialize(context):
g.securities = ["600570.SS", "510300.SS"]
set_universe(g.securities)
def handle_data(context, data):
for security in g.securities:
if security in data:
bar = data[security]
print(f"{security}: 价格={bar.price}, 收益率={bar.returns:.2%}")5.3 价格异常检测
def handle_data(context, data):
bar = data[g.security]
# 检测价格是否有效
if bar.price > 0 and bar.pre_close > 0:
change_pct = abs(bar.price - bar.pre_close) / bar.pre_close
# 涨幅超过5%报警
if change_pct > 0.05:
print(f"价格异常波动: {change_pct:.2%}")6. 常见问题
Q1: money 字段是 nan?
# 答:部分bar数据可能没有成交额,特别是:
# 1. 分钟级数据可能不提供money字段
# 2. 特定证券在某些时段没有成交
# 建议添加判断
if bar.money and not math.isnan(bar.money):
print(f"成交额: {bar.money}")
else:
print("成交额数据不可用")Q2: 如何判断是否开盘?
# 使用 is_open 字段
if bar.is_open == 1:
print("当前处于交易时段")
else:
print("当前非交易时段(如停牌、涨跌停等)")7. 完整调试代码
如果想查看 data 对象的所有可用信息,可以使用以下调试代码:
def handle_data(context, data):
print("=" * 60)
print(f"data 类型: {type(data)}")
print(f"data keys: {list(data.keys())}")
for security, bar in data.items():
print(f"\n--- {security} ---")
print(f" dt: {bar.dt}")
print(f" price: {bar.price}")
print(f" pre_close: {bar.pre_close}")
print(f" returns: {bar.returns}")
print(f" is_open: {bar.is_open}")
print(f" money: {bar.money}")
print(f" sid: {bar.sid}")
# 计算涨跌幅
if bar.pre_close > 0:
change = (bar.price - bar.pre_close) / bar.pre_close
print(f" 涨跌幅: {change:.2%}")
print("=" * 60)8. 总结
概念 | 说明 |
|---|---|
BarDict | data 参数的类型,类似于字典 |
BarData | 单个证券的数据对象 |
访问方式 |
|
核心字段 |
|
提示: 在使用前养成检查字段是否为
nan或None的习惯,避免计算错误。

全部 0条评论