VeighNa量化社区
你的开源社区量化交易平台 | vn.py | vnpy
Member
avatar
加入于:
帖子: 53
声望: 0

Exception in thread Thread-1:
Traceback (most recent call last):
File "D:\anaconda\envs\py_vnpy3.7\lib\threading.py", line 926, in _bootstrap_inner
self.run()
File "D:\anaconda\envs\py_vnpy3.7\lib\threading.py", line 870, in run
self._target(*self._args, **self._kwargs)
File "D:\vnpy3.9.1\vnpy-3.9.1\vnpy\event\engine.py", line 60, in _run
self._process(event)
File "D:\vnpy3.9.1\vnpy-3.9.1\vnpy\event\engine.py", line 73, in _process
[handler(event) for handler in self._handlers[event.type]]
File "D:\vnpy3.9.1\vnpy-3.9.1\vnpy\event\engine.py", line 73, in <listcomp>
[handler(event) for handler in self._handlers[event.type]]
File "D:\anaconda\envs\py_vnpy3.7\lib\site-packages\vnpy_ctastrategy\engine.py", line 212, in process_trade_event
self.sync_strategy_data(strategy)
File "D:\anaconda\envs\py_vnpy3.7\lib\site-packages\vnpy_ctastrategy\engine.py", line 855, in sync_strategy_data
save_json(self.data_filename, self.strategy_data)
File "D:\vnpy3.9.1\vnpy-3.9.1\vnpy\trader\utility.py", line 123, in save_json
ensure_ascii=False
File "D:\anaconda\envs\py_vnpy3.7\lib\json__init.py", line 179, in dump
for chunk in iterable:
File "D:\anaconda\envs\py_vnpy3.7\lib\json\encoder.py", line 431, in _iterencode
yield from _iterencode_dict(o, _current_indent_level)
File "D:\anaconda\envs\py_vnpy3.7\lib\json\encoder.py", line 405, in _iterencode_dict
yield from chunks
File "D:\anaconda\envs\py_vnpy3.7\lib\json\encoder.py", line 405, in _iterencode_dict
yield from chunks
File "D:\anaconda\envs\py_vnpy3.7\lib\json\encoder.py", line 438, in _iterencode
o = _default(o)
File "D:\anaconda\envs\py_vnpy3.7\lib\json\encoder.py", line 179, in default
raise TypeError(f'Object of type {o.
class.name__} '
TypeError: Object of type time is not JSON serializable

我策略发现有如下报错,请问各位大佬这个是为什么?

Member
avatar
加入于:
帖子: 53
声望: 0

而且看起来是数据没有正确保存的问题,但是不知道为什么会产生这样的情况

description

Super Moderator
avatar
加入于:
帖子: 100
声望: 10

从错误信息来看,问题出在 time 对象无法被 JSON 序列化。具体来说,VeighNa 在保存策略数据时,使用了 json.dump 方法,但策略数据中包含了 time 类型的对象,而 json 模块默认不支持序列化 time 对象。


问题原因

json.dump 只能序列化以下类型的数据:

  • 基本类型:int, float, str, bool, None
  • 容器类型:list, dict
  • 其他类型:需要自定义序列化方法。

time 对象(例如 datetime.time)不在默认支持的类型中,因此会抛出 TypeError


解决方法

可以通过以下两种方式解决这个问题:


方法 1:自定义 JSON 序列化方法

在保存策略数据时,自定义一个序列化方法,将 time 对象转换为字符串。例如:

import json
from datetime import time

def default_serializer(obj):
    if isinstance(obj, time):
        return obj.isoformat()  # 将 time 对象转换为字符串
    raise TypeError(f"Object of type {obj.__class__.__name__} is not JSON serializable")

# 保存策略数据时使用自定义序列化方法
with open("strategy_data.json", "w", encoding="utf-8") as f:
    json.dump(strategy_data, f, default=default_serializer, ensure_ascii=False)

方法 2:在策略中避免使用 time 对象

如果策略数据中不需要保存 time 对象,可以在保存数据之前将其转换为字符串或其他可序列化的类型。例如:

from datetime import time

# 假设 strategy_data 中包含 time 对象
for key, value in strategy_data.items():
    if isinstance(value, time):
        strategy_data[key] = value.isoformat()  # 转换为字符串

# 保存策略数据
with open("strategy_data.json", "w", encoding="utf-8") as f:
    json.dump(strategy_data, f, ensure_ascii=False)

修改 VeighNa 源码

如果问题出在 VeighNa 的源码中(例如 vnpy_ctastrategy/engine.py),可以修改 sync_strategy_data 方法,添加自定义序列化逻辑。例如:

def sync_strategy_data(self, strategy):
    # 自定义序列化方法
    def default_serializer(obj):
        if isinstance(obj, time):
            return obj.isoformat()
        raise TypeError(f"Object of type {obj.__class__.__name__} is not JSON serializable")

    # 保存策略数据
    save_json(self.data_filename, self.strategy_data, default=default_serializer)

总结

  • 问题原因是 time 对象无法被 JSON 序列化。
  • 可以通过 自定义序列化方法在保存数据前转换类型 来解决。
  • 如果问题出在 VeighNa 源码中,可以修改相关代码,添加自定义序列化逻辑。

参考

© 2015-2022 上海韦纳软件科技有限公司
备案服务号:沪ICP备18006526号

沪公网安备 31011502017034号

【用户协议】
【隐私政策】
【免责条款】