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

各位大大,最近有个问题困扰我很久了。我写了个cta策略,通过veighna station启动ctastrategy得到的输出结果有问题,有些初始化的变量无法正确缓存和计算,但是通过powershell启动脚本启动ctastrategy的则能全部正确缓存和输出,但是veighna station不是开源的,没有提供源文件,只有编译的文件,所以一直想不清楚那个环节出了问题,之前也出现过不同版本通过veighna station启动ctastrategy得到的策略变量缓存输出结果不一样的问题,所以一直想搞清楚原因,还请各位大佬帮忙解惑,谢谢了。

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

通过veighna station启动ctastrategy:
2026-10-13 09:44:37 --------------------------------------------------
2026-10-13 09:44:37 VeighNa Trader进程启动
得到的ctastrategy输出结果:
09:52:39.276,"[tp_rb2610] 策略启动, vola_ratio:[]; update_date:None tnr: 0.0; ma_slope: 0.0; vol_contraction: False holding_bars:0;"
通过powershell启动脚本启动图形界面后启动ctastrategy:
策略启动, vola_ratio:[]; update_date:None tnr: 0.0; ma_slope: 0.0; vol_contraction: False holding_bars:0; open_date: None;bar_dates: [datetime.date(2026, 9, 21), datetime.date(2026, 9, 22), datetime.date(2026, 9, 23), datetime.date(2026, 9, 24), datetime.date(2026, 9, 28), datetime.date(2026, 9, 29), datetime.date(2026, 9, 30), datetime.date(2026, 10, 8), datetime.date(2026, 10, 9), datetime.date(2026, 10, 12)]

Member
加入于:
帖子: 6142
声望: 382

是否有多个python?没有的话,检查一下trader启动目录是否相同


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

(1)应该是只有一个Python,我自己找了一下pycharm和veighna station, 应该都是用veighna station安装时自带安装的Python;我也用命令行找了一下:
PS C:\Users\Administrator> where python
PS C:\Users\Administrator> where python3
PS C:\Users\Administrator> Get-Command python

CommandType Name Version Source


Application python.exe 3.13.81... C:\veighna_studio\python.exe

PS C:\Users\Administrator> python -c "import sys; print(sys.executable)"
C:\veighna_studio\python.exe
下面是winserver环境变量设置,应该不会有其它版本Python了:
%6SystemRoot9\system32
%SystemRoot%
%SystemRoot%\System32\Wberm
%SYSTEMROOT%(System32WindowsPowerShellv1.0\
%SYSTEMROOT%\System32\OpenSSH\
C:\veighna_studio
C:\veighna_studio\Scripts
(2)trader启动目录我后来又试了一下,第一步:我把c:\Administrator目录下的,.vntrader下的配置文件复制了一份到c:\veighna_studio下同时把这个策略的源码也复制了一份到C:\veighna_studio\Lib\site-packages\vnpy_ctastrategy\strategies目录下,第二步:c:\veighna_studio下通过powershell用脚本启动输出是正常的,第三步:而c:\Administrator下通过powershell用启动是不正常的,输出和上面一样,不正常的少了这一段:bar_dates: [datetime.date(2026, 9, 21), datetime.date(2026, 9, 22), datetime.date(2026, 9, 23), datetime.date(2026, 9, 24), datetime.date(2026, 9, 28), datetime.date(2026, 9, 29), datetime.date(2026, 9, 30), datetime.date(2026, 10, 8), datetime.date(2026, 10, 9), datetime.date(2026, 10, 12)];
另外,我在c:\Administrator下即使通过powershell用脚本启动输出也是错误的,和通过veighna_station图形界面启动一样的错误,veighna_station的启动目录就是设置在c:\Administrator下。

Super Moderator
avatar
加入于:
帖子: 146
声望: 15

让我搜索关于工作目录、.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 会缺失

结合你的日志差异,最可能是以下两种原因之一(或叠加):

  1. 两个 .vntrader 里的 cta_strategy_data.json 内容不同

    • c:\Administrator\.vntrader 里存的是旧缓存,其中 bar_dates 为 null 或不存在,导致 on_init 里算出来的值被覆盖/未恢复。
    • 你虽然复制了配置文件,但如果没把 cta_strategy_data.json 一起覆盖,或复制后又被旧进程写回,两边就不一致。
  2. 两个工作目录加载到的策略源码不是同一份

    • c:\Administrator\strategies 下可能残留旧版策略(variables 列表里没有 bar_dates,或 on_init 逻辑不同),它覆盖了 site-packages 里的新版。
    • 这也能解释你提到的「不同版本通过 Station 启动结果不一样」——本质是加载到了不同版本的源码。

排查建议

  1. 确认实际加载的策略文件
    在两个目录分别启动后,看日志里有没有 策略文件xxx加载失败 的提示;并对比:

    • c:\Administrator\strategies\ 下是否有你的策略文件
    • C:\veighna_studio\Lib\site-packages\vnpy_ctastrategy\strategies\ 下的文件
      用文件哈希(如 certutil -hashfile 文件名 SHA256)确认两份源码是否完全一致。
  2. 对比两个 .vntrader 目录

    c:\Administrator\.vntrader\cta_strategy_data.json
    c:\veighna_studio\.vntrader\cta_strategy_data.json
    

    重点看 bar_dates 字段是否存在、值是什么。可以先把两边的 cta_strategy_data.json 都删掉,再分别启动对比,排除缓存干扰。

  3. 统一工作目录
    最稳妥的做法是让 Station 和脚本使用同一个工作目录。VeighNa Station 的启动目录是可配置的,把它设成和脚本一致(或反过来),两边结果就会一致。

  4. 确认 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

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

原因找到了,是因为策略代码的类名重复了。虽然原来策略代码文件名改成了原文件名加backup的文件名,但是原来策略代码的类名没有改且还放在同一文件夹下,所以出现后面扫描的文件名策略类名覆盖前面文件的相同策略类名的,结果就是改过的策略被覆盖而无法生效。谢谢各位大侠帮助!