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)

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.1.0.tar.gz (17.5 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.1.0-py3-none-any.whl (16.2 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: policygate_capital-0.1.0.tar.gz
  • Upload date:
  • Size: 17.5 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.1.0.tar.gz
Algorithm Hash digest
SHA256 2b384ef96eb4abe52c332a7fbb0fbce659dbb5f976d9eb0fb098a4431c36b49f
MD5 48508eea075af2d5582c038167139930
BLAKE2b-256 f89b1405f25b0446c235c8a7c697436db345e45882ad8f794a6afee8fcd7d826

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for policygate_capital-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3c831b832c586dd6696e94d7305531e778bf46a957a55e792c5c4edb7968c5c9
MD5 977d5d4ed9a34786d87ee9393870a1ad
BLAKE2b-256 ffe07c3b658000204d476cba1375dfc3c2bfbf8b519e37c08e418b87a1cb3caa

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