Rebalance Activity
Read what auto-rebalance did to a position, and the events to track live.
Every auto-rebalance decision leaves a record, whether it traded or failed. Read the history per position, and the live state per config.
| Read | Endpoint |
|---|---|
| What rebalancing did to a position | GET /rebalance/{positionId}/events |
| The configs and their current drift | GET /rebalance/auto |
To set one up, see Auto-Rebalance.
Rebalance events
curl "https://pro-gateway.pearprotocol.io/rebalance/$POSITION_ID/events?limit=50" \
-H "x-api-key: $PEAR_API_KEY" \
-H "x-trade-account-id: $TRADE_ACCOUNT_ID"{
"limit": 50,
"items": [
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"autoRebalanceConfigId": "9c1b2d3e-4f56-4789-a0b1-c2d3e4f56789",
"positionId": "7d8e9f01-2345-4678-9abc-def012345678",
"weightSource": "INITIAL_WEIGHT",
"driftPct": "0.0563",
"currentWeights": { "0": 0.5563, "1": 0.4437 },
"targetWeights": { "0": 0.5, "1": 0.5 },
"status": "SUCCESS",
"createdAt": "2026-01-01T08:00:00.000Z"
}
]
}| Field | Meaning |
|---|---|
driftPct | The drift that tripped the threshold, measured the way that weightSource measures it. |
currentWeights | What the basket held when the decision was made. Keyed by instrument ID. |
targetWeights | What it traded towards. |
status | SUCCESS or FAILED. |
error | Present on FAILED, with the reason. |
Comparing currentWeights against targetWeights shows exactly how far the basket had drifted and what the rebalance aimed at. On a LIVE_BETA config the targets come from the live beta, so they move between events; on INITIAL_WEIGHT they are constant.
Page with limit and cursor, as with the other list endpoints.
Watch for failures
FAILED events are the ones to alert on. Three consecutive failures pause the config, so a burst of them means rebalancing is about to stop:
GET /rebalance/{positionId}/events?limit=3Three FAILED in a row and the config is paused, or about to be. A single SUCCESS resets the streak. See Auto-Rebalance.
Config state
GET /rebalance/auto returns the configs themselves, filtered by status, weightSource, or positionId, and paged with limit and cursor:
GET /rebalance/auto?status=PAUSEDThat is the query worth running on a schedule: it lists every config that has stopped working and why, in one call. pausedReason is USER, POSITION_CHANGED, REPEATED_FAILURES, or INVALID_LIVE_BETA_EXPOSURE.
A LIVE_BETA config also carries its timeframe — 1h, 4h, or 1d, the candle feed driving the comparison — and its live drift, so you can show a user how close the position is to its next rebalance without waiting for an event:
{
"limit": 20,
"items": [
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"positionId": "7d8e9f01-2345-4678-9abc-def012345678",
"status": "ACTIVE",
"minimumDriftPct": "0.05",
"weightSource": "LIVE_BETA",
"timeframe": "4h",
"beta": {
"state": "TRACKING",
"impliedEntryBeta": "0.9120",
"lastDerivedBeta": "0.9642",
"lastProcessedBetaTime": "2026-01-01T08:00:00.000Z",
"driftPct": "0.0572"
},
"createdAt": "2026-01-01T00:00:00.000Z",
"updatedAt": "2026-01-01T08:00:00.000Z"
}
]
}beta.state runs PENDING → BASELINED → TRACKING. Only TRACKING carries both sides of the comparison, so lastDerivedBeta, lastProcessedBetaTime, and driftPct exist only there. impliedEntryBeta appears from BASELINED on.
Compare driftPct against the config's minimumDriftPct. It can also be absent inside TRACKING, when the baseline is zero and no fraction can be derived.
Live events
Subscribe to user_events on the WebSocket and read five topics:
| Topic | Fires when |
|---|---|
rebalance.created | A config is created. |
rebalance.updated | A config changes: threshold, timeframe, or status. |
rebalance.executed | A rebalance ran. Read the matching event for whether it succeeded. |
rebalance.paused | A config stopped. Read pausedReason for why. |
rebalance.cancelled | A config is cancelled. |
rebalance.paused is the one that needs handling: it fires for a closed position, an invalid LIVE_BETA shape, and the repeated-failure circuit breaker alike, and until you resume it the position is no longer being kept on target.
An automatic pause also files a notification, so it survives the user not being on the page. Read those with GET /notifications.
The trades themselves
A rebalance places real orders, so it also appears in the ordinary trade record: an execution with the venue orders it sent, the fills those produced, and a position.updated event. The rebalance event tells you why it traded; the execution tells you what happened at the venue.