问题描述
看API的说明文档context.portfolio.positions.keys() 输出当前持仓的股票代码
我用
print(context.portfolio.positions.keys())
结果输出的是
2015-02-03 15:30:00 - INFO - KeysView({'000651.XSHE': UserPosition({'security': '000651.XSHE', 'price': 39.8, 'total_amount': 800, 'closeable_amount': 0, 'avg_cost': 40.01, 'acc_avg_cost': 40.01}), '002415.XSHE': UserPosition({'security': '002415.XSHE', 'price': 27.78, 'total_amount': 1100, 'closeable_amount': 0, 'avg_cost': 27.89, 'acc_avg_cost': 27.89}), '600999.XSHG': UserPosition({'security': '600999.XSHG', 'price': 24.9, 'total_amount': 1300, 'closeable_amount': 0, 'avg_cost': 24.57, 'acc_avg_cost': 24.57})})
这结果和context.portfolio.positions.values()基本一样。
是我哪里错了?
解决方案
您好!您并没有做错,这是由于 Python 3 的字典视图特性以及 JoinQuant 底层对象的打印格式(__repr__)共同导致的。
问题原因分析
在 JoinQuant 平台中,context.portfolio.positions 是一个类似字典(dict)的对象,键(key)是股票代码,值(value)是 Position 对象。
- Python 3 的特性:在 Python 3 中,调用字典的
.keys()方法返回的不再是一个简单的列表(list),而是一个 动态视图对象(dict_keys 或 KeysView)。 - 打印显示(repr):当您直接
print这个视图对象时,Python 会尝试打印它的内部表示。由于 JoinQuant 对底层字典类进行了封装,打印这个视图时,连带着把字典里的值(即UserPosition对象)也一并显示出来了,所以您看到的结果非常长,感觉和.values()差不多。
解决方法
如果您想要得到一个纯粹的、只包含股票代码的列表,只需要使用 list() 函数将这个视图对象强制转换为列表即可。
正确的代码写法:
# 将 KeysView 转换为 list
stock_list = list(context.portfolio.positions.keys())
print(stock_list)
这样输出的结果就会是您期望的:
['000651.XSHE', '002415.XSHE', '600999.XSHG']
补充:遍历持仓的常用写法
在实际编写策略时,如果您只是想遍历当前持仓的股票代码,可以直接遍历 context.portfolio.positions(在 Python 中遍历字典默认就是遍历它的 keys),不需要显式调用 .keys():
# 遍历当前持仓的所有股票代码
for stock in context.portfolio.positions:
print("当前持仓股票代码:", stock)
# 获取该股票的持仓对象
position = context.portfolio.positions[stock]
print("该股票持仓数量:", position.total_amount)
总结来说,直接 print(keys()) 只是显示形式的问题,数据结构本身是正确的,套一层 list() 就可以解决您的疑惑了。