Basket order placement

A "basket" is a set of orders you want treated as one logical unit for sizing/margin purposes — e.g. entering a 5-stock portfolio rebalance at once. Kite Connect has a margin-calculation API for baskets (basket_order_margins) but no single "place basket" call — placement is still sequential individual place_order() calls; the basket concept here is primarily about pre-trade margin checking across all legs together.

basket_params = [
    {"exchange": "NSE", "tradingsymbol": "INFY", "transaction_type": "BUY",
     "variety": "regular", "product": "CNC", "order_type": "MARKET", "quantity": 10},
    {"exchange": "NSE", "tradingsymbol": "TCS", "transaction_type": "BUY",
     "variety": "regular", "product": "CNC", "order_type": "MARKET", "quantity": 5},
    {"exchange": "NSE", "tradingsymbol": "RELIANCE", "transaction_type": "BUY",
     "variety": "regular", "product": "CNC", "order_type": "MARKET", "quantity": 8},
]

margin_check = kite.basket_order_margins(basket_params)
print(margin_check["final"]["total"])   # total margin needed for all legs together

Checking the basket's combined margin *before* firing any leg avoids the failure mode where legs 1-2 succeed and leg 3 gets rejected for insufficient funds partway through, leaving a partial rebalance instead of the complete intended basket.

Sequential placement with a pre-flight margin gate

def place_basket(kite, basket_params: list[dict]) -> list[dict]:
    margin_check = kite.basket_order_margins(basket_params)
    available = kite.margins(segment="equity")["available"]["cash"]
    if margin_check["final"]["total"] > available:
        raise RuntimeError("Basket exceeds available margin — aborting before placing any leg")

    results = []
    for params in basket_params:
        variety = params.pop("variety")
        order_id = kite.place_order(variety=variety, **params)
        results.append({"order_id": order_id, "params": params})
        time.sleep(0.3)   # avoid rate-limit bursts across legs
    return results

No native rollback if a later leg fails

Even with the margin pre-check, a later leg can still fail for other reasons (a rejected symbol, a circuit-limit issue on one specific stock). Track each leg's result and decide explicitly what to do with the already-filled legs — don't leave a half-executed basket unexamined.

Next: 062 — After-market orders (AMO)