Handle full-mode ticks (depth, OI)
{
"tradable": True,
"mode": "full",
"instrument_token": 408065,
"last_price": 1478.9,
"last_traded_quantity": 5,
"average_traded_price": 1472.3,
"volume_traded": 3821450,
"total_buy_quantity": 452100,
"total_sell_quantity": 398700,
"ohlc": {"open": 1465.0, "high": 1482.0, "low": 1460.5, "close": 1470.2},
"oi": 0,
"oi_day_high": 0,
"oi_day_low": 0,
"timestamp": datetime(...),
"depth": {
"buy": [{"price": 1478.8, "quantity": 75, "orders": 3}, ...],
"sell": [{"price": 1479.0, "quantity": 60, "orders": 2}, ...],
},
}
OI (open interest) — F&O only, and only meaningful mode-to-mode
oi fields are populated for F&O instruments, zero for equity. OI *changes* (not the absolute level) are what most F&O strategies actually watch — rising OI with rising price suggests fresh long buildup, rising OI with falling price suggests fresh short buildup, falling OI generally means unwinding. Track deltas, not just snapshots:
oi_history = {} # token -> previous OI
def track_oi_change(tick):
token = tick["instrument_token"]
prev = oi_history.get(token)
oi_history[token] = tick["oi"]
if prev is not None:
return tick["oi"] - prev
return 0
Depth in full-mode ticks vs the REST quote() depth
Same shape as chapter 26's REST depth, but arriving continuously — this is the live-updating version you'd use for a strategy that watches order-book imbalance in real time rather than a point-in-time check before firing one order.
def order_book_imbalance(depth: dict) -> float:
buy_vol = sum(level["quantity"] for level in depth["buy"])
sell_vol = sum(level["quantity"] for level in depth["sell"])
total = buy_vol + sell_vol
return (buy_vol - sell_vol) / total if total else 0.0
Bandwidth cost
Full mode ticks are the largest payload of the three modes and arrive most frequently for liquid instruments — only subscribe in full mode for instruments where you actually consume depth/OI (chapter 37).