问题描述
解决方案
在 PTrade 策略系统的 handle_data(context, data) 函数中,data 参数是一个非常核心的数据对象。它是一个**字典(Dictionary)**类型的对象,用于存储当前回测或交易周期(如一分钟或一天)内的行情数据。
以下是关于 data 参数的详细结构、包含的属性以及使用方法的说明:
1. 数据结构
- 类型:字典 (
dict) - 键 (Key):标的代码(字符串
str),例如'600570.SS'。 - 值 (Value):
SecurityUnitData对象。该对象包含了对应标的在当前时间切片(Bar)内的具体行情数据。
2. 包含的属性 (SecurityUnitData)
当你通过 data['股票代码'] 获取到一个标的的数据对象后,该对象包含以下属性:
| 属性名 | 类型 | 说明 | 备注 |
|---|---|---|---|
| open | float | 开盘价 | 当前周期(日/分钟)的开始价格 |
| close | float | 收盘价 | 当前周期(日/分钟)的结束价格 |
| high | float | 最高价 | 当前周期内的最高价格 |
| low | float | 最低价 | 当前周期内的最低价格 |
| volume | float | 成交量 | 当前周期的成交数量(单位:股) |
| money | float | 成交额 | 当前周期的成交金额(单位:元) |
| price | float | 最新价 | 当前周期的最新价格(通常等于 close) |
| dt | datetime | 时间 | 当前数据对应的时间戳 |
3. 使用示例
以下代码展示了如何在 handle_data 中读取 data 参数里的各种数据:
def initialize(context):
# 设置我们要操作的股票池
g.security = '600570.SS'
set_universe(g.security)
def handle_data(context, data):
# 1. 获取标的代码
security = g.security
# 2. 检查该标的当前是否有数据(防止停牌或未上市导致报错)
if security in data:
# 获取该标的的 SecurityUnitData 对象
stock_data = data[security]
# 3. 访问具体属性
current_price = stock_data['price'] # 获取最新价
current_open = stock_data['open'] # 获取开盘价
current_close = stock_data['close'] # 获取收盘价
current_high = stock_data['high'] # 获取最高价
current_low = stock_data['low'] # 获取最低价
current_vol = stock_data['volume'] # 获取成交量
# 打印日志查看
log.info("股票: %s, 时间: %s, 最新价: %f, 成交量: %f" % (
security,
stock_data['dt'],
current_price,
current_vol
))
# 简单策略示例:如果收盘价大于开盘价(阳线),则买入
if current_close > current_open:
order(security, 100)
4. 重要注意事项
- 数据范围:
data中只包含股票池(Universe)中的标的数据。如果你没有在initialize或before_trading_start中使用set_universe()设置股票池,或者设置的股票在当天停牌,data中可能不会包含该股票的数据。 - 访问方式:虽然文档提到值是对象,但在 PTrade 的实际使用惯例中,通常支持以字典键值对的方式访问属性(如
data['600570.SS']['close']),也支持对象属性访问(如data['600570.SS'].close),建议优先使用字典方式访问以保持兼容性。 - 周期依赖:
- 如果是日线回测,
data包含的是当天的日线数据(OHLCV)。 - 如果是分钟回测,
data包含的是当前这一分钟的分钟线数据。
- 如果是日线回测,
- Tick 级别:
handle_data不处理 Tick 级别的高频切片数据(Tick 数据需使用tick_data函数处理),但在handle_data中获取的price通常是该周期的最新快照价格。
Q&A 常见问题解答
Q1: handle_data 中的 data 和 get_history 获取的数据有什么区别?
A: data 仅包含当前这一个时间点(当前分钟或当天)的切片数据,主要用于实时判断。而 get_history 用于获取过去一段时间的历史序列数据(如过去5天的收盘价),主要用于计算均线、MACD 等技术指标。
Q2: 如果股票停牌了,data 里会有数据吗?
A: 通常情况下,如果股票全天停牌,data 字典中可能不会包含该股票的 key,或者其数据状态不可用。因此在实盘或回测代码中,建议先判断 if security in data: 再进行取值,以避免 KeyError 错误。
Q3: data 里的 volume 单位是什么?
A: 单位是股(Shares),而不是手。例如,如果成交了 1 手,volume 的值通常是 100。
Q4: 可以在 handle_data 以外的地方使用这个 data 对象吗?
A: 不可以。data 是 handle_data 函数的局部参数,仅在该函数运行时由系统传入。如果在其他函数(如 before_trading_start)需要行情数据,应使用 get_price 或 get_snapshot 等 API 主动获取。