Skip to content

9.5 合规与监管

概念详解

程序化交易的合规与监管是量化投资中不可忽视的基础性要求。随着全球主要市场对程序化交易监管的持续加强,合规不仅仅是法律部门的事情,更是量化策略开发和运维团队必须内化的能力。一个技术上完美但合规不达标的策略,轻则被罚款/暂停交易,重则面临监管调查和刑事责任。

程序化交易合规的主要领域包括:

1. 中国市场(A股/期货) 中国对程序化交易的监管体系近年来快速完善:

  • 程序化交易报告制度(2024年起实施):所有程序化交易投资者需要向交易所和证监会进行报告,包括策略类型、服务器位置、交易频率范围等。未报告的程序化交易面临暂停交易的风险。

  • 异常交易行为监控:交易所实时监控以下异常行为:

    • 频繁申报并撤单(撤单率 > 30%可能触发调查)
    • 大额申报不成交(虚报价格)
    • 自买自卖(自成交)
    • 关联账户对倒
    • 日内回转交易超限(部分品种有限制)
    • 程序化交易导致的价格异常波动
  • 流量控制:各交易所对程序化交易的申报速率有明确限制(如上交所的每秒300笔限制),超速会被阻断。

  • 穿透式监管:期货市场要求看穿式监管,交易软件需要满足穿透式监管技术要求。

2. 美国市场

  • SEC Rule 15c3-5 (Market Access Rule):券商必须对客户订单进行盘前风控检查,包括信用限额、持仓限额、错误订单价格检查等。
  • Regulation SCI:要求关键市场基础设施(交易所、清算所等)建立全面的技术合规体系。
  • CAT (Consolidated Audit Trail):收集和存储全美所有股票和期权的订单和执行数据,用于监管调查。
  • FINRA:监控券商的交易行为、最佳执行义务、反洗钱等。

3. 欧盟市场

  • MiFID II / MiFIR:对算法交易的系统性要求,包括算法测试、熔断机制、交易报告等。
  • MAR (Market Abuse Regulation):禁止市场操纵和内幕交易,对算法交易的操纵行为(spoofing/layering)有明确的处罚规定。
名词解释:异常交易监控

交易所对程序化交易设置的监管指标,如频繁撤单、自成交比例、大额申报等,超标可能被处罚或暂停交易。

名词解释:Spoofing(幌骗交易)

一种市场操纵行为:通过挂出无意成交的大额订单来制造虚假的供需假象,诱导其他投资者以不利价格交易,然后迅速撤销虚假订单。Dodd-Frank Act明确定义spoofing为非法行为。

名词解释:穿透式监管

监管机构要求看穿交易者的实际身份,防止通过多层代理或技术手段隐藏真实交易者。中国的穿透式监管要求交易终端采集并上报客户的硬件信息和软件环境。

数学原理

撤单率的计算与监控

撤单率是交易所最关注的异常交易指标之一。不同的交易所可能有略微不同的定义,但核心公式为:

$$CancelRate = \frac{N_{cancelled}}{N_{submitted}}$$

其中 Nsubmitted 是提交订单数,Ncancelled 是撤销订单数。

更精细的版本是权重撤单率,考虑了订单的挂单时间:

$$WeightedCancelRate = \frac{\sum w_i \cdot \mathbb{1}_{cancelled}(i)}{\sum w_j \cdot \mathbb{1}_{submitted}(j)}$$

其中权重 wi=min(tcanceltsubmit,Tmax),即挂单时间越长权重越大。

订单簿操纵的检测

Spoofing检测的基本逻辑:观察订单是否存在"挂出-成交前撤销"的模式。SPOOF_SCORE:

$$SPOOF\_SCORE = \frac{\sum orders\ where\ (cancel\_within\_10ms\ AND\ no\_partial\_fill)}{\sum orders\ with\ large\_size\_ratio}$$

最佳执行义务的量化

MiFID II要求投资公司采取所有充分步骤为客户获得最佳执行结果。最佳执行可以通过执行质量指标来量化:

$$ExecutionQuality = w_1 \cdot S_{price} + w_2 \cdot S_{speed} + w_3 \cdot S_{cost} + w_4 \cdot S_{likelihood}$$

其中各项 S 是相应维度的标准化得分。

Python实战

📌 案例1:监控撤单率

