Get order status by order_id
Chapter 18 introduced the order book; this chapter is the focused, single-order lookup you'll actually call after every place_order().
def poll_order_status(kite, order_id: str, timeout_s: int = 10, interval_s: float = 0.5) -> dict:
import time
elapsed = 0.0
while elapsed < timeout_s:
history = kite.order_history(order_id)
latest = history[-1]
if latest["status"] in ("COMPLETE", "REJECTED", "CANCELLED"):
return latest
time.sleep(interval_s)
elapsed += interval_s
return kite.order_history(order_id)[-1] # return best-known state even if still pending
order_id = kite.place_order(...)
result = poll_order_status(kite, order_id)
if result["status"] == "COMPLETE":
print(f"Filled {result['filled_quantity']} @ avg {result['average_price']}")
elif result["status"] == "REJECTED":
print(f"Rejected: {result['status_message']}")
Polling vs WebSocket order updates
Polling order_history() is simple and fine for a bot placing a handful of orders per day. For higher-frequency strategies, subscribe to order updates via the WebSocket ticker instead — much lower latency, no polling overhead:
def on_order_update(ws, data):
print("Order update:", data["order_id"], data["status"])
kws.on_order_update = on_order_update
Order updates arrive on the *same* KiteTicker connection used for market data (chapter 36) — no separate connection needed.
Terminal vs non-terminal states — know which is which
- Terminal (stop polling/waiting):
COMPLETE,REJECTED,CANCELLED. - Non-terminal (keep waiting or act):
OPEN,TRIGGER PENDING,OPEN PENDING,VALIDATION PENDING,MODIFY PENDING,CANCEL PENDING.
A bot that treats any non-COMPLETE status as "failed" will incorrectly abandon orders that are still legitimately in flight (e.g. OPEN resting on the book, or a pending modify/cancel request you just issued).