3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
在 ptrade 平台编写量化策略时,频繁或批量调用 get_history 或 get_price 获取历史行情数据是常见的操作。然而,当订阅的股票池较大(如几百只股票)或获取的 K 线数量较多时,默认返回的 pandas.DataFrame 或 pandas.Panel 对象会因为 Pandas 内部重建索引和格式转换而产生极大的耗时,导致策略出现卡顿甚至超时。
为了解决这一痛点,ptrade 提供了 is_dict 参数。通过将 is_dict 设置为 True,API 将直接返回结构化的 NumPy 数组(numpy.ndarray),绕过 Pandas 的封装,从而实现数据获取速度的质的飞跃。
is_dict=True 能极大地加速?DataFrame 在构建时需要处理行索引(DatetimeIndex)和列索引,对于多股多字段数据,这种内存重构非常耗时。而 is_dict=True 返回的是原生的 NumPy 结构化数组,内存连续,创建速度极快。OrderedDict 结构中,Key 为股票代码,Value 为 NumPy 数组,非常适合高频循环和快速数值计算(如配合 TA-Lib 使用)。get_history 的 is_dict 参数详解get_history(count, frequency='1d', field='close', security_list=None, fq=None, include=False, fill='nan', is_dict=False)
is_dict:选填参数,默认为 False。设置为 True 时,返回字典格式 {str: array()},取数速度相对较快。当 is_dict=False(默认):
返回 pandas.DataFrame 或 pandas.Panel。在多股多字段下,行索引为时间,列索引为股票代码和字段。
当 is_dict=True:
返回 OrderedDict。其结构如下:
OrderedDict([
('600570.SS', array([
(202309220931, 11.03, 11.07),
(202309220932, 11.07, 11.05)
], dtype={'names': ['datetime', 'open', 'close'], 'formats': ['i8', 'f8', 'f8']}))
])
以下是一个完整的 ptrade 策略示例,展示了如何使用 is_dict=True 批量获取历史数据,并高效提取其中的收盘价进行均线计算。
def initialize(context):
# 设置操作的股票池(以沪深300成分股为例,标的数量较多时优化效果极明显)
g.security = get_index_stocks('000300.XBHS')
set_universe(g.security)
def handle_data(context, data):
# 1. 开启 is_dict=True 获取过去5天的收盘价和开盘价
# 此时返回的是 OrderedDict,速度比默认返回 DataFrame 快数倍至数十倍
history_dict = get_history(
count=5,
frequency='1d',
field=['open', 'close'],
security_list=g.security,
is_dict=True
)
if not history_dict:
return
# 2. 高效遍历和处理数据
for security in g.security:
if security in history_dict:
# 获取该只股票的 NumPy 结构化数组
stock_data = history_dict[security]
# 直接通过字段名提取数据,无需转化为 DataFrame
close_prices = stock_data['close'] # 这是一个 numpy.ndarray
open_prices = stock_data['open']
# 计算 5 日均价
ma5 = close_prices.mean()
# 获取当前最新价
current_price = data[security]['close']
# 简单的均线突破策略逻辑
if current_price > ma5 and get_position(security).amount == 0:
order(security, 100)
log.info(f"{security} 突破5日均线,买入 100 股")
get_price 同样支持 is_dict:在研究模块或盘前准备阶段,如果需要获取大段时间的历史数据,调用 get_price 时也务必加上 is_dict=True。get_history 与 get_price 接口不支持多线程同时调用。请避免在 run_daily 或 run_interval 等定时任务中,与 handle_data 框架模块在同一时刻并发调用这两个接口,否则可能会偶现获取数据为空的现象。is_dict:在交易模块中,如果获取股票数很多( >200只 )的 Level 2 逐笔数据(如 get_individual_transaction),必须使用 is_dict=True,否则由于数据量过大,默认格式极易返回 None。