NSE F&O in Pine: sessions, lot sizes and expiries

IST session guards, last-entry cut-offs, NIFTY, BANKNIFTY and SENSEX expiry days, current lot sizes with sources, and MCX hours for GOLDM and SILVERM.

Updated 30 Aug 2026

Most Pine examples on the internet assume a market that trades around the clock. An NSE intraday script has three constraints those examples never mention: a session that opens at 09:15 and closes at 15:30 IST, a broker that squares off intraday positions before the close, and contracts that expire on a calendar the exchange changes every year or two. This page covers the Pine idioms for each, with the current numbers and where they come from.

Everything below was checked on 2026-08-30. Lot sizes and expiry days change; the sources are linked so you can re-check them.

The IST clock

Without a timezone argument, hour(), minute() and time() use syminfo.timezone, the exchange timezone. For NSE and MCX that is already IST, but pass "Asia/Kolkata" explicitly so the script still reads correctly on a non-Indian symbol or a copied chart. Work in minutes since midnight; it keeps every comparison a single integer.

//@version=6hh    = hour(time,   "Asia/Kolkata")mm    = minute(time, "Asia/Kolkata")tMins = hh * 60 + mm
inSession = tMins >= 9 * 60 + 15 and tMins < 15 * 60 + 30

The same thing as a session string, which is what time() and input.session() expect:

nseSession = input.session("0915-1530", "NSE session")inSession  = not na(time(timeframe.period, nseSession, "Asia/Kolkata"))

TradingView's sessions guide covers the string format, including multi-segment sessions and day-of-week suffixes.

Last-entry cut-off and square-off

Intraday (MIS) positions get squared off by the broker before the close, at a time each broker sets. A script that can still enter at 15:20 will hand its exit to that square-off, at whatever price the market shows. Two guards fix this: a cut-off after which no new entries are placed, and an explicit flat-by time that closes and cancels everything.

lastEntryHr  = input.int(14, "No new entries after (hour, IST)",   minval = 10, maxval = 15)lastEntryMin = input.int(30, "No new entries after (minute)",      minval = 0,  maxval = 59)
canEnter = tMins <  lastEntryHr * 60 + lastEntryMinisEOD    = tMins >= 15 * 60 + 15                     // flat by 15:15
if isEOD and strategy.position_size != 0    strategy.close_all(comment = "EOD square-off")if isEOD    strategy.cancel_all()

Why 14:30 on a 15:30 close: a 15-minute ORB entry at 14:45 has two bars before the 15:15 square-off, which is not enough room for a stop or a target to resolve. Set the cut-off so the last entry has the same number of bars as the strategy's average holding time. Re-assert exit orders every bar while in a position; Pine runs the script top to bottom on every bar, and an exit declared once is not remembered.

Expiry cadence, 2025 to 2026

Two regulatory changes rewrote the Indian expiry calendar. From 20 November 2024, each exchange keeps one weekly index-options expiry: NSE kept NIFTY and discontinued the BANKNIFTY, FINNIFTY and MIDCPNIFTY weeklies, per Zerodha's support note. From 1 September 2025, NSE moved its expiry day from Thursday to Tuesday and BSE moved to Thursday, per Strota and OneTradeJournal.

IndexExchangeWeekly expiryMonthly expiryHoliday rule
NIFTYNSETuesdayLast TuesdayPrevious trading day
BANKNIFTYNSENone since 20 Nov 2024Last TuesdayPrevious trading day
MIDCPNIFTYNSENone since 20 Nov 2024Last TuesdayPrevious trading day
SENSEXBSEThursdayLast ThursdayPrevious trading day
Stock F&O (RELIANCE, TCS)NSENoneLast TuesdayPrevious trading day

Sources: OneTradeJournal calendar and Strota, both secondary. The exchange's own calendar is the final word, and both sources say so.

A script does not need to know the expiry date unless it trades options or rolls futures. It does need to know that the continuous ticker it is charting rolls on that date, which is the next section.

Continuous futures tickers

TradingView charts index futures through continuous tickers: NSE:NIFTY1! is the front month, NSE:NIFTY2! the next. The chart splices contracts on expiry, so a 15-minute strategy on NIFTY1! sees a price jump on the roll that no single contract had. Backtests across many months should be read with that in mind.

For alerts, send the root symbol or the continuous ticker; either resolves. Sarathi strips the exchange prefix (NSE:, BSE: or MCX:) and the 1! or 2! suffix and looks up the root in its instrument table, so NSE:BANKNIFTY1!, BANKNIFTY1! and BANKNIFTY all land on the same instrument. GOLD maps to GOLDM and SILVER to SILVERM because the mini contracts are the retail-sized ones. The full list of accepted aliases is under /developers.

Lot sizes

SEBI's December 2024 circular put index contract values in a ₹15 lakh band and made lot revisions periodic. NSE circular FAOP/70616, dated 3 October 2025, cut the index lots for contracts from January 2026. The primary lives in the NSE circular archive; NSE's site rejects some automated fetches, hence the member-site mirror linked here.