PYTHON3 行 · 103 B
📄此处有展示代码3 行 · 103 B展开 ▼
python
cancel_rate = cancelled_orders / total_orders
if cancel_rate > threshold:
    alert("撤单率过高")
点击展开可浏览运行结果
📘 本段为公式演示片段(伪代码占位符,无完整上下文)

📌 案例2:综合合规监控系统

PYTHON270 行 · 10.2 KB
📄此处有展示代码270 行 · 10.2 KB展开 ▼
python
from dataclasses import dataclass, field
from typing import List, Dict, Optional
from datetime import datetime, timedelta
from collections import deque, defaultdict
import numpy as np

@dataclass
class ComplianceRule:
    """合规规则定义"""
    rule_id: str
    name: str
    description: str
    severity: str  # LOW, MEDIUM, HIGH, CRITICAL
    
    # 指标监控参数
    metric_name: str
    threshold: float
    window_seconds: int = 60
    cooldown_seconds: int = 300

class ComplianceMonitor:
    """合规监控器 - 实时检测违规行为"""
    
    def __init__(self):
        # 定义规则库
        self.rules = self._initialize_rules()
        
        # 订单历史(滑动窗口)
        self.order_history: deque = deque(maxlen=10000)
        self.cancel_history: deque = deque(maxlen=5000)
        self.fill_history: deque = deque(maxlen=10000)
        
        # 违规记录
        self.violations: deque = deque(maxlen=1000)
        
        # 状态追踪
        self.is_throttled = False  # 是否被限流
        self.trading_paused = False  # 交易是否暂停
    
    def _initialize_rules(self) -> List[ComplianceRule]:
        """初始化合规规则库"""
        return [
            ComplianceRule(
                'R001', '撤单率过高', 
                '订单撤单率超过监管阈值', 'HIGH',
                metric_name='cancel_rate', threshold=0.30, window_seconds=300
            ),
            ComplianceRule(
                'R002', '自成交检测',
                '检测自己的买卖订单相互成交', 'CRITICAL',
                metric_name='self_trade_ratio', threshold=0.01, window_seconds=300
            ),
            ComplianceRule(
                'R003', '申报速率超限',
                '每秒钟订单申报数量超过交易所限制', 'HIGH',
                metric_name='order_rate_per_sec', threshold=300, window_seconds=5
            ),
            ComplianceRule(
                'R004', '价格异常偏离',
                '订单价格与最新成交价偏离超过合理范围', 'MEDIUM',
                metric_name='price_deviation_pct', threshold=0.05, window_seconds=60
            ),
            ComplianceRule(
                'R005', '大额申报未成交',
                '大额挂单在成交前被撤销(疑似spoofing)', 'CRITICAL',
                metric_name='spoofing_score', threshold=0.50, window_seconds=600
            ),
            ComplianceRule(
                'R006', '频繁修改订单',
                '短时间内对同一订单频繁修改价格/数量', 'MEDIUM',
                metric_name='modify_frequency', threshold=5, window_seconds=10
            ),
            ComplianceRule(
                'R007', '持仓超限',
                '单只股票持仓超过监管或内部限制', 'HIGH',
                metric_name='position_limit_pct', threshold=1.0, window_seconds=60
            ),
            ComplianceRule(
                'R008', 'T+0回转超限',
                '日内回转交易超过允许次数', 'MEDIUM',
                metric_name='day_trade_count', threshold=100, window_seconds=23400  # 交易时段
            ),
        ]
    
    def record_order(self, order_info: dict):
        """记录一笔订单"""
        order_info['timestamp'] = datetime.now()
        self.order_history.append(order_info)
    
    def record_cancel(self, order_id: str, timestamp: datetime = None):
        """记录一笔撤单"""
        self.cancel_history.append({
            'order_id': order_id,
            'timestamp': timestamp or datetime.now()
        })
    
    def record_fill(self, fill_info: dict):
        """记录一笔成交"""
        fill_info['timestamp'] = datetime.now()
        self.fill_history.append(fill_info)
    
    def check_compliance(self) -> List[dict]:
        """执行所有合规检查,返回违规列表"""
        now = datetime.now()
        violations = []
        
        for rule in self.rules:
            result = self._check_rule(rule, now)
            if result:
                violations.append(result)
                self.violations.append(result)
        
        # 如果存在CRITICAL违规,自动暂停交易
        if any(v['severity'] == 'CRITICAL' for v in violations):
            self.trading_paused = True
        
        return violations
    
    def _check_rule(self, rule: ComplianceRule, now: datetime) -> Optional[dict]:
        """检查单条合规规则"""
        window_start = now - timedelta(seconds=rule.window_seconds)
        
        # 根据规则类型计算指标
        current_value = None
        
        if rule.rule_id == 'R001':  # 撤单率
            recent_orders = [o for o in self.order_history 
                           if o['timestamp'] > window_start]
            recent_cancels = [c for c in self.cancel_history 
                            if c['timestamp'] > window_start]
            if len(recent_orders) > 20:  # 足够样本量才判断
                current_value = len(recent_cancels) / max(len(recent_orders), 1)
        
        elif rule.rule_id == 'R002':  # 自成交
            recent_fills = [f for f in self.fill_history 
                          if f['timestamp'] > window_start]
            if recent_fills:
                self_trades = sum(1 for f in recent_fills if f.get('is_self_trade', False))
                current_value = self_trades / len(recent_fills)
        
        elif rule.rule_id == 'R003':  # 申报速率
            recent_orders = [o for o in self.order_history 
                           if o['timestamp'] > window_start]
            if recent_orders:
                elapsed = (now - recent_orders[0]['timestamp']).total_seconds()
                current_value = len(recent_orders) / max(elapsed, 1)
        
        elif rule.rule_id == 'R004':  # 价格偏离
            recent_orders = [o for o in self.order_history 
                           if o['timestamp'] > window_start]
            deviations = []
            for o in recent_orders:
                if 'market_price' in o and 'order_price' in o and o['market_price'] > 0:
                    dev = abs(o['order_price'] - o['market_price']) / o['market_price']
                    deviations.append(dev)
            if deviations:
                current_value = max(deviations)
        
        elif rule.rule_id == 'R005':  # Spoofing检测
            recent_orders = [o for o in self.order_history 
                           if o['timestamp'] > window_start]
            spoofing_candidates = [
                o for o in recent_orders
                if o.get('quantity', 0) > 10000  # 大单
                and o.get('cancel_time') is not None
                and (o['cancel_time'] - o['timestamp']).total_seconds() < 0.5  # 0.5秒内撤销
                and o.get('filled_qty', 0) == 0  # 未成交
            ]
            if recent_orders:
                current_value = len(spoofing_candidates) / len(recent_orders)
        
        elif rule.rule_id == 'R006':  # 频繁修改
            recent_orders = [o for o in self.order_history 
                           if o['timestamp'] > window_start]
            # 按order_id分组,检查每个订单的修改次数
            mod_counts = defaultdict(int)
            for o in recent_orders:
                if o.get('is_modify'):
                    mod_counts[o.get('order_id', '')] += 1
            if mod_counts:
                current_value = max(mod_counts.values())
        
        # 判断是否违规
        if current_value is not None and current_value > rule.threshold:
            return {
                'rule_id': rule.rule_id,
                'rule_name': rule.name,
                'severity': rule.severity,
                'current_value': current_value,
                'threshold': rule.threshold,
                'window_seconds': rule.window_seconds,
                'timestamp': now.isoformat(),
                'description': (f"{rule.name}: 当前值={current_value:.3f} "
                              f"阈值={rule.threshold:.3f}")
            }
        
        return None
    
    def get_compliance_report(self) -> dict:
        """生成合规报告摘要"""
        return {
            'trading_paused': self.trading_paused,
            'is_throttled': self.is_throttled,
            'total_violations_today': len(self.violations),
            'violations_by_severity': {
                sev: sum(1 for v in self.violations if v['severity'] == sev)
                for sev in ['LOW', 'MEDIUM', 'HIGH', 'CRITICAL']
            },
            'recent_violations': list(self.violations)[-10:]
        }

