问题描述
使用get_price获取K线数据后发现有停牌日期的数据,应该如何处理?
解决方案
在 ptrade 量化平台中,使用 get_price 或 get_history 接口获取历史 K 线数据时,系统默认不会跳过停牌的日期。对于停牌日,系统会使用停牌前最后一个交易日的数据进行填充,并且当天的成交量(volume)为 0。
因此,要过滤掉停牌日的数据,最简单有效的方法就是剔除成交量为 0 的数据行。
过滤停牌日数据的方法
由于 get_price 返回的数据通常是 pandas.DataFrame 格式(在获取单只股票或多只股票时),你可以直接使用 pandas 的条件过滤功能来剔除停牌日。
示例代码:获取单只股票并过滤停牌日
def initialize(context):
g.security = '600570.SS'
set_universe(g.security)
def handle_data(context, data):
# 获取过去 10 天的日线数据,包含 volume 字段
df = get_price(g.security, count=10, frequency='1d', fields=['open', 'close', 'volume'])
if df is not None and not df.empty:
# 过滤掉成交量为 0 的行(即停牌日)
df_filtered = df[df['volume'] > 0]
log.info("原始数据行数: %s, 过滤后数据行数: %s" % (len(df), len(df_filtered)))
log.info("过滤后的数据:\n%s" % df_filtered)
示例代码:获取多只股票并过滤停牌日
当获取多只股票时,返回的 DataFrame 会包含 code 列(Python 3.11 环境下)。
def initialize(context):
g.security = ['600570.SS', '000001.SZ']
set_universe(g.security)
def handle_data(context, data):
# 获取多只股票的数据
df = get_price(g.security, count=10, frequency='1d', fields=['close', 'volume'])
if df is not None and not df.empty:
# 过滤掉所有成交量为 0 的行
df_filtered = df[df['volume'] > 0]
# 如果需要单独获取某只股票过滤后的数据
df_ss = df_filtered.query('code == "600570.SS"')
log.info("恒生电子过滤后的数据:\n%s" % df_ss)
总结
- 停牌特征:价格数据沿用前一日,
volume(成交量)为 0。 - 处理方案:在请求字段中务必包含
'volume',然后使用df[df['volume'] > 0]进行过滤。 - 适用接口:此逻辑同样适用于
get_history接口获取的数据。