Skip to main content

PolicyGate Capital

Deterministic runtime capital governance for autonomous trading systems.

PolicyGate Capital is a policy engine that evaluates proposed orders against capital constraints and returns ALLOW, DENY, or MODIFY decisions. It enforces position limits, exposure caps, loss limits, execution throttles, and kill switches — deterministically, with an append-only audit trail.

Install

pip install policygate-capital

Quick Start

Define a policy

# policy.yaml
version: "0.1"
timezone: "UTC"

defaults:
  mode: "enforce"    # or "monitor" (log violations, always ALLOW)
  decision: "deny"   # fail-closed on evaluation errors

limits:
  exposure:
    max_position_pct: 0.10        # 10% of equity per symbol
    max_gross_exposure_x: 2.0     # 2x equity total
    max_net_exposure_x: 1.0       # 1x equity net
  loss:
    daily_loss_limit_pct: 0.02    # -2% daily loss triggers deny
    max_drawdown_pct: 0.05        # -5% drawdown triggers kill switch
  execution:
    max_orders_per_minute_global: 20
    max_orders_per_minute_by_strategy: 10
  kill_switch:
    trip_on_rules: ["LOSS-002"]
    trip_after_n_violations: 3
    violation_window_seconds: 300

overrides:
  symbols:
    AAPL:
      exposure:
        max_position_pct: 0.05    # tighter limit for AAPL
        max_gross_exposure_x: 2.0
        max_net_exposure_x: 1.0
  strategies: {}

Use as a library

from policygate_capital.engine.policy_engine import PolicyEngine
from policygate_capital.models.intent import OrderIntent
from policygate_capital.models.state import (
    ExecutionState, MarketSnapshot, PortfolioState,
)

engine = PolicyEngine("policy.yaml")

intent = OrderIntent(
    intent_id="order-001",
    timestamp="2026-02-18T00:00:00Z",
    strategy_id="momentum_v1",
    account_id="acct_1",
    instrument={"symbol": "AAPL", "asset_class": "equity"},
    side="buy",
    order_type="market",
    qty=100,
    limit_price=None,
)

portfolio = PortfolioState(
    equity=100000.0,
    start_of_day_equity=100000.0,
    peak_equity=100000.0,
    positions={},
)

market = MarketSnapshot(
    timestamp="2026-02-18T00:00:00Z",
    prices={"AAPL": 200.0},
)

execution = ExecutionState()

decision = engine.evaluate(intent, portfolio, market, execution)
print(decision.decision)       # "MODIFY" — reduced to fit 10% cap
print(decision.modified_intent.qty)  # 50.0

Use as a CLI

policygate-eval \
  --policy policy.yaml \
  --intent intent.json \
  --portfolio portfolio.json \
  --market market.json \
  --execution execution.json \
  --audit-log audit.jsonl \
  --pretty

Exit codes: 0 = ALLOW/MODIFY, 1 = DENY, 2 = error.

Rules

Rule Domain Severity Trigger
KILL-001 Kill switch CRIT Kill switch active
LOSS-001 Loss HIGH Daily return breaches limit
LOSS-002 Loss CRIT Drawdown breaches limit (trips kill switch)
EXEC-001 Execution HIGH Global order rate exceeded
EXEC-002 Execution HIGH Per-strategy order rate exceeded
EXP-001 Exposure HIGH Position size breaches limit (MODIFY if possible)
EXP-002 Exposure HIGH Gross exposure breaches limit
EXP-003 Exposure HIGH Net exposure breaches limit
SYS-001 System CRIT Missing/invalid price (fail-closed)

Evaluation Order

Fixed and deterministic:

  1. SYS-001 — Missing data check (fail-closed)
  2. KILL-001 — Kill switch
  3. LOSS-001/002 — Loss limits (daily loss, drawdown)
  4. EXEC-001/002 — Execution throttles
  5. EXP-001/002/003 — Exposure checks (with MODIFY for position cap)

Monitor Mode

Set defaults.mode: "monitor" to log all violations without blocking orders. Useful for shadow-running policies against live traffic before enforcement.

SYS-001 (missing price) still denies in monitor mode — you can't evaluate without data.

Audit Trail

Every evaluation emits an append-only JSONL event containing:

  • Original intent, portfolio state, market snapshot, execution state
  • Decision with all violations and computed evidence
  • SHA-256 hash of the policy file
  • Engine version and timestamp

Audit events can be replayed to verify determinism:

from policygate_capital.engine.replay import replay_event, decisions_match

original, replayed = replay_event(event, policy)
assert decisions_match(original, replayed)

Documentation

License

MIT

Metadata

Release files for policygate-capital 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for policygate-capital 0.2.0
File Size Uploaded
policygate_capital-0.2.0.tar.gz 43.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for policygate-capital 0.2.0
File Interpreter ABI Platform
policygate_capital-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 77.4 kB

Release files / policygate_capital-0.2.0.tar.gz

Download URL policygate_capital-0.2.0.tar.gz
Size 43.6 kB
Tags Source
SHA-256 checksum
How to use checksums
e31e718d97632aa5fa5aee360b4024915f916afdf81b9b6a422414aef4d55895
BLAKE2b-256 checksum
How to use checksums
404a7263fc04c18c45330ead81374977f963a7bb0649b772ec47dd063b9cf5cf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.5

Release files / policygate_capital-0.2.0-py3-none-any.whl

Download URL policygate_capital-0.2.0-py3-none-any.whl
Size 33.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
43b47d744e32016e696de9ee85a328c3a5926ea454db689a25e73ba4a3d59da7
BLAKE2b-256 checksum
How to use checksums
3915caad23431739b59dc1feb93df399de50350c824b9feaaa4b992ddcd4d0e8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.5

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page