# ==================== 使用示例 ====================

monitor = ComplianceMonitor()

# 模拟正常交易
print("合规监控系统演示:")
for i in range(100):
    # 模拟订单
    monitor.record_order({
        'order_id': f'ORD_{i:05d}',
        'symbol': 'AAPL',
        'side': 'BUY',
        'quantity': np.random.randint(100, 5000),
        'order_price': 150.0 + np.random.uniform(-0.5, 0.5),
        'market_price': 150.0,
        'is_modify': np.random.random() < 0.1,
    })
    
    # 模拟一些撤单
    if np.random.random() < 0.15:  # 15%撤单率 - 正常
        monitor.record_cancel(f'ORD_{i:05d}')
    
    # 模拟一些成交
    if np.random.random() < 0.7:
        monitor.record_fill({
            'order_id': f'ORD_{i:05d}',
            'symbol': 'AAPL',
            'filled_qty': np.random.randint(100, 5000),
            'fill_price': 150.0,
            'is_self_trade': False,
        })

# 注入异常行为模拟:超高撤单率
for i in range(50):
    monitor.record_order({
        'order_id': f'SPAM_{i:05d}',
        'symbol': 'TSLA',
        'side': 'SELL',
        'quantity': 10000,
        'order_price': 250.0,
        'market_price': 250.0,
        'is_modify': False,
    })
    # 所有都立即撤单
    monitor.record_cancel(f'SPAM_{i:05d}')

