🛡️【写一行规则就能冻结账号?】揭秘广发证券智能风控系统的魔法引擎!
🔍 一、前言:金融黑天鹅,如何用代码提前阻击?
在证券系统里,一旦出现非法套利、频繁下单、非正常大额转账等行为,系统必须在毫秒级响应进行冻结或拦截。
本篇揭示广发证券风控系统背后的核心逻辑引擎:一个可配置、可热更新的“规则引擎系统” ,让风控从“程序员专属”变成“业务可控”。
🧠 二、广发证券风控系统架构全景
交易行为流 → Kafka 消息总线 → 风控规则引擎(规则 DSL)→ Redis 告警/冻结 → 运营台前端展示
🛠️ 三、规则引擎的核心能力
| 能力 | 说明 |
|---|---|
| DSL 规则语法 | 支持“类 SQL”风格:WHEN 条件 THEN 动作 |
| 动态规则 | 不重启服务即可发布/修改规则 |
| 状态缓存 | 用 Redis 记录用户行为滑窗数据 |
| 决策执行 | 阻断、冻结、短信通知、打标签等多种行为 |
📦 四、风控规则 DSL 示例
WHEN total_orders_last_1m > 100 AND is_hft_user = true
THEN freeze_account, alert("高频交易异常")
这表示:“如果某用户在1分钟内下单次数超过100次,且是高频用户,则冻结账号并告警。”
🧪 五、实战代码演示:构建风控规则引擎
1️⃣ 规则定义对象
@dataclass
class Rule:
name: str
condition: str # e.g., "orders_last_1m > 100 and account_type == 'HFT'"
actions: List[str] # e.g., ["freeze", "alert"]
2️⃣ 条件表达式安全执行器(基于 ast)
import ast
def safe_eval(expr, context):
tree = ast.parse(expr, mode='eval')
code = compile(tree, '<string>', 'eval')
return eval(code, {"__builtins__": {}}, context)
3️⃣ 规则执行引擎
def execute_rules(rules, context):
for rule in rules:
if safe_eval(rule.condition, context):
for action in rule.actions:
handle_action(action, context["user_id"])
def handle_action(action, user_id):
if action == "freeze":
redis.set(f"frozen:{user_id}", True)
elif action == "alert":
print(f"告警:用户 {user_id} 触发风控")
4️⃣ 示例调用
rules = [
Rule("高频下单", "orders_last_1m > 100 and account_type == 'HFT'", ["freeze", "alert"]),
]
context = {
"user_id": "u001",
"orders_last_1m": 130,
"account_type": "HFT"
}
execute_rules(rules, context)
输出:
告警:用户 u001 触发风控
📊 六、实际风控覆盖场景
| 类型 | 示例 |
|---|---|
| 高频交易 | 连续快速挂单撤单超100次 |
| 异常资金转移 | 24小时内跨平台转账超限额 |
| 非法设备登录 | 异地登录 + 模拟器标识 |
| 暴力破解 | 连续密码错误10次 |
❗️ 七、易错点与避坑指南
| 问题 | 错误方式 | 建议方案 |
|---|---|---|
| DSL 表达式注入 | 用户拼接表达式执行 | 只允许内部规则,禁止外部动态拼接 |
| Redis 状态漂移 | 多实例并发读写不一致 | 使用 Redis Lua 脚本或事务锁 |
| 冻结误判 | 条件太苛刻 | 多规则加权评分、加入白名单策略 |
✅ 八、总结
风控系统的本质,不只是“查问题”,而是“抢时间”。广发证券通过构建:
- 配置化的 DSL 规则引擎
- 高性能状态数据计算(Redis 滑窗)
- 多动作组合策略
让业务与安全真正融合,提前阻击风险、守住核心资产。
🔮 下篇预告
《广发证券是怎么用 Rust 拿下高频交易底盘性能的?——一场 Java 与 Rust 的真实较量》