11 KiB
RiskManager - 事前风控管理模块
功能简介
RiskManager是用于事前风控管理的功能模块,采用插件式架构设计,提供标准化的风控规则开发模板(RuleTemplate)。用户可以通过其UI界面便捷完成风控规则的启停、参数修改和状态监控,也可以自行编写符合业务需求的自定义风控规则。
内置5条风控规则,覆盖中国期货程序化交易系统监管要求中的核心检测项:
- 活动委托检查:限制同时处于活动状态的委托数量上限
- 每日上限检查:限制日内累计委托/撤单/成交笔数(支持全汇总和单合约两个维度)
- 重复报单检查:防止短时间内重复发送完全相同的委托
- 委托规模检查:限制单笔委托的数量和名义价值
- 委托指令检查:验证委托价格、数量是否符合合约规范(合约存在性、最小变动价位、数量上下限等)
加载启动
VeighNa Station加载
启动登录VeighNa Station后,点击【交易】按钮,在配置对话框中的【应用模块】栏勾选【RiskManager】。
脚本加载
在启动脚本中添加如下代码:
# 写在顶部
from vnpy_riskmanager import RiskManagerApp
# 写在创建main_engine对象后
main_engine.add_app(RiskManagerApp)
启动模块
在菜单栏中点击【功能】-> 【交易风控】,或者点击左侧按钮栏的图标:
即可进入事前风控模块的UI界面。界面采用左侧规则列表 + 右侧规则详情(参数/变量)的布局,如下图所示:
左侧列表显示所有已加载的风控规则名称,点击后右侧显示该规则的当前参数和实时变量。每条规则都包含active参数,可在【修改风控参数】对话框中单独启用或停用。
当任何一条规则拦截委托时,系统会:
- 在VeighNa Trader主界面的【日志】栏输出拦截原因
- 通过Windows系统托盘弹出气泡通知(停留30秒)
- 播放系统提示音(当前仅支持Windows)
内置风控规则
活动委托检查(ActiveOrderRule)
限制同时处于活动状态(提交中 / 未成交 / 部分成交)的委托数量。
| 参数 | 名称 | 默认值 | 说明 |
|---|---|---|---|
| active_order_limit | 活动委托上限 | 50 | 活动委托数量达到此值后不再发单 |
| 变量 | 名称 | 说明 |
|---|---|---|
| active_order_count | 活动委托数量 | 当前处于活动状态的委托笔数 |
当一笔委托状态变为非活动(全部成交 / 已撤销 / 拒单)时,计数器自动释放。
每日上限检查(DailyLimitRule)
限制日内累计的委托、撤单和成交笔数,支持全汇总(所有合约合计)和单合约两个维度的独立上限。
| 参数 | 名称 | 默认值 | 说明 |
|---|---|---|---|
| total_order_limit | 汇总委托上限 | 20000 | 所有合约合计的委托笔数上限 |
| total_cancel_limit | 汇总撤单上限 | 10000 | 所有合约合计的撤单笔数上限 |
| total_trade_limit | 汇总成交上限 | 10000 | 所有合约合计的成交笔数上限 |
| contract_order_limit | 合约委托上限 | 2000 | 单个合约的委托笔数上限 |
| contract_cancel_limit | 合约撤单上限 | 1000 | 单个合约的撤单笔数上限 |
| contract_trade_limit | 合约成交上限 | 1000 | 单个合约的成交笔数上限 |
| 变量 | 名称 | 说明 |
|---|---|---|
| total_order_count | 汇总委托笔数 | 当天所有合约累计委托笔数 |
| total_cancel_count | 汇总撤单笔数 | 当天所有合约累计撤单笔数 |
| total_trade_count | 汇总成交笔数 | 当天所有合约累计成交笔数 |
| contract_order_count | 合约委托笔数 | 各合约分别统计(dict,key为vt_symbol) |
| contract_cancel_count | 合约撤单笔数 | 各合约分别统计 |
| contract_trade_count | 合约成交笔数 | 各合约分别统计 |
六项上限中有任意一项达到即拦截后续委托。计数器每日重置。
重复报单检查(DuplicateOrderRule)
防止策略因逻辑错误在短时间内反复发送完全相同的委托请求。
规则将每笔委托请求格式化为字符串(合约代码 + 委托类型 + 方向 + 开平 + 数量 @ 价格),统计相同请求的重复次数。
| 参数 | 名称 | 默认值 | 说明 |
|---|---|---|---|
| duplicate_order_limit | 重复报单上限 | 10 | 相同委托请求的允许最大次数 |
| 变量 | 名称 | 说明 |
|---|---|---|
| duplicate_order_count | 重复报单笔数 | 当前累计的重复报单统计(dict) |
委托一旦被拦截,计数器不再增加(避免无限增长),用户需手动排查策略逻辑。
委托规模检查(OrderSizeRule)
限制单笔委托的数量和名义价值,防止因参数错误导致异常大单。
| 参数 | 名称 | 默认值 | 说明 |
|---|---|---|---|
| order_volume_limit | 委托数量上限 | 500 | 单笔委托允许的最大手数 |
| order_value_limit | 委托价值上限 | 1000000 | 单笔委托允许的最大名义价值 |
委托名义价值的计算公式为:数量 × 价格 × 合约乘数。由于合约乘数需要从CTP等接口推送的合约信息中获取,仅当合约信息已缓存且为限价单时才会执行价值检查。
委托指令检查(OrderValidityRule)
验证委托本身的合法性,确保发送到交易所的委托不会被拒单。检测项包括:
- 合约存在性:委托的目标合约代码是否在系统中可查到
- 价格精度:委托价格是否为合约最小变动价位(pricetick)的整数倍
- 数量范围:委托数量是否在合约允许的[min_volume, max_volume]区间内
该规则除公共的active参数外,无其他用户可配置参数。默认启用,建议始终保持开启,避免低级的委托格式错误。
自定义风控规则
用户可以像编写CTA策略一样编写自己的风控规则。RiskManager提供了标准化的风控规则开发模板(RuleTemplate),只需继承基类并实现必要的方法即可添加新的风控逻辑。
规则模板
所有风控规则继承RuleTemplate基类,其结构与CtaTemplate高度一致:
from vnpy_riskmanager.template import RuleTemplate
from vnpy.trader.object import OrderRequest, OrderData, TradeData, TickData
class MyCustomRule(RuleTemplate):
"""自定义风控规则"""
# 规则名称(UI显示名,同时作为配置主键,需全局唯一)
name: str = "我的自定义规则"
# 参数字段 → UI显示名
parameters: dict[str, str] = {
"my_limit": "自定义上限",
}
# 变量字段 → UI显示名
variables: dict[str, str] = {
"my_count": "自定义计数",
}
def on_init(self) -> None:
"""初始化(构造函数中自动调用)"""
self.my_limit: int = 100
self.my_count: int = 0
def check_allowed(self, req: OrderRequest, gateway_name: str) -> bool:
"""
检查是否允许此笔委托。
返回 True = 放行,返回 False = 拦截并输出日志。
"""
if self.my_count >= self.my_limit:
self.write_log(f"自定义计数{self.my_count}达到上限")
return False
return True
def on_order(self, order: OrderData) -> None:
"""收到委托回报时触发"""
self.my_count += 1
self.put_event()
def on_trade(self, trade: TradeData) -> None:
"""收到成交回报时触发"""
pass
def on_tick(self, tick: TickData) -> None:
"""收到行情Tick时触发"""
pass
def on_timer(self) -> None:
"""每秒定时触发"""
pass
RuleTemplate方法速查
| 方法 | 触发时机 | 说明 |
|---|---|---|
check_allowed(req, gateway) |
每次发单前 | 核心方法,返回True/False决定是否放行 |
on_init() |
规则实例化时 | 初始化参数和变量 |
on_order(order) |
收到委托回报 | 更新活动委托、计数器等 |
on_trade(trade) |
收到成交回报 | 更新成交计数等 |
on_tick(tick) |
收到行情Tick | 如需要基于行情数据做风控 |
on_timer() |
每秒 | 如需要基于时间窗口做统计 |
write_log(msg) |
主动调用 | 输出拦截日志到主界面 |
put_event() |
主动调用 | 推送变量更新到UI界面 |
get_contract(vt_symbol) |
主动调用 | 查询合约信息(乘数、最小变动价位等) |
注意:只有实际重写了on_order / on_trade / on_tick / on_timer的规则才会收到对应的事件推送。RiskEngine会通过needs_callback()方法自动检测,避免不必要的事件分发开销。
放置自定义规则
对于用户自行开发的风控规则,需要放到VeighNa Trader运行时目录下的rules目录中,才能被识别加载。具体的运行时目录路径,可以在VeighNa Trader主界面顶部的标题栏查看。该目录通常与.vntrader文件夹平级,若不存在rules目录,需自行创建。
对于在Windows上默认安装的用户来说,放置规则的rules目录路径通常为:
C:\Users\Administrator\rules
其中Administrator为当前登录Windows的系统用户名。
请注意:
- 显示在UI左侧的是规则类的
name属性,而不是规则文件名; - 规则类名必须以
Rule结尾(例如MyCustomRule),否则不会被加载。
RiskEngine启动时会自动扫描并加载该目录下符合条件的规则类,同时也会加载vnpy_riskmanager.rules包内的内置规则。两个来源的规则会合并显示在UI左侧的规则列表中。
如规则文件发生修改,重新启动VeighNa Trader即可加载新版本。
Cython加速
对于性能敏感的场景(如高频交易中大量事件回调),可以将.py编译为.pyd(Windows)或.so(Linux)。vnpy_riskmanager.rules目录下已经提供了每条内置规则的Cython版本(.pyx文件),用户自定义规则也可以同样处理。
RiskEngine在扫描规则时会同时匹配*.py、*.pyd、*.so后缀的文件,无需额外配置。若同一规则类同时存在纯Python与编译版本,后加载的版本会覆盖先加载的版本(扫描顺序为py → pyd → so)。
参数配置
修改参数
在UI界面左侧列表中选择需要修改的规则,点击右下角的【修改风控参数】按钮:
弹出参数编辑对话框,各参数根据类型自动匹配输入控件:
- bool类型:下拉框(True / False),如
active开关 - int类型:整数微调框
- float类型:浮点数微调框(6位小数精度)
修改后点击【确定】保存并立即生效。参数会自动持久化到运行时目录下.vntrader文件夹中的risk_manager_setting.json文件,下次启动自动恢复。
启停规则
每条规则都有active参数(默认True)。设为False后该规则不再参与委托拦截检查。可在【修改风控参数】对话框中,将active对应的下拉框改为False后保存。
建议日常保持全部规则启用。如需临时关闭某条规则以排查问题,关闭后应立即恢复。



