Home >  > VNPY4.0

VNPY4.0

几年没用,不会用了,记录一下:

一、回测

C:\Users\Administrator\.vntrader下面有一个database.db文件,将自己的数据库改名为database.db,然后替换这个文件。

运行回测报错:

我看了一下,这个turnover字段好像在tick表格中要用到,
但是在我的数据库中是没有这个字段,所以导致报错。

应该是vnpy之前某次升级,加了这个字段。

 

后来将原数据库中的数据导出为csv,再通过vnpy的csv文件导入,终于好了。

 

<div>
<div>import sqlite3</div>
<div>import csv</div>
<div></div>
<div># 连接到数据库</div>
<div>conn = sqlite3.connect('RB888.db')</div>
<div>cursor = conn.cursor()</div>
<div></div>
<div># 执行查询</div>
<div>cursor.execute('SELECT * FROM dbbardata')</div>
<div>rows = cursor.fetchall()</div>
<div></div>
<div># 写入CSV文件</div>
<div>with open('RB888.csv', 'w', newline='', encoding='utf-8') as file:</div>
<div>    writer = csv.writer(file)</div>
<div>    writer.writerow([i[0] for i in cursor.description])  # 写入列名</div>
<div>    writer.writerows(rows)</div>
<div></div>
<div># 关闭连接</div>
<div>conn.close()</div>
</div>

这里还有一个问题,从原数据库导出来csv之后,日期的格式老是显示不正确,我在这引问题又花了不少时间。

其实日期不正确没有关系,导入到vnpy之后又显示正确了。

终于将回测跑通了。

 

二、开发策略

在C:\Users\Administrator新建一个文件夹,strategies,注意名称不能出错

开发的策略放在:C:\Users\Administrator\strategies下面,

回测时就可以看到这个策略了。

当然,你也可以将策略放在:C:\veighna_studio\Lib\site-packages\vnpy_ctastrategy\strategies这里面,这是系统存放默认策略的地方。

三、代码回测
很久没有vnpy了,一开始只想到了使用UI界面进行回测,将代码回测都忘记了。
可是用UI界面回测效率实在太低了,要不断的打开、关闭窗口。
回测代码:

from vnpy_ctastrategy.backtesting import BacktestingEngine
from vnpy_ctastrategy.strategies.boll_channel_strategy import BollChannelStrategy
from datetime import datetime


engine = BacktestingEngine()
engine.set_parameters(
	vt_symbol = "RB888.SHFE",
	interval ="1m",
	start = datetime(2019,1,1),
	end = datetime(2025,5,1),
	rate = 0.0001,
	slippage = 4,
	size = 10,
	pricetick = 1,
	capital = 15_000,
	)

engine.add_strategy(BollChannelStrategy,{})
engine.load_data()
engine.run_backtesting()
df = engine.calculate_result()
engine.calculate_statistics()
engine.show_chart()

备注:如何要使用代码回测,则策略文件要保存到:C:\veighna_studio\Lib\site-packages\vnpy_ctastrategy\strategies这里面。

还有,运行上面的代码会报错:

C:\veighna_studio\Lib\site-packages\vnpy_ctastrategy\backtesting.py:400: FutureWarning: Series.__getitem__ treating keys as positions is deprecated. In a future version, integer keys will always be treated as labels (consistent with DataFrame behavior). To access a value by position, use `ser.iloc[pos]`
ewm_sharpe: float = ((ewm_mean - daily_risk_free) / ewm_std)[-1] * np.sqrt(self.annual_days)

这个警告信息 FutureWarning: Series.__getitem__ treating keys as positions is deprecated... 是由于 pandas 版本升级导致的,它提示 Series[-1] 这种索引方式在未来版本会被视为 标签(label) 而非 位置(position),建议改用 Series.iloc[-1] 来明确按位置索引。

解决方法
1. 修改 vn.py 源码(推荐)

找到 vnpy_ctastrategy/backtesting.py 文件的第 400 行(报错位置):

ewm_sharpe: float = ((ewm_mean - daily_risk_free) / ewm_std)[-1] * np.sqrt(self.annual_days)

改成:
ewm_sharpe: float = ((ewm_mean - daily_risk_free) / ewm_std).iloc[-1] * np.sqrt(self.annual_days)

四、解决日志问题

另外,发现用代码回测,生成的日志文件是空的。所以通过以下方式实现:
在策略开头加入:

import logging
import os

# 日志目录
log_dir = "./log"
os.makedirs(log_dir, exist_ok=True)

# 配置日志记录器
log_path = os.path.join(log_dir, "vt.log")
logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s  %(levelname)s: %(message)s",
    handlers=[
        logging.FileHandler(log_path, mode='a', encoding='utf-8'),
    ]
)


策略中加入:

def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
    super().__init__(cta_engine, strategy_name, vt_symbol, setting)

    self.logger = logging.getLogger(strategy_name)  # 添加这行
    ...

3.将原来策略中的: self.write_log("xxx") 改成:

self.logger.info("xxx")   # 或 warning / error / debug

Updated on May.21.2025
问过vnpy官方的回复:

回测的CTA策略日志不会输出到文件。回测时候的logs都存在回测引擎实例的logs列表里。可以选择通过图形界面回测,print函数打印日志,通过终端查看底层输出。也可以通过jupyter回测,在jupyter里面获取回测引擎实例的logs

五、导入数据

六、CTA策略自动移仓换月
https://zhuanlan.zhihu.com/p/429681035

七、tick级别的回测
https://www.vnpy.com/forum/topic/1992-vn-pyshe-qu-jing-xuan-8-tickshu-ju-zai-ru-he-ce-lue-hui-ce

八、米筐数据
对于非日内的CTA策略来说,跑日内k线级别的回测,一定要用复权了的连续合约数据(RQData对应888),否则换月时的跳空会严重影响策略信号的正确性,以及持仓盈亏的计算。

https://www.vnpy.com/forum/topic/7003-guan-yu-shu-ju-yuan-mi-kuang-orju-kuan

配置好就可以在回测界面点击“下载”按钮下载了。
其中license是注册米筐后对方发给你的一长串代码。

而且米筐下载数据挺快的,2015-2025年的数据2分钟就下载好了。

九、其他问题:
1.获取账户资金或动态仓位
Q:实盘中如何获取实时的账户资金?
A:
方式一:main_engine.get_account,可以参考get_pricetick函数的写法。
get_account() 是实盘/扩展框架中才可能存在的方法,标准 vn.py 回测框架中是没有的。
https://www.vnpy.com/forum/topic/30591-huo-qu-zhang-hu-zi-jin

方式二:

# In cta strategy
if isinstance(self.cta_engine, CtaEngine):
   self.acc_dict = self.cta_engine.main_engine.engines['oms'].accounts

方式三:
月神的代码实现:
https://www.vnpy.com/forum/topic/348-vnpyce-lue-nei-diao-yong-zi-jin-shi-xian-dan-shi-wo-bing-bu-jian-yi-da-jia-shi-yong-dong-tai-zi-jin-cang-wei?page=1

官方说法:本质上因为账户的资金情况对未来行情的预测没有任何帮助(收益),加上只是进一步增加量化交易这件事的不确定性(风向)

暧昧帖

本文暂无标签