问题描述
解决方案
在 PTrade 量化交易平台中,get_price 和 get_history 都是用于获取历史行情数据(K线数据)的核心函数,但它们在时间维度的定义方式和使用场景上有显著的区别。
以下是详细的对比解释:
1. 核心区别
| 特性 | get_history |
get_price |
|---|---|---|
| 时间基准 | 相对时间 (以当前时刻为基准) | 绝对时间 (指定具体的日期范围) |
| 核心参数 | count (获取过去多少根K线) |
start_date / end_date (开始与结束日期) |
| 数据定位 | 获取截止到“当前回测/交易时间”往前推 N 条数据 | 获取指定历史时间段(如 2022-01-01 到 2022-02-01)的数据 |
| 主要用途 | 策略运行中:计算技术指标(如 MA, MACD) | 研究/初始化:获取特定历史区间数据、补全数据 |
2. 函数详解与应用场景
A. get_history (获取最近 N 条历史数据)
功能描述:
该函数用于获取截止到当前策略运行时间点之前的 N 条历史数据。它是一个“向后看”的函数,非常适合在策略循环运行过程中(如 handle_data)动态获取最新的历史窗口。
主要参数:
count: 需要获取的 K 线数量(必填)。frequency: 周期(如 '1d', '1m')。include: 是否包含当前这根未走完的 K 线(默认为 False)。
应用场景:
- 计算滚动技术指标:例如在
handle_data中,每天需要获取过去 5 天的收盘价来计算 5日均线 (MA5)。 - 策略逻辑判断:判断过去 N 天是否连续上涨。
代码示例:
def handle_data(context, data):
# 获取过去 5 天的收盘价(不包含今天)
# 场景:计算 5日均线
his = get_history(count=5, frequency='1d', field='close', security_list='600570.SS')
ma5 = his.mean()
log.info(f"5日均线: {ma5}")
B. get_price (获取指定时间段数据)
功能描述:
该函数用于获取指定开始日期和结束日期之间的数据,或者指定结束日期往前推 N 条的数据。它更像是一个静态的数据查询工具。
主要参数:
start_date: 开始时间(如 '20230101')。end_date: 结束时间(如 '20230131')。count: 数量(注意:start_date和count不能同时使用)。
应用场景:
- 研究环境:在编写策略前的研究阶段,拉取某一段特定历史行情进行分析。
- 策略初始化:在
initialize或before_trading_start中,获取大盘或某只股票在过去一年的表现作为基准对比。 - 获取特定日期数据:比如需要查询 2015 年股灾期间某只股票的表现。
代码示例:
def initialize(context):
# 获取 2022年1月1日 到 2022年1月31日 的数据
# 场景:研究或计算长期静态指标
df = get_price('600570.SS', start_date='20220101', end_date='20220131', frequency='1d')
log.info(df)
3. 总结与建议
- 如果你在写
handle_data或tick_data函数,需要根据最新的行情动态计算指标(如“金叉死叉”、“突破20日高点”),请务必使用get_history。它是随时间推进而滑动的窗口。 - 如果你在 研究界面 (Notebook) 进行数据分析,或者在策略开始前需要加载一段固定的历史数据进行预处理,请使用
get_price。
Q&A
Q: get_history 能获取当前正在进行的这根 K 线数据吗?
A: 默认情况下 include=False,不包含当前 K 线。如果设置 include=True,则会包含当前这根尚未结束的 K 线数据(即包含最新的 tick 撮合生成的临时 K 线)。
Q: get_price 的数据包含 end_date 当天吗?
A: get_price 返回的数据不包括查询时指定的 end_date 当天的数据(如果是盘中调用且 end_date 为今日)。但在回测历史数据时,通常包含该区间内的已结数据。具体需注意 API 文档中关于“数据返回内容不包括当天数据”的说明(视具体调用环境而定)。
Q: 为什么在 handle_data 中不建议用 get_price?
A: 虽然可以用,但 get_price 需要你手动计算日期的偏移(例如手动计算“今天”的前10天是哪一天),而 get_history 直接通过 count=10 自动处理了日历和非交易日的逻辑,使用起来更加简便且不易出错。