Halyrd’s risk system operates in two independent layers: a policy layer that evaluates each proposed trade against configured drawdown and loss limits before submission, and a physics layer enforced by the TWAK signing key at the protocol level that prevents orders from exceeding absolute hard caps regardless of what the policy layer passes. These two endpoints let you inspect both layers — the first shows how much headroom remains on each live risk rule, and the second gives you a full audit log of every order that was blocked and the reason it was rejected.
GET /agents//risk/objectives
Returns the current measured value and remaining headroom for each active risk rule. Poll this endpoint to monitor how close the agent is to any limit before it would be forced to stand aside.
GET http://localhost:8000/agents/current/risk/objectives
Response
[
{
"rule": "max_drawdown",
"current": 0.035,
"limit": 0.20,
"headroom_pct": 82.5
},
{
"rule": "daily_drawdown",
"current": 0.021,
"limit": 0.08,
"headroom_pct": 73.8
},
{
"rule": "consecutive_losses",
"current": 1,
"limit": 4,
"headroom_pct": null
}
]
| Field | Type | Description |
|---|
rule | string | Identifier for the risk rule, e.g. max_drawdown, daily_drawdown, consecutive_losses. |
current | number | The rule’s current measured value. Drawdown rules use decimal fractions; count-based rules use integers. |
limit | number | The threshold at which the rule triggers and the agent stands aside. |
headroom_pct | number | null | Percentage of the limit that remains unused — (limit - current) / limit × 100. Returns null for count-based rules (e.g. consecutive_losses) where a percentage headroom isn’t meaningful. |
GET /agents//risk/blocks
Returns the complete chronological log of orders that were blocked by either the policy layer or the TWAK physics layer. Each entry records which layer blocked the order, which rule triggered, and the exact reason the order was rejected.
GET http://localhost:8000/agents/current/risk/blocks
Response
[
{
"ts": "2025-06-22T15:00:00Z",
"layer": "policy",
"rule": "daily_drawdown",
"reason": "Trade would use 2.1% of daily budget; only 1.9% remaining.",
"order_ref": "ord_xyz789"
},
{
"ts": "2025-06-22T18:05:00Z",
"layer": "physics",
"rule": "per_trade_cap",
"reason": "Order size 520 USDT exceeds per-trade cap 500 USDT.",
"order_ref": "ord_abc456"
}
]
| Field | Type | Description |
|---|
ts | string | ISO 8601 timestamp when the block occurred. |
layer | string | Which enforcement layer blocked the order: policy (pre-submission rule evaluation) or physics (TWAK signing-key hard cap). |
rule | string | The specific rule that triggered the block, e.g. daily_drawdown, per_trade_cap. |
reason | string | Human-readable explanation of why the order was rejected, including the relevant values at the time. |
order_ref | string | Internal reference ID for the blocked order, useful for correlating with journal entries. |
Layer descriptions
| Layer | Description |
|---|
policy | The agent’s configurable rule engine. Evaluates drawdown budgets, consecutive-loss limits, and other soft constraints before an order is submitted. Policy rules are adjustable via PATCH /agents/{id}/config. |
physics | Hard limits enforced by the TWAK signing key at the protocol level. These operate independently of agent software and cannot be overridden by the policy layer or via config — they are a last-resort safety mechanism. |
Quote rejections — caused by price divergence, stale quotes, or insufficient liquidity — are a separate category from policy and physics blocks. They are emitted as quote_rejected WebSocket events and surfaced in the blocked orders log in the dashboard UI, but they do not appear in this endpoint’s response.