问题描述
我复制了http://dict.thinktrader.net/vide ... thon.html?id=WK5Ewg该链接(原生python策略回测)的代码
运行在PyCharm python3.8中,出现错误
具体为result = run_strategy_file(user_script, param=param)中的client.createView(C.request_id, bson.BSON.encode(data))
有大佬帮看一下嘛,感谢
解决方案
在 PyCharm 等外部 IDE 中使用 QMT(迅投)的原生 Python 框架(如 xtquant)进行策略回测时,出现 client.createView(C.request_id, bson.BSON.encode(data)) 报错,通常是由于数据序列化失败或环境依赖冲突引起的。底层 C++ 客户端在与 Python 交互时使用 BSON 格式传递数据,如果数据格式不符就会抛出此异常。
以下是常见的排查方向和解决办法:
1. 检查 param 参数中的数据类型(最常见原因)
bson.BSON.encode(data) 报错绝大多数是因为传入的 param 字典中包含了 BSON 无法识别的数据类型。BSON 只能序列化 Python 的原生基本类型(如 int, float, str, bool, list, dict)。
常见错误类型:
- 使用了
numpy的数据类型(如np.int64,np.float64)。 - 使用了
pandas的时间类型(如pd.Timestamp)或原生的datetime.date(有时需要转为字符串或毫秒时间戳)。
解决办法:
在调用 run_strategy_file 之前,强制将 param 中的所有值转换为 Python 原生类型。例如:
# 假设你的 param 是这样的
param = {
'start_time': '20230101',
'end_time': '20231231',
'capital': 1000000,
# 如果这里不小心传入了 np.int64(1000000),就会报错
}
# 强制类型转换示例
clean_param = {}
for k, v in param.items():
if isinstance(v, (int, float)):
clean_param[k] = float(v) if isinstance(v, float) else int(v) # 消除 numpy 类型
else:
clean_param[k] = str(v)
# 使用清理后的参数运行
result = run_strategy_file(user_script, param=clean_param)
2. 排查 bson 库冲突
Python 环境中可能安装了错误的 bson 库。QMT 依赖的 BSON 编码功能通常来自于 pymongo 包,而不是独立的 bson 包。如果你通过 pip install bson 安装了独立的包,可能会导致 API 不兼容。
解决办法:
在 PyCharm 的终端(Terminal)中执行以下命令,卸载冲突的库并重新安装正确的库:
# 卸载可能冲突的独立 bson 库
pip uninstall bson -y
# 确保安装了 pymongo(它自带了正确的 bson 实现)
pip install pymongo
3. 确保 QMT 终端已启动并允许外部连接
外部 IDE(PyCharm)调用 run_strategy_file 进行回测时,底层仍然需要依赖 QMT 终端的数据服务和回测引擎。如果 QMT 客户端没有启动,或者没有正确配置外部调用权限,client.createView 也会因为无法建立通信视图而报错。
解决办法:
- 确保 QMT 客户端(全功能版或极简版)正在运行且已登录。
- 确保你的
xtquant库版本与当前运行的 QMT 客户端版本匹配。建议直接从 QMT 安装目录下的bin.x64/Lib/site-packages中提取最新的xtquant库到你的 PyCharm 环境中。
4. 检查 Python 版本兼容性
你提到使用的是 Python 3.8。QMT 官方内置的 Python 环境通常是 3.6.8 或 3.8.x。请确保你使用的 xtquant 库(特别是里面的 .pyd 动态链接库文件)是为 Python 3.8 编译的版本。如果版本不匹配,底层 C++ 接口调用时会出现各种奇怪的崩溃或编码错误。
总结排查步骤:
print(param)并使用type()检查里面每一个 value 的类型,剔除所有numpy类型。- 检查
pip list,卸载bson,保留/安装pymongo。 - 保持 QMT 终端开启状态再运行 PyCharm 脚本。