问题描述
例如
def init(C):
stockList = ['000001.SZ', '000002.SZ', '000004.SZ', '000006.SZ']
C.set_universe(stockList)
def handlebar(C):
universe = C.get_universe()
print(universe)
结果是:['000006.SZ', '000001.SZ', '000002.SZ', '000004.SZ']
为什么和 stockList 的顺序不一样? 请教了。谢谢
解决方案
您好!出现 get_universe() 获取的股票池顺序与 set_universe() 设置时不一致的情况,主要是由 QMT 底层的数据存储机制 决定的。
为什么顺序会发生改变?
QMT 平台的底层是使用 C++ 编写的。为了保证股票池中股票代码的唯一性以及提高底层数据的检索和处理效率,QMT 底层在接收到 set_universe 传入的列表后,通常会将其存储在类似 Set(集合)或 Hash Set(哈希集合)的数据结构中。
集合(Set)这种数据结构的一个核心特性就是无序性(或者按照哈希值、内部树结构排序)。因此,当您调用 C.get_universe() 时,底层是将集合中的元素重新打包成 Python 的 list 返回给您,这个返回的顺序是底层集合遍历的顺序,而不是您最初传入时的插入顺序。
解决方案:如何保持股票的特定顺序?
如果您在编写策略时,后续的逻辑严格依赖于股票列表的初始顺序,建议您不要依赖 get_universe() 的返回顺序,而是在 Python 层面自己维护一个全局列表。
您可以利用 ContextInfo 对象可以自由挂载自定义属性的特点,将原始列表保存下来。示例如下:
#coding:gbk
def init(C):
# 原始的股票列表,有特定的顺序
stockList = ['000001.SZ', '000002.SZ', '000004.SZ', '000006.SZ']
# 1. 设置给底层系统,用于驱动行情和获取历史数据
C.set_universe(stockList)
# 2. 将原始列表保存为 ContextInfo 的自定义属性,用于后续按顺序遍历
C.my_stock_list = stockList
def handlebar(C):
# 如果需要按特定顺序处理股票,请使用自己维护的列表
print("按原始顺序遍历:")
for stock in C.my_stock_list:
print(stock)
# 如果只是需要判断某只股票是否在股票池中,或者不需要关心顺序,可以使用 get_universe()
# universe = C.get_universe()
总结:
C.set_universe()的主要作用是告诉 QMT 底层需要订阅和计算哪些股票的数据。- 如果策略逻辑需要用到有序的股票列表,请在
init中通过C.自定义变量名 = stockList的方式自行保存并使用。