VeighNa框架的事前风控模块
说明
提供包括交易流控、下单数量、活动委托、撤单总数等规则的统计和限制,有效实现事前风控功能。
功能特性
基础风控规则
- OrderFlowRule - 委托流速控制:限制单位时间内的委托笔数,防止瞬间大量下单
- OrderSizeRule - 单笔委托数量上限:限制单笔委托的最大手数
- ActiveOrderRule - 活动委托数量上限:限制同时存在的未成交委托数量
- CancelLimitRule - 撤单频率控制:限制单一合约在时间窗口内的撤单次数
高级风控规则
-
OrderValidityRule - 委托指令合法性监控:
- 检查合约是否存在
- 检查委托价格是否为最小变动价位的整数倍
- 检查委托数量是否超过单笔最大手数限制
-
DuplicateOrderRule - 重复报单监控:检测并拦截短时间内完全相同的重复委托
-
DailyLimitRule - 全天委托/撤单笔数监控:对整个交易日内的总委托和总撤单数量进行限制
-
RollingWindowRule - 滚动窗口委托/撤单笔数监控:对短时间内的委托和撤单频率进行限制
性能优化
所有风控规则均使用 Cython 编译为 C 扩展,实现微秒级的风控检查延迟:
- OrderSizeRule: ~1000万 ops/s(整数比较)
- CancelLimitRule: ~5万 ops/s(时间窗口滑动)
安装
环境要求
- Python 3.10 或以上版本
- VeighNa 4.0.0 或以上版本
- C 编译器(用于编译 Cython 扩展)
- Windows: MSVC (Visual Studio Build Tools)
- Linux: gcc
- macOS: clang
安装方法
方式一:使用 pip 安装发布版本
pip install vnpy_riskmanager
方式二:从源代码安装
# 下载源代码
git clone https://github.com/vnpy/vnpy_riskmanager.git
cd vnpy_riskmanager
# 安装(会自动编译 Cython 扩展)
pip install .
方式三:开发模式安装
# 开发模式安装(修改代码后无需重新安装)
pip install -e .
使用指南
启动风控模块
在 VeighNa Trader 中加载风控模块:
from vnpy.event import EventEngine
from vnpy.trader.engine import MainEngine
from vnpy.trader.ui import MainWindow, create_qapp
from vnpy_ctp import CtpGateway
from vnpy_riskmanager import RiskManagerApp
def main():
qapp = create_qapp()
event_engine = EventEngine()
main_engine = MainEngine(event_engine)
# 添加交易接口
main_engine.add_gateway(CtpGateway)
# 添加风控模块(会自动启动)
main_engine.add_app(RiskManagerApp)
main_window = MainWindow(main_engine, event_engine)
main_window.showMaximized()
qapp.exec()
if __name__ == "__main__":
main()
配置风控参数
风控参数通过 risk_engine_setting.json 文件配置,该文件位于用户目录的 .vntrader 文件夹下。
配置示例:
{
"active_order_limit": 10,
"order_size_limit": 100,
"order_flow_limit": 10,
"order_flow_clear": 1,
"cancel_limit": 10,
"cancel_window": 1,
"check_contract_exists": true,
"check_price_tick": true,
"check_volume_limit": false,
"max_order_volume": 1000,
"max_duplicate_orders": 3,
"duplicate_window": 1.0,
"daily_order_limit": 1000,
"daily_cancel_limit": 500,
"rolling_window_seconds": 1.0,
"rolling_order_limit": 20,
"rolling_cancel_limit": 20
}
参数说明:
| 参数 | 说明 | 默认值 |
|---|---|---|
active_order_limit |
活动委托数量上限 | 10 |
order_size_limit |
单笔委托数量上限 | 100 |
order_flow_limit |
流速控制:单位时间内委托笔数上限 | 10 |
order_flow_clear |
流速控制:统计周期(秒) | 1 |
cancel_limit |
单合约撤单次数上限 | 10 |
cancel_window |
撤单统计窗口(秒) | 1 |
check_contract_exists |
是否检查合约存在性 | true |
check_price_tick |
是否检查价格合法性 | true |
check_volume_limit |
是否检查委托数量上限 | false |
max_order_volume |
单笔最大委托手数 | 1000 |
max_duplicate_orders |
允许的重复委托次数 | 3 |
duplicate_window |
重复检测时间窗口(秒) | 1.0 |
daily_order_limit |
全天委托笔数上限 | 1000 |
daily_cancel_limit |
全天撤单笔数上限 | 500 |
rolling_window_seconds |
滚动窗口时间长度(秒) | 1.0 |
rolling_order_limit |
滚动窗口内委托笔数上限 | 20 |
rolling_cancel_limit |
滚动窗口内撤单笔数上限 | 20 |
在界面中使用
- 启动 VeighNa Trader 后,在菜单栏选择 功能 -> 风控管理
- 在弹出的风控管理窗口中:
- 勾选"启用风控"复选框来启用/禁用风控功能
- 调整各项风控参数
- 点击"保存"按钮保存配置
开发新规则
方式一:仅 Python 实现(快速原型)
适合快速开发和测试新的风控逻辑。
步骤:
-
在
vnpy_riskmanager/rules/目录下创建新的.py文件,例如my_custom_rule.py -
继承
RuleTemplate并实现风控逻辑:
from typing import TYPE_CHECKING
from vnpy.trader.object import OrderRequest, CancelRequest
from ..template import RuleTemplate
if TYPE_CHECKING:
from ..engine import RiskEngine
class MyCustomRule(RuleTemplate):
"""自定义风控规则"""
def __init__(self, risk_engine: "RiskEngine", setting: dict) -> None:
"""构造函数"""
super().__init__(risk_engine, setting)
def init_rule(self, setting: dict) -> None:
"""初始化风控规则"""
self.my_limit: int = setting.get("my_limit", 100)
def check_allowed(self, req: OrderRequest, gateway_name: str) -> bool:
"""检查是否允许委托"""
if req.volume > self.my_limit:
self.write_log(f"委托数量 {req.volume} 超过限制 {self.my_limit}")
return False
return True
-
无需手动注册 -
RiskEngine会自动发现并加载rules/目录下所有继承自RuleTemplate的规则类 -
在
risk_engine_setting.json中添加规则所需的配置参数:
{
"my_limit": 100
}
- 重启应用即可生效
方式二:Cython 优化(性能关键路径)
适合对性能要求高的风控规则,可获得 10-100 倍的性能提升。
步骤:
-
首先创建
.py文件实现基础逻辑(参考方式一) -
创建对应的
.pyx文件,使用 Cython 语法优化:
# cython: language_level=3
from typing import TYPE_CHECKING
from ..template cimport RuleTemplate
if TYPE_CHECKING:
from ..engine import RiskEngine
cdef class MyCustomRule(RuleTemplate):
"""自定义风控规则(Cython 优化版本)"""
# 属性声明(public 使其可从 Python 访问,确保 .py 和 .pyx 版本行为一致)
cdef public int my_limit
def __init__(self, risk_engine: "RiskEngine", setting: dict) -> None:
"""构造函数"""
super().__init__(risk_engine, setting)
cpdef void init_rule(self, dict setting):
"""初始化风控规则"""
self.my_limit = setting.get("my_limit", 100)
cpdef bint check_allowed(self, object req, str gateway_name):
"""检查是否允许委托"""
if req.volume > self.my_limit:
self.write_log(f"委托数量 {req.volume} 超过限制 {self.my_limit}")
return False
return True
- 在
setup.py中添加 Extension 配置:
from setuptools import setup, Extension
from Cython.Build import cythonize
extensions = [
# ... 现有的扩展 ...
Extension(
"vnpy_riskmanager.rules.my_custom_rule",
["vnpy_riskmanager/rules/my_custom_rule.pyx"],
),
]
setup(
ext_modules=cythonize(extensions, compiler_directives={"language_level": "3"}),
)
- 重新编译安装:
pip install -e .
- Python 会自动优先加载编译后的
.pyd文件,无需修改engine.py
Cython 开发注意事项
为确保 .py 和 .pyx 版本行为一致,并支持完整的测试覆盖:
-
属性声明使用
cdef public# 使 Cython 属性可从 Python 访问,便于测试 cdef public int my_limit
-
时间相关功能使用 Python 的
time.time()import time # 不要用 from libc.time cimport time current_time = time.time() # 使用 Python 的 time.time() 而非 C time(),以便在测试中可被 mock
-
合约查询直接调用
risk_enginecontract = self.risk_engine.get_contract(req.vt_symbol)
-
保持接口一致
.py和.pyx文件的类名、方法签名必须完全一致- 确保测试用例能同时验证两个版本
性能基准测试
运行性能基准测试:
python benchmark_cython.py
输出示例:
OrderSizeRule: 10000000 checks in 1.23s (8130081 ops/s)
CancelLimitRule: 100000 checks in 2.15s (46511 ops/s)
测试
运行完整测试套件:
# 安装测试依赖
pip install pytest
# 运行所有测试
pytest tests/ -v
# 运行特定规则的测试
pytest tests/rules/test_order_validity_rule.py -v
代码质量检查
# Ruff 代码检查
ruff check .
# Mypy 类型检查
mypy vnpy_riskmanager
Release files for vnpy_riskmanager 2.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| vnpy_riskmanager-2.0.0.tar.gz | 517.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| vnpy_riskmanager-2.0.0-cp313-cp313-win_amd64.whl | CPython 3.13 | CPython 3.13 | Windows x86-64 | Details |
Total release size: 1.2 MB
Release files / vnpy_riskmanager-2.0.0.tar.gz
| Download URL | vnpy_riskmanager-2.0.0.tar.gz |
|---|---|
| Size | 517.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
5611305d84e722748c6491be9f7a0cf9f24e634be65689fbd8c55a57b5e9a0d3
|
|
BLAKE2b-256 checksum How to use checksums |
8d57cd70c0b38d28ea4998b920ffb80b1951dd3fc7e5782f5843a1a3496cf857
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.9.3
|
Release files / vnpy_riskmanager-2.0.0-cp313-cp313-win_amd64.whl
| Download URL | vnpy_riskmanager-2.0.0-cp313-cp313-win_amd64.whl |
|---|---|
| Size | 713.3 kB |
| Tags | CPython 3.13 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
43934f4f319b06c1fde7b644b88c9b34f495ef26d0221ec843d42cfa183fdb8e
|
|
BLAKE2b-256 checksum How to use checksums |
d3cda81e0eb5e960a30dadf06a19e9b0a998af951d35a692f953859bbc3f76e0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.9.3
|