F&O instrument fields: expiry, lot size, strike
F&O rows in the instrument master (chapter 21) carry fields equity rows leave empty/zero.
nfo_df = kite.instruments("NFO")
option_row = nfo_df[
(nfo_df.name == "NIFTY") &
(nfo_df.instrument_type == "CE") &
(nfo_df.strike == 24500)
].sort_values("expiry").iloc[0]
print(option_row[["tradingsymbol", "expiry", "strike", "lot_size", "tick_size"]])
{
"tradingsymbol": "NIFTY26D2624500CE",
"expiry": "2026-12-26",
"strike": 24500.0,
"lot_size": 65, # you can only trade in multiples of this — current NIFTY lot size, see note below
"tick_size": 0.05, # minimum price increment
}
lot_size — quantity must always be a multiple of it
def validate_quantity(qty: int, lot_size: int):
if qty % lot_size != 0:
raise ValueError(f"Quantity {qty} is not a multiple of lot_size {lot_size}")
Placing an order with quantity=100 on an instrument with lot_size=65 is rejected outright — the exchange only accepts whole-lot orders on F&O. Equity has lot_size=1 (any integer quantity is valid).
tick_size — price must align to it
def round_to_tick(price: float, tick_size: float) -> float:
return round(price / tick_size) * tick_size
A limit order priced at ₹182.53 on an instrument with tick_size=0.05 gets rejected — round every computed limit price to the nearest valid tick before sending it.
instrument_type values you'll see in NFO/BFO
FUT (future), CE (call option), PE (put option). Combine with name (underlying, e.g. NIFTY, RELIANCE) and expiry to fully identify a contract.
Lot size changes periodically — and just did, again
NSE revised index F&O lot sizes effective the January 2026 expiry series: NIFTY 50 moved from 75 to 65, BANKNIFTY from 35 to 30. This is not a one-time historical event — NSE reviews and adjusts lot sizes periodically (roughly tracking index value, per SEBI's minimum-contract-value guidelines), and has done so multiple times. Never hardcode a lot size in your strategy code — always read it fresh from the instrument master for the specific contract you're about to trade, exactly as option_row["lot_size"] does above. Any code, tutorial, or forum post you find quoting a specific lot size number should be treated as a snapshot in time, not a constant.