# Build a prop risk tool

> Watch equity on many accounts, enforce daily and maximum drawdown, and flatten on breach.

Source: https://tickwire.io/docs/guides/prop-risk-tool/

A prop risk tool has one job: never miss a breach. That means knowing when you **can't** see an
account, not just when it's losing.

## The shape

1. Connect each trader's account, ideally with the **investor password** if you only monitor, or
   the master password if you must flatten.
2. Subscribe to each account's stream for equity and positions.
3. Treat any health other than `healthy` as "not watching" and alert on it.
4. On breach, flatten with an idempotent close, then verify.

## 1. Stream equity

```js
const ws = new WebSocket(`wss://api.tickwire.io/users/current/accounts/${id}/ws?auth-token=${token}`);
ws.onopen = () => ws.send(JSON.stringify({ type: "subscribe" }));
ws.onmessage = (m) => {
  const f = JSON.parse(m.data);
  if (f.type === "accountInformation" || f.type === "accountInformationUpdated") {
    check(id, f.accountInformation.equity, f.accountInformation.balance);
  }
  if (f.type === "health" && f.status !== "healthy") notWatching(id, f);
};
```

Keep the last `seq` you processed. If the socket drops, reconnect with
`{"type":"subscribe","sync":{"lastSeq":<seq>}}` and you'll get what you missed. See
[Streaming](https://tickwire.io/docs/streaming/).

## 2. Day boundaries in broker time

Daily loss limits usually reset at the **broker's** midnight. Take the start-of-day balance at the
broker's day change, not at UTC midnight. See [Time zones](https://tickwire.io/docs/time-zones/).

## 3. Know when you're blind

Register a webhook for `account.health_changed`. If an account goes `disconnected` or `down`, your
tool isn't protecting that trader. Say so in your UI rather than showing the last equity as current.

## 4. Flatten on breach

```bash
curl -s -X POST "$TW/users/current/accounts/$ID/trade" \
  -H "auth-token: $TW_KEY" \
  -H "Idempotency-Key: breach-$ID-2026-09-23" \
  -H "X-Actor: risk-engine" -H "X-Reason: daily loss 5% breached" \
  -H "content-type: application/json" \
  -d '{"actionType": "POSITIONS_CLOSE_SYMBOL", "symbol": "EURUSD"}'
```

Across many accounts at once, the batch endpoint `POST /v1/orders/close` takes
selectors (all positions, by symbol, by magic) for up to 20 accounts in one idempotent call.

Then verify: read `positions` until it's empty. If any close came back `unknown`, retry with the
**same** key; see [Idempotency](https://tickwire.io/docs/idempotency/).

## 5. Or let Tickwire enforce it

Our risk engine can run the rule for you: drawdown and profit trackers per day, week, month and
lifetime, with absolute or relative thresholds and broker-time day boundaries. The guard runs
**next to the terminal**, so it keeps enforcing even if our central services or yours are
unreachable. Breaches arrive as webhooks. This part is not available yet.
