Quick Start
Architecture
The compliance module is Python-only (not on the hot path) and uses a separate SQLite database so compliance data survives strategy changes. All components are thread-safe.Audit Trail
Every compliance event is recorded with a SHA-256 hash chain. Each event links to its predecessor, creating a tamper-evident log that auditors can verify end-to-end.Tracked Event Types
| Event Type | When Recorded |
|---|---|
ORDER_SUBMITTED | Order passes compliance gate |
ORDER_FILLED | Fill recorded |
ORDER_CANCELED | Cancellation recorded |
ORDER_REJECTED | Compliance rejects order |
ORDER_AMENDED | Order amendment |
POSITION_CHANGED | Position update |
CONFIG_CHANGED | Compliance config or role change |
KILL_SWITCH_ACTIVATED | Emergency halt activated |
KILL_SWITCH_DEACTIVATED | Emergency halt deactivated |
APPROVAL_REQUESTED | Order held for review |
APPROVAL_GRANTED | Reviewer approves |
APPROVAL_DENIED | Reviewer denies |
APPROVAL_EXPIRED | Request auto-expired |
SURVEILLANCE_ALERT | Surveillance detector fires |
LIMIT_BREACH | Regulatory limit breached |
REPORT_GENERATED | Compliance report created |
DATA_PURGED | Retention purge executed |
Trade Surveillance
Real-time detection of manipulative trading patterns using sliding-window analysis. Runs once per strategy cycle viaon_cycle().
Detectors
| Detector | What It Catches | Severity |
|---|---|---|
| Wash Trading | Buy + sell same market within threshold | Critical |
| Spoofing | Order placed and canceled before fill | Warning |
| Layering | N stacked orders on one side | Warning |
| Rapid-Fire | Order rate exceeding limit/minute | Warning |
| Concentration | Single market exceeding portfolio share | Warning |
Accessing Alerts
Human-in-the-Loop Approval
Orders exceeding a notional threshold are held for manual review. The strategy loop is never blocked - pending orders are queued and submitted asynchronously when approved.Approval Workflow
Notification Callback
Role-Based Access Control (RBAC)
Five hierarchical roles control who can perform compliance-sensitive operations.| Role | Permissions |
|---|---|
| Viewer | View positions, feeds, orders, audit trail, alerts, reports |
| Trader | Submit/cancel orders, view positions/feeds/orders/alerts |
| Risk Manager | Trader + kill switch, modify risk config |
| Compliance Officer | Risk Manager + approve/deny orders, resolve alerts, generate reports, modify compliance config, export audit |
| Admin | Compliance Officer + manage roles, purge data |
Regulatory Limits
Firm-wide limits enforced before order submission, separate from strategy-levelRiskConfig.
| Limit | Description |
|---|---|
restricted_markets | Blacklisted market IDs - orders rejected immediately |
max_position_per_market | Per-market position size cap |
max_total_notional | Portfolio-wide notional cap |
max_concentration_pct | Max % of portfolio in one market (default 25%) |
max_daily_volume | Daily traded volume cap |
max_orders_per_minute | Order rate limit (default 120) |
max_cancel_ratio | Max cancel-to-order ratio (default 95%) |
Kill Switch
Emergency halt with RBAC enforcement. RequiresRISK_MANAGER role or higher. Snapshots all open positions at activation time for post-incident review.
Reporting
Generate regulatory-ready reports for internal review and filing.Daily Trade Report
Position Report
Full Compliance Report
Data Retention
SEC Rule 17a-4 requires 6+ years of record retention. Default is 2,555 days (~7 years).Pipeline Integration
Usecompliance_gate as the first function in your pipeline to automatically enforce compliance on every cycle.
compliance_gate returns None, which halts the pipeline for that cycle. Surveillance runs every cycle. Stale approvals are auto-expired.
Standalone Usage
The compliance module works independently fromhz.run():
Configuration Reference
ComplianceConfig
| Field | Type | Default | Description |
|---|---|---|---|
enabled | bool | True | Master switch for all compliance checks |
audit_enabled | bool | True | Enable audit trail recording |
surveillance_enabled | bool | True | Enable trade surveillance |
approval_enabled | bool | False | Enable human-in-the-loop approval |
regulatory_limits | RegulatoryLimitConfig | (defaults) | Firm-wide limits |
approval_threshold_notional | float | 5000 | Notional threshold for approval |
approval_timeout_secs | float | 300 | Approval request TTL |
retention_days | int | 2555 | Data retention period (~7 years) |
db_path | str | None | None | SQLite database path |
surveillance_window_secs | float | 300 | Sliding window for surveillance |
wash_trade_threshold_secs | float | 5.0 | Buy+sell same market threshold |
spoof_cancel_threshold_secs | float | 2.0 | Order+cancel threshold |
layering_depth | int | 3 | Stacked orders threshold |
roles | dict[str, Role] | {} | Actor-to-role mapping |
kill_switch_requires_role | Role | RISK_MANAGER | Minimum role for kill switch |
approval_callback | Callable | None | None | Notification callback |
webhook_url | str | None | None | Webhook URL for alerts |
RegulatoryLimitConfig
| Field | Type | Default | Description |
|---|---|---|---|
max_position_per_market | dict[str, float] | {} | Per-market position limits |
max_total_notional | float | inf | Total portfolio notional cap |
max_concentration_pct | float | 25.0 | Max single-market concentration |
restricted_markets | set[str] | set() | Blacklisted market IDs |
max_daily_volume | float | inf | Daily volume cap |
max_orders_per_minute | int | 120 | Order rate limit |
max_cancel_ratio | float | 0.95 | Max cancel-to-order ratio |