问题描述
import jqfactor
import pandas as pd
import jqdata
from jqlib.technical_analysis import *
def initialize(context):
#设定沪深300作为基准
set_benchmark('000300.XSHG')
#开启动态复权模式(真实价格)
set_option('use_real_price',True)
#输出内容到日志 log.info()
log.info('初始函数开始运行切全局只运行一次')
g.security =['300901.XSHE','000001.XSHE']
run_daily(period,time = 'every_bar')
def period(context):
security=g.security
q = get_bars(security, count=36, unit='1M',fields=('low'),include_now=True,end_dt=context.current_dt,fq_ref_date= context.current_dt.date(),df=True)
print(q)
for qq in q:
qq = q.min()
print(qq)
各位大神,怎么提取多种股票的最低价, 我只能打出所有的一起比较最低价,怎么不是那样一个股票一个最低价的,好烦躁!
解决方案
在 JoinQuant 聚宽平台上,当你使用 get_bars 函数并传入多个股票代码且设置 df=True 时,返回的是一个带有 MultiIndex(多重索引) 的 pandas DataFrame。直接对这个 DataFrame 调用 .min() 会计算整个列的最小值,而不是按股票分别计算。
要分别提取每只股票的最低价,有两种推荐的解决方法:
方法一:使用 df=False 返回字典格式(推荐,更简单高效)
当设置 df=False 时,get_bars 会返回一个字典,键(key)是股票代码,值(value)是包含数据的 numpy 数组。这样遍历起来非常直观:
import jqdata
def initialize(context):
set_benchmark('000300.XSHG')
set_option('use_real_price', True)
log.info('初始函数开始运行且全局只运行一次')
g.security = ['300901.XSHE', '000001.XSHE']
# 建议按天运行,而不是 every_bar,避免分钟级别重复打印
run_daily(period, time='09:30')
def period(context):
security = g.security
# 设置 df=False,返回字典
q = get_bars(security, count=36, unit='1M', fields=['low'],
include_now=True, end_dt=context.current_dt,
fq_ref_date=context.current_dt.date(), df=False)
# 遍历字典,分别获取每只股票的最低价
for stock in security:
# q[stock] 是一个 numpy 数组,包含 'low' 字段
stock_low_data = q[stock]['low']
min_low = stock_low_data.min()
print(f"股票 {stock} 过去36个月的最低价是: {min_low}")
方法二:使用 df=True 并利用 pandas 的 groupby 分组计算
如果你坚持要使用 DataFrame 格式,可以通过 pandas 的 groupby 方法,按照索引中的股票代码层级(通常是 level 0)进行分组,然后再求最小值:
import jqdata
import pandas as pd
def initialize(context):
set_benchmark('000300.XSHG')
set_option('use_real_price', True)
log.info('初始函数开始运行且全局只运行一次')
g.security = ['300901.XSHE', '000001.XSHE']
run_daily(period, time='09:30')
def period(context):
security = g.security
# 设置 df=True,返回 MultiIndex DataFrame
q = get_bars(security, count=36, unit='1M', fields=['low'],
include_now=True, end_dt=context.current_dt,
fq_ref_date=context.current_dt.date(), df=True)
# q 的 index 是 MultiIndex,第一层级 (level=0) 是股票代码
# 使用 groupby 按股票代码分组,然后求最小值
min_lows = q.groupby(level=0)['low'].min()
print("各股票的最低价如下:")
print(min_lows)
# 如果你想遍历打印
for stock, min_val in min_lows.items():
print(f"股票 {stock} 的最低价是: {min_val}")
总结与建议
- 数据结构理解:处理多标的数据时,一定要清楚 API 返回的数据结构。
get_bars多标的df=True返回的是 MultiIndex DataFrame,不能像单标的那样直接操作。 - 性能优化:在量化回测中,尽量使用
df=False获取 numpy 数组或字典,因为 pandas DataFrame 的构建和操作在大量循环中会显著拖慢回测速度。 - 运行频率:你的代码中使用了
time='every_bar',如果是分钟回测,每分钟都会去获取过去36个月的数据并计算,这非常耗时且没有必要。建议改为time='09:30'每天开盘计算一次即可。