mx-risk-guard

June 15, 2026 · View on GitHub

🛡️ 轻量、券商无关的 A 股交易机器人风控引擎
Lightweight, broker-agnostic risk guard for A-share trading bots.

PyPI License: MIT Python 3.9+

纯规则护栏,不依赖 LLM。 只做一件事:在你的交易机器人犯傻时强制兜底。

✨ 为什么需要它?

LLM 驱动的交易机器人会出现:

  • 🤖 幻觉股票代码(编造 002594、300750)
  • 🔥 过度集中(all-in 单股)
  • 💸 失控亏损(连续止损不收手)
  • 🐛 下单成功但未成交还以为持仓

mx-risk-guard 是独立于策略层的最后一道护栏,纯 Python 规则引擎,可与任何券商 SDK 配合。

🚀 30 秒上手

from mx_risk_guard import (
    RiskEngine, MxMoniAdapter, DryRunAdapter,
    SinglePositionRule, DailyLossCircuitBreaker,
    DrawdownStopLoss, BlacklistRule,
)

# 1. 接入你的 broker(需实现 get_balance/get_positions/sell_safe/cancel_all)
adapter = MxMoniAdapter(broker=your_broker)

# 2. 组合规则
engine = (
    RiskEngine(adapter)
    .add_rule(SinglePositionRule(max_pct=0.55))            # 单股≤55%
    .add_rule(DailyLossCircuitBreaker(max_loss_pct=0.03))  # 单日亏损≥3% 熔断
    .add_rule(DrawdownStopLoss(max_drawdown_pct=0.08))     # 单股回撤≥8% 平
    .add_rule(BlacklistRule(codes={"300750", "002594"}))   # 黑名单
)

# 3. 执行
engine.run(dry_run=False)

📋 内置规则

规则触发条件动作
SinglePositionRule单股市值 > total × max_pct减仓到阈值
DailyLossCircuitBreaker当日盈亏 ≤ -max_loss_pct全部清仓 🚨
DrawdownStopLoss持仓浮亏 ≤ -max_drawdown_pct强平该股
BlacklistRule持仓中含黑名单代码立即清仓
HoldingDaysRule持仓天数 > max_days强制卖出

🔌 适配器

  • MxMoniAdapter — 东方财富妙想模拟盘(配合 mx-trader-bridge
  • DryRunAdapter — 单元测试 / 回测干跑
  • 自定义 BrokerAdapter — 实现 2 个方法即可:snapshot() + execute(action)
from mx_risk_guard import BrokerAdapter, PortfolioSnapshot

class QmtAdapter:  # QMT/Ptrade 适配
    def snapshot(self) -> PortfolioSnapshot:
        # 拉数据 → PortfolioSnapshot
        ...
    def execute(self, action) -> dict:
        # 下卖单
        ...

📚 完整示例

示例说明
examples/quickstart.py5 行最小 demo,外部传入 snapshot
examples/custom_rule.py自定义规则(开盘跳空清仓 / 现金占比告警)
examples/with_mx_moni.py接入妙想模拟盘真实持仓扫描
pip install -e .
python examples/quickstart.py

🧪 干跑测试

from mx_risk_guard import RiskEngine, DryRunAdapter, PortfolioSnapshot, DrawdownStopLoss

snap = PortfolioSnapshot(
    total_assets=1_000_000,
    available_cash=50_000,
    day_pnl_pct=-2.5,
    positions=[
        {"code": "002015", "name": "协鑫能科", "count": 1000, "avail_count": 1000,
         "price": 10.0, "market_value": 10_000, "profit_pct": -10.5}
    ],
)
result = RiskEngine(DryRunAdapter(snap)).add_rule(DrawdownStopLoss(0.08)).run()
print(result["actions"])
# [RiskAction(rule='drawdown_stop_loss', code='002015', qty=1000, ...)]

🏗️ 设计哲学

  1. 不依赖 LLM — 规则即代码,可单测可回测
  2. 券商无关 — Adapter 模式,10 行接入任意 SDK
  3. 可组合 — 规则按需开启/关闭/调阈值
  4. 可观测 — 每次扫描产出 RiskAction 列表,便于落库审计

📦 安装

pip install mx-risk-guard

🤝 贡献

欢迎 PR:新增规则、适配器、回测样例。

📄 License

MIT © mx-risk-guard contributors