# 执行合规检查
violations = monitor.check_compliance()
report = monitor.get_compliance_report()

print(f"\n合规检查报告:")
print(f"  交易状态: {'暂停' if report['trading_paused'] else '正常'}")
print(f"  今日违规数: {report['total_violations_today']}")
print(f"  按严重程度: {report['violations_by_severity']}")

if violations:
    print(f"\n  最新违规:")
    for v in violations[:5]:
        print(f"    [{v['severity']}] {v['description']}")
点击展开可浏览运行结果
合规监控系统演示:

合规检查报告:
  交易状态: 正常
  今日违规数: 1
  按严重程度: {'LOW': 0, 'MEDIUM': 0, 'HIGH': 1, 'CRITICAL': 0}

  最新违规:
    [HIGH] 撤单率过高: 当前值=0.453 阈值=0.300

📌 案例3:Pre-Trade合规检查

PYTHON77 行 · 3.0 KB
📄此处有展示代码77 行 · 3.0 KB展开 ▼
python
class PreTradeCompliance:
    """盘前合规检查器 - 在每个订单发送前执行"""
    
    def __init__(self, position_limits, restricted_stocks, 
                 max_order_value, min_price, max_price):
        self.position_limits = position_limits  # {symbol: max_shares}
        self.restricted_stocks = set(restricted_stocks)
        self.max_order_value = max_order_value
        self.min_price = min_price  # 最低允许价格
        self.max_price = max_price  # 最高允许价格
    
    def check(self, order: dict, current_positions: dict,
              current_price: float) -> tuple:
        """
        盘前合规检查
        
        返回: (passed: bool, reason: str)
        """
        symbol = order['symbol']
        qty = order['quantity']
        side = order['side']
        price = order.get('price', current_price)
        
        # 1. 禁买/禁卖名单检查
        if symbol in self.restricted_stocks:
            return False, f"{symbol} 在限制交易名单中"
        
        # 2. 价格合理性检查
        if price < self.min_price or price > self.max_price:
            return False, f"价格 {price} 超出合理范围 [{self.min_price}, {self.max_price}]"
        
        # 3. 订单价值检查
        order_value = abs(qty * price)
        if order_value > self.max_order_value:
            return False, f"订单价值 {order_value:,.0f} 超过单笔上限 {self.max_order_value:,.0f}"
        
        # 4. 持仓限制检查
        current_qty = current_positions.get(symbol, 0)
        new_qty = current_qty + (qty if side == 'BUY' else -qty)
        
        if symbol in self.position_limits:
            limit = self.position_limits[symbol]
            if abs(new_qty) > limit:
                return False, f"下单后持仓 {abs(new_qty)} 超过限额 {limit}"
        
        # 5. 空头检查(如果账户不允许卖空)
        if side == 'SELL' and current_qty < qty:
            return False, f"可卖数量不足(持仓: {current_qty}, 卖出: {qty})"
        
        return True, "检查通过"

# 初始化盘前风控
pre_trade = PreTradeCompliance(
    position_limits={'AAPL': 5000, 'TSLA': 2000, 'NVDA': 3000},
    restricted_stocks={'GME', 'AMC'},  # 限制名单
    max_order_value=500000,
    min_price=1.0,
    max_price=5000.0
)

# 测试几个订单
test_orders = [
    {'symbol': 'AAPL', 'side': 'BUY', 'quantity': 1000, 'price': 150.0},
    {'symbol': 'GME', 'side': 'BUY', 'quantity': 100, 'price': 25.0},  # 限制名单
    {'symbol': 'TSLA', 'side': 'BUY', 'quantity': 3000, 'price': 250.0},  # 超限
    {'symbol': 'NVDA', 'side': 'SELL', 'quantity': 500, 'price': 800.0},
]

