Skip to main content

Deterministic runtime capital governance for autonomous trading systems

Project description

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

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

policygate_capital-0.2.0.tar.gz (43.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

policygate_capital-0.2.0-py3-none-any.whl (33.8 kB view details)

Uploaded Python 3

File details

Details for the file policygate_capital-0.2.0.tar.gz.

File metadata

  • Download URL: policygate_capital-0.2.0.tar.gz
  • Upload date:
  • Size: 43.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for policygate_capital-0.2.0.tar.gz
Algorithm Hash digest
SHA256 e31e718d97632aa5fa5aee360b4024915f916afdf81b9b6a422414aef4d55895
MD5 5c2f1a836ec3ce9c74c1f5972756ed9a
BLAKE2b-256 404a7263fc04c18c45330ead81374977f963a7bb0649b772ec47dd063b9cf5cf

See more details on using hashes here.

File details

Details for the file policygate_capital-0.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for policygate_capital-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 43b47d744e32016e696de9ee85a328c3a5926ea454db689a25e73ba4a3d59da7
MD5 6269d4290b88d7d0134b659524036156
BLAKE2b-256 3915caad23431739b59dc1feb93df399de50350c824b9feaaa4b992ddcd4d0e8

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page