# vnpy_riskmanager **Repository Path**: vnpy/vnpy_riskmanager ## Basic Information - **Project Name**: vnpy_riskmanager - **Description**: vn.py框架的事前风控模块 - **Primary Language**: Python - **License**: MIT - **Default Branch**: main - **Homepage**: https://www.vnpy.com - **GVP Project**: No ## Statistics - **Stars**: 4 - **Forks**: 13 - **Created**: 2021-09-07 - **Last Updated**: 2025-11-02 ## Categories & Tags **Categories**: Uncategorized **Tags**: Python, 量化交易, vnpy ## README # VeighNa框架的事前风控模块

## 说明 vnpy_riskmanager是[VeighNa](https://www.vnpy.com)框架的事前风控模块。它提供了一套风控规则引擎,可以在交易过程中对委托下单进行实时检查。所有核心风控规则均使用 **Cython** 编译为C语言扩展,实现了微秒级的风控检查延迟,确保了在高速交易场景下的性能表现。 ## 功能特性 本模块内置了多种常用的风控规则,覆盖了从委托合法性到交易频率的多个方面: - **ActiveOrderRule** - 活动委托数量上限:限制任何时候账户中处于未成交状态的委托总数。 - **DailyLimitRule** - 全天委托/撤单笔数监控:对整个交易日内的总委托和总撤单数量进行限制。 - **DuplicateOrderRule** - 重复报单监控:检测并拦截在极短时间窗口内,针对同一合约的、方向和价格等完全相同的重复委托。 - **OrderSizeRule** - 单笔委托数量上限:限制单笔委托的最大手数,防止因“乌龙指”下出超大订单。 - **OrderValidityRule** - 委托指令合法性监控:在下单前对委托指令进行合法性检查,包括: - 检查委托的合约是否存在。 - 检查委托价格是否为合约最小价格变动的整数倍。 - 检查委托数量是否超过了交易所规定的单笔最大手数限制。 ## 安装 ### 环境要求 - Python 3.10 或以上版本 - VeighNa 4.0.0 或以上版本 - C++编译器(用于从源码安装时编译Cython扩展) - Windows: [Microsoft C++ Build Tools](https://visualstudio.microsoft.com/visual-cpp-build-tools/) - Linux: `sudo apt-get install build-essential` - macOS: `xcode-select --install` ### 安装方法 **方式一:使用 pip 安装(推荐)** ```bash pip install vnpy_riskmanager ``` **方式二:从源代码安装** 如果你需要进行二次开发,可以从源代码安装。 ```bash # 下载源代码 git clone https://github.com/vnpy/vnpy_riskmanager.git cd vnpy_riskmanager # 开发模式安装(修改代码后无需重新安装) pip install -e . ``` 执行 `pip install` 时会自动编译Cython代码。 ## 开发与编译 如果你修改了 `.pyx` 文件,或者希望手动编译,可以执行以下步骤: 1. **安装开发依赖**: ```bash pip install cython ``` 2. **执行编译**: 在项目根目录下,运行 `setup.py` 的 `build_ext` 命令。 ```bash python setup.py build_ext --inplace ``` `--inplace` 参数会使编译生成的扩展文件(Windows下为`.pyd`,Linux/macOS下为`.so`)直接放在源代码目录中,方便直接运行和调试。 ## 使用指南 ### 启动风控模块 在VeighNa Trader的启动入口脚本中,添加`RiskManagerApp`即可。 ```python 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() ``` ## 开发新规则 你可以根据自己的风控需求,轻松地添加新的规则。 ### 1. 添加纯Python规则 适合快速开发和逻辑验证。 1. **创建文件**: 在 `.vntrader`文件夹平级的`rules/` 目录下创建一个新的Python文件,例如 `my_new_rule.py`。 2. **编写代码**: 文件内容需要包含一个继承自 `RuleTemplate` 的类。类名必须以 `Rule` 结尾。 ```python from vnpy.trader.object import OrderRequest, OrderData from ..template import RuleTemplate class MyNewRule(RuleTemplate): """在这里写规则的中文描述""" # 规则的英文名,必须是唯一的 name: str = "MyNewRule" # 定义可配置的参数,用于在UI上显示和修改 parameters: dict[str, str] = { "my_param": "我的参数" } # 定义需要监控的变量,用于在UI上显示 variables: dict[str, str] = { "my_variable": "我的变量" } def on_init(self) -> None: """初始化方法""" self.my_param: int = 100 # 设置参数的默认值 self.my_variable: int = 0 # 初始化变量 def check_allowed(self, req: OrderRequest, gateway_name: str) -> bool: """ 核心风控逻辑。 如果订单允许通过,返回 True。 如果订单被拦截,调用 self.write_log() 记录原因,并返回 False。 """ if req.volume > self.my_param: msg = f"委托数量{req.volume}超过参数限制{self.my_param}" self.write_log(msg) return False return True def on_order(self, order: OrderData) -> None: """处理委托回报,用于更新规则的内部状态""" self.my_variable += 1 self.put_event() # 更新UI显示 ``` 3. **重启程序**: `RiskEngine` 会在启动时自动发现并加载新规则。 ### 2. 添加Cython规则(性能优化) 对于需要处理高频事件(如`on_tick`)或包含复杂计算的规则,推荐使用Cython进行性能优化。 1. **创建`.pyx`文件**: 在 `.vntrader`文件夹平级的`rules/` 目录下创建Cython文件,例如 `my_new_rule_cy.pyx`。 2. **编写Cython代码**: 关键在于,需要定义一个 `cdef class` 来实现核心逻辑,并在文件末尾提供一个同名的Python `class` 作为包装器,用于被`RiskEngine`识别。 ```cython # cython: language_level=3 from vnpy.trader.object import OrderRequest from vnpy_riskmanager.template cimport RuleTemplate cdef class MyNewRuleCy(RuleTemplate): """Cython规则实现""" cdef public int my_param cdef public int my_variable cpdef void on_init(self): self.my_param = 100 self.my_variable = 0 cpdef bint check_allowed(self, object req, str gateway_name): if req.volume > self.my_param: msg = f"委托数量{req.volume}超过参数限制{self.my_param}" self.write_log(msg) return False return True # Python包装器,用于被RiskEngine发现和加载 class MyNewRule(MyNewRuleCy): name: str = "MyNewRule" parameters: dict[str, str] = { "my_param": "我的参数" } variables: dict[str, str] = { "my_variable": "我的变量" } ``` 3. **创建编译脚本**: 用户自定义的Cython规则不应修改项目本身的`setup.py`。反之,应该为你的规则创建一个独立的编译脚本`rule_setup.py`,并与`.pyx`文件放在同一个`rules/`目录下。 **`rule_setup.py` 内容示例:** ```python from setuptools import setup, Extension from Cython.Build import cythonize # 注意:这里的 name 需要和 .pyx 文件名保持一致 rule_name = "my_new_rule_cy" extensions = [ Extension( name=rule_name, sources=[f"{rule_name}.pyx"], ) ] setup( ext_modules=cythonize( extensions, compiler_directives={"language_level": "3"} ) ) ``` 4. **编译**: 在 `rules/` 目录下打开终端,运行 `rule_setup.py` 来编译你的规则。 ```bash # 确保你正处于 rules/ 目录下 python rule_setup.py build_ext --inplace ``` 编译成功后,会在当前目录下生成同名的 `.pyd` (Windows) 或 `.so` (Linux/macOS) 文件。 5. **重启程序**: `RiskEngine`会自动优先加载编译好的Cython版本规则。 ## 运行脚本 `script/` 目录下提供了一些用于测试和演示的实用脚本。 - **`run_trader.py`**: 启动一个加载了本风控模块的VeighNa Trader实例,用于图形界面的功能测试和日常使用。 - **`benchmark_performance.py`**: 用于对比纯Python规则和Cython规则的性能差异。它会模拟大量的 `check_allowed` 调用,并打印出每秒操作数(ops/s)。 - **`test_cython_rules.py`**: 用于对Cython规则进行简单的单元测试,确保其逻辑正确性。