文章前言
本文分上下两篇完整讲解 PTrade 平台set_universe函数,从基础固定股票池到每日自动切换行业股票池实战,覆盖静态、动态两种主流使用场景,附带完整可运行代码、回测日志、踩坑注意事项与投资风险提示,新手看完即可上手使用。
一、函数核心概念:策略专属「股票关注清单」
1. 核心作用
set_universe()是 PTrade 内置基础函数,核心功能:限定策略需要加载、读取数据的股票范围。 生活化类比: 购物前写好购物清单,超市只找清单商品;量化策略仅加载清单内个股行情,过滤全市场冗余数据,提升运行速度、简化日志输出。
2. 底层关键特性
该函数仅用于设置get_history()接口默认读取的股票列表,非强制调用函数;不使用该函数时,调用行情接口必须手动传入股票代码列表。
二、基础语法与两种调用时机
1. 基础语法
入参仅支持股票代码列表,格式规范:沪市.SS、深市.SZ
# 示例:固定3只金融股作为股票池 stock_list = ["600036.SS", "601318.SS", "601988.SS"] set_universe(stock_list)2. 两种调用场景
- initialize () 初始化函数(静态固定池)策略启动一次性设定股票池,全程不更换,适合长期持有固定个股策略。
- before_trading_start () 盘前函数(动态轮动池)每个交易日开盘前刷新股票池,适合行业轮动、每日选股策略。
三、实战场景 1:静态固定股票池(上篇基础案例)
需求
策略启动后固定观测工商银行、建设银行,每根 K 线输出实时收盘价,仅处理清单内标的。
完整代码
def initialize(context): # 全局变量存储固定股票池 g.my_stocks = ["601398.SS", "601939.SS"] # 设置全局观测股票池 set_universe(g.my_stocks) print(f"策略启动,关注股票:工商银行、建设银行") def handle_data(context, data): # 格式化当前时间 current_time = context.current_dt.strftime("%H:%M") print(f"\n{current_time}的价格:") # 遍历股票池打印行情 for stock in g.my_stocks: price = data[stock].close stock_name = "工商银行" if stock == "601398.SS" else "建设银行" print(f"{stock_name}: {price}元")回测输出日志示例
INFO - INFO - 工商银行: 7.5元 INFO - 建设银行: 8.89元 INFO - INFO - 工商银行: 7.46元 INFO - 建设银行: 8.95元 INFO - INFO - 工商银行: 7.63元 INFO - 建设银行: 9.19元 INFO - 正在进行回测统计数据汇总 INFO - 回测统计数据汇总完成 INFO - 回测结束,结束类型: 程序结束 策略回测结束场景优势
仅加载 2 只股票数据,计算量小、日志干净,不会出现全市场海量无关数据干扰。
四、实战场景 2:动态每日切换股票池(下篇进阶案例)
需求
按星期自动切换行业股票池:周一银行、周二石油、周三银行、周四白酒、周五保险,无需手动修改代码,盘前自动更新set_universe。
完整可运行代码
def initialize(context): # 预先定义每周对应股票池,0=周一,4=周五 g.weekly_stocks = { 0: ["601398.SS", "601939.SS"], # 周一 银行 1: ["601857.SS", "600028.SS"], # 周二 石油 2: ["600000.SS", "601166.SS"], # 周三 银行 3: ["600519.SS", "600809.SS"], # 周四 白酒 4: ["601318.SS", "601628.SS"] # 周五 保险 } # 股票代码-中文名映射字典 g.stock_names = { "601398.SS": "工商银行", "601939.SS": "建设银行", "601857.SS": "中国石油", "600028.SS": "中国石化", "600000.SS": "浦发银行", "601166.SS": "兴业银行", "600519.SS": "贵州茅台", "600809.SS": "山西汾酒", "601318.SS": "中国平安", "601628.SS": "中国人寿" } def before_trading_start(context, data): # 获取当日交易日,提取星期(0周一~4周五) today = get_trading_day() weekday = today.weekday() # 赋值当日股票池 g.today_stocks = g.weekly_stocks[weekday] # 更新全局观测股票池 set_universe(g.today_stocks) # 打印当日关注标的 names = [g.stock_names[code] for code in g.today_stocks] print(f"今天是周{weekday+1},关注股票:{names[0]}、{names[1]}") def handle_data(context, data): current_time = context.current_dt.strftime("%H:%M") for stock in g.today_stocks: price = data[stock].close name = g.stock_names[stock] print(f"{current_time} {name}价格:{price}元")回测日志效果展示
INFO - 今天是周4,关注股票:贵州茅台、山西汾酒 INFO - 15:00 贵州茅台价格:1436.78元 INFO - 15:00 山西汾酒价格:190.39元 INFO - 今天是周5,关注股票:中国平安、中国人寿 INFO - 15:00 中国平安价格:55.54元 INFO - 15:00 中国人寿价格:39.66元 INFO - 今天是周1,关注股票:工商银行、建设银行 INFO - 15:00 工商银行价格:7.27元 INFO - 15:00 建设银行价格:8.7元适用场景
行业轮动策略、分日期观测不同板块,无需人工修改代码,全自动切换观测范围。
五、高频踩坑注意事项
- 不使用 set_universe 的隐患未调用函数时,直接通过
data[股票代码]读取行情大概率报错,系统无对应股票数据缓存;等同于没有购物清单,无法快速调取目标商品。 - 股票代码格式严禁写错沪市 60 开头后缀
.SS,深市 00/30 开头后缀.SZ,代码后缀错误会直接找不到个股数据,策略运行异常。 - 动态池更新位置规范每日换股逻辑必须放在
before_trading_start盘前函数,不要放在handle_data内频繁重复调用,避免重复加载数据拖慢策略。 - 股票池数量控制股票池标的越多,数据加载耗时越长,无需求个股及时剔除,优化策略运行效率。
六、投资风险提示
- 本文全部代码仅为 PTrade 函数语法教学演示,历史回测结果不代表未来实盘收益,A 股存在股价波动、行业政策、宏观经济、流动性等多重投资风险。
- 本文仅为 Python 量化编程技术科普,不构成任何个股买卖、仓位配置投资建议,入市有风险,投资需谨慎。
七、总结
set_universe核心作用总结三个字:划范围。
- 静态固定标的:
initialize内一次性设置; - 动态轮动选股:
before_trading_start每日更新; 使用该函数可精简日志、减少数据报错、提升策略运行效率,是 PTrade 量化基础必学函数。