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
Subscribe to tpslUpdates and buffer incoming updates
Fetch tpslBook snapshot with block height
Apply buffered updates where
height > snapshot_heightContinue 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: trueto see position-attached orders vs standalone triggersMarket microstructure research — study how TP/SL placement evolves relative to price action
SDK
The Hydromancer Python SDK handles sync automatically:
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 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) and doesn't affect handling.
Building a heatmap
To build a trigger-order heatmap:
Bucket by price — group orders by
triggerPxinto price buckets (e.g., $500 intervals for BTC)Weight by size — sum
szwithin each bucket for volume-weighted heatmapSplit by type — separate take profits (
orderTypecontains "Take Profit") from stop losses ("Stop") for distinct color layersSplit 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
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
Last updated