让我搜索关于工作目录、.vntrader 配置目录以及策略数据缓存的相关信息
让我查看 CTA 策略引擎的源代码,了解策略加载和变量缓存的机制
让我查看 CTA 策略引擎的源代码,了解策略加载和变量缓存的实现
让我查看策略模板和工具函数,了解变量缓存和 .vntrader 目录的机制
我已经查看了相关源码和社区资料,下面结合源码机制帮你分析这个问题。
核心结论:问题出在「工作目录(cwd)」
你自己的测试其实已经定位到了关键点——决定结果的是启动时的工作目录,而不是 Python 解释器或 Station 本身。这一点在 vnpy_ctastrategy 的源码里可以完全解释清楚。
源码机制分析
1. .vntrader 目录跟随工作目录
CTA 引擎读写配置和缓存用的是 load_json / save_json(来自 vnpy.trader.utility),它们定位的是当前工作目录下的 .vntrader 文件夹。这个目录里包含:
| 文件 |
内容 |
vt_setting.json |
全局配置(数据库、数据服务、日志) |
cta_strategy_setting.json |
CTA 策略参数配置 |
cta_strategy_data.json |
CTA 策略运行时变量缓存 |
所以:
- 在
c:\Administrator 启动 → 用 c:\Administrator\.vntrader
- 在
c:\veighna_studio 启动 → 用 c:\veighna_studio\.vntrader
2. 策略源码的加载顺序(关键)
engine.py 的 load_strategy_class() 会从两个位置加载策略类:
def load_strategy_class(self) -> None:
# 1. 已安装模块自带的 strategies 目录
path1: Path = Path(__file__).parent.joinpath("strategies")
self.load_strategy_class_from_folder(path1, "vnpy_ctastrategy.strategies")
# 2. 当前工作目录下的 strategies 目录
path2: Path = Path.cwd().joinpath("strategies")
self.load_strategy_class_from_folder(path2, "strategies")
注意:后加载的 cwd/strategies 会覆盖先加载的模块自带策略(同名类以 self.classes[value.__name__] 为准)。也就是说,如果你在 c:\Administrator\strategies 里放了一份旧版策略源码,它会覆盖掉你复制到 site-packages 里的新版。
3. 变量缓存的恢复逻辑
_init_strategy() 里的顺序是:先执行 on_init,再用缓存覆盖变量:
# Call on_init function of strategy
self.call_strategy_func(strategy, strategy.on_init)
# Restore strategy data(variables)
data: dict | None = self.strategy_data.get(strategy_name, None)
if data:
for name in strategy.variables:
value = data.get(name, None)
if value is not None:
setattr(strategy, name, value)
而 strategy_data 来自 cta_strategy_data.json(load_strategy_data())。
为什么 bar_dates 会缺失
结合你的日志差异,最可能是以下两种原因之一(或叠加):
两个 .vntrader 里的 cta_strategy_data.json 内容不同
c:\Administrator\.vntrader 里存的是旧缓存,其中 bar_dates 为 null 或不存在,导致 on_init 里算出来的值被覆盖/未恢复。
- 你虽然复制了配置文件,但如果没把
cta_strategy_data.json 一起覆盖,或复制后又被旧进程写回,两边就不一致。
两个工作目录加载到的策略源码不是同一份
c:\Administrator\strategies 下可能残留旧版策略(variables 列表里没有 bar_dates,或 on_init 逻辑不同),它覆盖了 site-packages 里的新版。
- 这也能解释你提到的「不同版本通过 Station 启动结果不一样」——本质是加载到了不同版本的源码。
排查建议
确认实际加载的策略文件
在两个目录分别启动后,看日志里有没有 策略文件xxx加载失败 的提示;并对比:
c:\Administrator\strategies\ 下是否有你的策略文件
C:\veighna_studio\Lib\site-packages\vnpy_ctastrategy\strategies\ 下的文件
用文件哈希(如 certutil -hashfile 文件名 SHA256)确认两份源码是否完全一致。
对比两个 .vntrader 目录
c:\Administrator\.vntrader\cta_strategy_data.json
c:\veighna_studio\.vntrader\cta_strategy_data.json
重点看 bar_dates 字段是否存在、值是什么。可以先把两边的 cta_strategy_data.json 都删掉,再分别启动对比,排除缓存干扰。
统一工作目录
最稳妥的做法是让 Station 和脚本使用同一个工作目录。VeighNa Station 的启动目录是可配置的,把它设成和脚本一致(或反过来),两边结果就会一致。
确认 variables 列表
检查策略类里 bar_dates 是否在 variables 中声明。只有声明了才会被写入/恢复缓存;如果只在 on_init 里赋值但没进 variables,重启后就不会持久化。
小结
VeighNa Station 本身只是启动器,它把工作目录固定到了 c:\Administrator;而 CTA 引擎的 .vntrader(含 cta_strategy_data.json 缓存)和 strategies(策略源码)都相对当前工作目录定位。因此「Station 启动」和「PowerShell 脚本启动」结果不同,本质是工作目录不同 → 加载的缓存和策略源码不同,而不是 Station 的编译文件有问题。
建议按上面第 1、2 步先做一次文件级对比,基本就能锁定是「缓存差异」还是「源码差异」。
参考来源:
vnpy_ctastrategy/engine.py(load_strategy_class、_init_strategy、load_strategy_data、sync_strategy_data)
vnpy_ctastrategy/template.py(variables、get_variables)
- 社区 FAQ:
data-persistence-guide.md、multi-account-deployment.md、cta-strategy-tips.md
基于RAG技术开发的VeighNa AI助手,你的个人专属 Desk Quant