> For the complete documentation index, see [llms.txt](https://docs.hydromancer.xyz/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.hydromancer.xyz/readme/builder-guides/tpsl-heatmap-streaming.md).

# TP/SL heatmap streaming

Stream real-time trigger order (take profit / stop loss) updates and build heatmaps showing where TP/SL orders cluster at different price levels.

### How it works

1. Subscribe to [tpslUpdates](/readme/websocket/tpslupdates.md) and buffer incoming updates
2. Fetch [tpslBook](/readme/rest-api/market-data/tpslbook.md) snapshot with block height
3. Apply buffered updates where `height > snapshot_height`
4. Continue applying live updates

Trigger orders are **immutable** — only `add` and `remove` diffs, no modifications. This makes the sync model simpler than L4 orderbooks (no partial fills, no matching required).

### Use cases

* **TP/SL heatmaps** — visualize where stop losses and take profits cluster relative to current price. Dense clusters = potential liquidation cascades or profit-taking zones.
* **Liquidation risk analysis** — large clusters of stop losses below support indicate potential cascade risk
* **Smart money tracking** — monitor where large accounts place their TP/SL levels
* **Position-level TP/SL monitoring** — filter `isPositionTpsl: true` to see position-attached orders vs standalone triggers
* **Market microstructure research** — study how TP/SL placement evolves relative to price action

### SDK

The [Hydromancer Python SDK](https://github.com/hydromancerxyz/hydromancer-sdk) handles sync automatically:

```python
from hydromancer_sdk import TpslClient

def on_update(client, height, adds, removes):
    book = client.get_book("BTC")
    if book:
        print(f"BTC: {book.order_count} orders "
              f"(TP={len(book.take_profits)}, SL={len(book.stop_losses)})")

        # Get orders near current price
        near = book.orders_near_price(105000, pct=5)
        print(f"  Within 5% of $105K: {len(near)} orders")

        # Price level heatmap data
        levels = book.price_levels()
        for px, count in levels.items():
            if count >= 3:
                print(f"  ${px}: {count} orders")

client = TpslClient(coins=["BTC", "ETH"], on_update=on_update)
await client.run()
```

See [examples/stream\_tpsl.py](https://github.com/hydromancerxyz/hydromancer-sdk/blob/main/examples/stream_tpsl.py) for a complete streaming example.

### Manual implementation

If implementing without the SDK, maintain a map of `oid → order` per market:

* **add** — insert or replace order by `oid` (idempotent upsert)
* **remove** — delete order by `oid`

No matching or modification logic is needed. Every `remove` diff is terminal — just drop the order from your map. The `reason` field is informational (see [tpslUpdates](/readme/websocket/tpslupdates.md#remove-handling)) and doesn't affect handling.

### Building a heatmap

To build a trigger-order heatmap:

1. **Bucket by price** — group orders by `triggerPx` into price buckets (e.g., $500 intervals for BTC)
2. **Weight by size** — sum `sz` within each bucket for volume-weighted heatmap
3. **Split by type** — separate take profits (`orderType` contains "Take Profit") from stop losses ("Stop") for distinct color layers
4. **Split by side** — `"A"` (sell-side triggers, typically stop losses below price) vs `"B"` (buy-side triggers, typically take profits above price)

### Key details

* Updates arrive per-block (\~70ms block time on Hyperliquid)
* \~110K trigger orders across \~330 markets (typical for mainnet)
* Block processing latency: \~20µs p50 (near-instant)
* Orders are fully immutable — no size or price changes after placement
* `isPositionTpsl: true` = attached to a position (auto-cancel when position closes)
* `reduceOnly: true` = almost all trigger orders (reduce-only by nature)

### Differences from L4 orderbook

|                     | L4 orderbook                     | TPSL book                |
| ------------------- | -------------------------------- | ------------------------ |
| **What**            | Resting limit orders on the book | Untriggered TP/SL orders |
| **Diffs**           | `new`, `update`, `remove`        | `add`, `remove` only     |
| **Modifications**   | Yes (partial fills change size)  | No (immutable)           |
| **Matching**        | Required (crossed orders)        | Not needed               |
| **Snapshot format** | Binary (multi-zstd msgpack)      | JSON                     |
| **Typical count**   | \~460K orders                    | \~110K orders            |


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.hydromancer.xyz/readme/builder-guides/tpsl-heatmap-streaming.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