print("\nPre-Trade合规检查:")
for order in test_orders:
    passed, reason = pre_trade.check(
        order, 
        current_positions={'AAPL': 2000, 'NVDA': 200}, 
        current_price=order['price']
    )
    status = "PASS" if passed else "REJECT"
    print(f"  [{status}] {order['symbol']} {order['side']} {order['quantity']}: {reason}")
点击展开可浏览运行结果
Pre-Trade合规检查:
  [PASS] AAPL BUY 1000: 检查通过
  [REJECT] GME BUY 100: GME 在限制交易名单中
  [REJECT] TSLA BUY 3000: 订单价值 750,000 超过单笔上限 500,000
  [REJECT] NVDA SELL 500: 可卖数量不足(持仓: 200, 卖出: 500)

常见误区

误区1:合规是法律部门的事,与量化团队无关。 合规指标(撤单率、申报速率、持仓限制等)直接影响策略的交易行为。如果策略设计时没有考虑合规约束,上线后频繁触发交易所警告将导致策略无法执行。

误区2:只要策略逻辑没问题就不会违规。 即使是"好"的策略,技术实现中的bug也可能产生违规行为。例如:循环逻辑错误导致重复发送同一订单、异常处理不当导致撤单风暴、网络重试机制导致超频。

误区3:撤单率只看实时数据就够了。 交易所通常使用滑动窗口计算撤单率,而且定义可能与策略团队理解的不同。需要仔细阅读交易所的异常交易监控细则,确保监控逻辑与交易所一致。

误区4:合规检查降低策略收益。 正确的合规设计反而可能保护策略——例如,撤单率限制促使你在发送订单前更谨慎地评估成交概率,减少无效订单,降低整体交易成本。

误区5:只要不在中国交易,合规要求就宽松。 不同市场的合规要求各异但都不可忽视。美国的CAT和Reg SCI、欧洲的MiFID II在某些方面比中国的监管更细致。

实战练习

练习1: 阅读上交所/深交所的《异常交易行为监控细则》和《程序化交易管理实施细则》,编写一份"程序化交易合规checklist"文档,涵盖申报、撤单、持仓、自成交、异常波动等核心指标的监管阈值和监控方法。

练习2: 实现一个"Spoofing检测模拟器":

  • 模拟正常交易和Spoofing行为的订单流
  • 使用多种检测特征:挂单规模/撤单速度/挂单层位置变化
  • 训练一个检测模型(逻辑回归或XGBoost)
  • 评估在正常策略交易中的误报率

练习3: 设计一个"合规熔断"自动化系统:

  • 根据合规监控结果(违规严重程度和频率)自动采取分级措施
    • Level 1 (WARNING): 记录日志,不限制交易
    • Level 2 (SOFT_LIMIT): 降低订单频率50%
    • Level 3 (HARD_LIMIT): 暂停所有新订单,只允许平仓
    • Level 4 (KILL_SWITCH): 取消所有未成交订单,全部平仓,断开交易连接
  • 实现自动恢复机制(冷却时间后自动逐级解除限制)

延伸阅读

  1. 中国证监会. 证券市场程序化交易管理规定(试行) (2024年). — 中国程序化交易监管的最新法规框架。
  2. 上海证券交易所. 上海证券交易所程序化交易管理实施细则.
  3. SEC. Rule 15c3-5 (Market Access Rule)Regulation SCI.
  4. ESMA. MiFID II / MiFIR Guidelines on Algorithmic Trading.
  5. Gregoriou, G. N. (2015). Handbook of High Frequency Trading. Ch. 23 (Regulatory Issues). — HFT监管问题的学术和实务讨论。

本章要点

  • 程序化交易合规覆盖申报报告异常行为监控流量控制穿透式监管四大领域
  • 撤单率自成交申报速率是最常触发的三大约束指标
  • Spoofing(幌骗交易)在全球主要市场均为明确的违法行为,可能面临刑事处罚
  • 合规监控应分为盘前检查(Pre-Trade)、盘中实时(In-Trade)、事后审计(Post-Trade)三层
  • 合规熔断机制应分级设计,从温和限流到强制断开,确保违规行为能被及时阻断
  • 合规不是"减速带"——设计得当的合规约束能帮助策略变得更稳健