InstrumentLotSinceSource
NIFTY65 (was 75)Jan 2026 contractsNSE FAOP/70616
BANKNIFTY30 (was 35)Jan 2026 contractsNSE FAOP/70616
MIDCPNIFTY120 (was 140)Jan 2026 contractsNSE FAOP/70616
SENSEX20 (was 10)Jan 2026 contractsSahi, Ventura (secondary)
GOLDM100 gStanding specMCX Gold Mini specification; NiftyTrader
SILVERM5 kgStanding specMCX Silver Mini specification; Dhan
RELIANCE, TCSRevised half-yearlyLatest NSE stock lot fileNSE contract file, not reproduced here

Stock lots are revised every six months on the same SEBI rule, so this page does not print a number that will be wrong by the next revision. Read the lot from the NSE contract file or from the /dashboard/instruments table, which the server refreshes from the exchange masters.

lotSize = input.int(65, "Lot size (check NSE contract file)", minval = 1)lots    = input.int(1,  "Lots per signal", minval = 1)qty     = lotSize * lots

Index tick sizes step with the index level on NSE: 0.05 up to 15,000, 0.10 to 30,000, and 0.20 above, per the NSE contract specifications. Format prices in a payload with str.tostring(x, "#.##") so a 0.05 tick survives the round trip.

MCX hours for GOLDM and SILVERM

Bullion on MCX trades Monday to Friday, 09:00 to 23:30 IST, extending to 23:55 while US daylight saving is in force, per MCX's contract specification sheets and Dhan's SILVERM summary. Two expiry rules apply: Gold Mini contracts expire on the 5th of the contract month, Silver Mini on the last calendar day, with the previous working day used when that falls on a holiday.

ContractTrading unitQuoteTickSession (IST)Expiry
GOLDM100 g₹ per 10 g₹109:00 to 23:30 / 23:555th of contract month
SILVERM5 kg₹ per kg₹109:00 to 23:30 / 23:55Last calendar day

The DST switch matters for a session string. Either take the session as an input and change it twice a year, or compute the close from a boolean:

usDst      = input.bool(true, "US daylight saving in force")mcxSession = usDst ? "0900-2355" : "0900-2330"inMcx      = not na(time(timeframe.period, mcxSession, "Asia/Kolkata"))

An intraday commodity script also needs its own square-off time; the evening session means "flat by 15:15" is the wrong default. Most brokers square off MCX intraday positions shortly before the session close.

Sarathi's tier-1 instruments

Sarathi's webhook accepts any symbol in its universe. Tier 1 is the eight instruments the house strategies were written for; tier 2 is the NIFTY 50 names that also have F&O contracts. The table shows how each tier-1 instrument's expiry is encoded, which is the rule the broker adapter will use to pick a concrete contract. Planned

SymbolExchangeKindExpiry ruleSession (IST)
NIFTYNSEIndexWeekly Tuesday, monthly last Tuesday09:15 to 15:30
BANKNIFTYNSEIndexMonthly last Tuesday09:15 to 15:30
MIDCPNIFTYNSEIndexMonthly last Tuesday09:15 to 15:30
SENSEXBSEIndexWeekly Thursday, monthly last Thursday09:15 to 15:30
GOLDMMCXCommodity5th of contract month09:00 to 23:30 / 23:55
SILVERMMCXCommodityLast calendar day09:00 to 23:30 / 23:55
RELIANCENSEStockMonthly last Tuesday09:15 to 15:30
TCSNSEStockMonthly last Tuesday09:15 to 15:30

Alerts for a symbol outside the universe are rejected with a 400 and a hint listing the tier-1 symbols, so a typo in sym never becomes a card. The webhooks page covers the rest of the inbound contract.

Try it in Sarathi

The Studio writes Pine v6 with the IST clock, the cut-off inputs and the square-off block from this page already in the header. Post the alert to your webhook, keep the account on the paper route, and each signal arrives as a card in Telegram and on the web dashboard. You confirm at ½, 1× or 2×, or skip; nothing is placed otherwise.

Questions

Sarathi writes and checks Pine v6 strategies; paper trade before you connect a broker.

Open the Studio
Sarathiसारथी

Sarathi means charioteer. The charioteer drives; the warrior decides when to shoot. Here the software drives, and you confirm every order.

Status

Pre-launch · pre-revenue
Bridge verified live 24 Aug 2026

Get started →

Sarathi is an execution bridge, not an investment adviser, and is not registered with SEBI as a Research Analyst. Nothing on this page is advice or a recommendation to trade. Sarathi never holds your funds or securities; every order is placed by you, on your own broker account. Derivatives trading carries substantial risk of loss.

Chart illustrations use TradingView Lightweight Charts™. Every price on this page is made up.

TradingView and Telegram are trademarks of their respective owners. Sarathi is not affiliated with or endorsed by them.