PortfolioGuard
PortfolioGuard enforces account-wide exposure limits across every running strategy simultaneously.
What it does
PortfolioGuard enforces account-wide exposure limits across every running strategy simultaneously. It tracks aggregate notional, rolling 24-hour drawdown, per-market concentration, and correlated-cluster concentration. When an incoming order would breach any of these limits, it is either downsized to the safe remaining budget or rejected outright. PortfolioGuard does not change the strategy intent, the market, or the direction — it only sets the maximum size an order is allowed to carry.
Pipeline placement
Applies to: Every OrderIntent — checks account-level, market-level, and cluster-level limits
Why it matters
| If this fails | Consequence |
|---|---|
| Aggregate notional exceeds account limit | Multiple strategies running simultaneously could push total exposure beyond what the account balance can safely support, creating risk of insolvency if several positions move adversely at the same time. Worked example Setup: Account aggregate notional is 38,000 pUSD across 6 markets. Cap is 50,000 pUSD. Strategy proposes a new 14,000 pUSD entry on market 0x05a. Without bot: Each strategy enforces only its own per-strategy budget. The 14,000 entry takes total notional to 52,000, breaching the account cap by 4%. The breach is only caught at the daily reconciliation run. With bot: PortfolioGuard sums across all strategies, computes 38,000 + 14,000 = 52,000, and votes RESHAPE_REQUIRED with `cap_remaining_pUSD=12,000`. The strategy resubmits at 12,000 and the order is approved. |
| Single-market concentration unchecked | Concentrating too much capital in one market means a single bad resolution or liquidity event can cause a disproportionate drawdown relative to the account size. |
| 24-hour drawdown not tracked cross-strategy | Each strategy sees only its own losses. Without a cross-strategy drawdown check, the total intraday loss can exceed a level the account is designed to tolerate. |
| Correlated cluster exposure ignored | On neg-risk or thematically linked markets, multiple strategies may each hold positions that all resolve together. Cluster concentration can make seemingly diversified positions highly correlated. |
Inputs
Polymarket inputs
| Input | Source | Required | Use |
|---|---|---|---|
| Account balance and available USDC | on-chain | required | Establish the total capital base against which percentage-of-account limits are applied. |
| Current open positions per market with notional sizes | Data API | required | Compute aggregate notional across all open positions and per-market exposure. |
| Realised and unrealised P&L over rolling 24 hours | Data API | required | Calculate rolling drawdown to enforce the max_24h_drawdown_pct circuit breaker. |
Internal inputs
| Input | Source | Required | Use |
|---|---|---|---|
| Per-strategy order intent queue and current allocations | StrategyRegistry | required | Aggregate pending and active allocations from all strategies before approving new additions. |
| KillSwitch active flag | KillSwitch | required | Immediately reject all orders if the KillSwitch has been triggered. |
| Cluster mapping for correlated markets | Admin UI | optional | Group neg-risk and thematically linked markets into clusters for aggregate concentration checks. |
Authority
What this bot is permitted to do
State
Readiness
General live
Status
live
Class
Guardrail
Default mode
general_live
Developer owner
Polytraders core — Risk pod
Capital impact
Direct
Reason codes emitted
| Code | Severity | Meaning | Action |
|---|---|---|---|
| KILL_SWITCH_ACTIVE | HARD_REJECT | Global kill switch is active. | Immediately return HARD_REJECT without fetching portfolio state. |
| STALE_MARKET_DATA | HARD_REJECT | Account balance or position data could not be fetched. | Return HARD_REJECT; retry on next fresh fetch. |
| STRATEGY_BUDGET_EXCEEDED | HARD_REJECT | One or more budget limits (aggregate, drawdown, per-market, cluster) are exhausted. | Return HARD_REJECT or RESHAPE_REQUIRED depending on which limit is binding. |
| PORTFOLIO_GUARD_DRAWDOWN_BREACHED | HARD_REJECT | Rolling 24-hour drawdown exceeds max_24h_drawdown_pct hard limit. | Return HARD_REJECT; circuit breaker remains active until drawdown falls below warning threshold or manual reset. |
| PORTFOLIO_GUARD_NOTIONAL_RESHAPE | RESHAPE | Order size exceeds remaining aggregate, per-market, or cluster budget but does not trigger a hard reject. | Return RESHAPE_REQUIRED with constraints.max_size_usd = min(remaining budgets). |
| PORTFOLIO_GUARD_CLUSTER_LIMIT | HARD_REJECT | Cluster exposure would exceed max_cluster_pct. | Return HARD_REJECT or RESHAPE_REQUIRED depending on budget remaining. |
| RECONCILIATION_DRIFT_OBSERVED | WARN | Position ledger data from Data API diverges from the last cached state by more than 1%. | Log drift delta and emit WARN; continue with conservative (lower) position estimate. |
Related bots in Risk Guardrail
Used by
Reverse index — strategies that currently reference risk.portfolioguard. If you change this bot's authority or reason codes, these strategies must re-pass shadow.
| Strategy | State | Activity |
|---|---|---|
| US Elections — sentiment fade | demo-wired | last triggered 18m ago |
Showing 1 of 1 · demo-wired ≠ production-live
Why this matters
Risk Guardrail bots does NOT propose intents or sign orders; only permits or blocks. Understanding the authority boundary prevents misuse and makes promotion-gate reviews faster and more reliable. View raw spec JSON →