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 + 30The 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.
| Index | Exchange | Weekly expiry | Monthly expiry | Holiday rule |
|---|---|---|---|---|
| NIFTY | NSE | Tuesday | Last Tuesday | Previous trading day |
| BANKNIFTY | NSE | None since 20 Nov 2024 | Last Tuesday | Previous trading day |
| MIDCPNIFTY | NSE | None since 20 Nov 2024 | Last Tuesday | Previous trading day |
| SENSEX | BSE | Thursday | Last Thursday | Previous trading day |
| Stock F&O (RELIANCE, TCS) | NSE | None | Last Tuesday | Previous 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.
| Instrument | Lot | Since | Source |
|---|---|---|---|
| NIFTY | 65 (was 75) | Jan 2026 contracts | NSE FAOP/70616 |
| BANKNIFTY | 30 (was 35) | Jan 2026 contracts | NSE FAOP/70616 |
| MIDCPNIFTY | 120 (was 140) | Jan 2026 contracts | NSE FAOP/70616 |
| SENSEX | 20 (was 10) | Jan 2026 contracts | Sahi, Ventura (secondary) |
| GOLDM | 100 g | Standing spec | MCX Gold Mini specification; NiftyTrader |
| SILVERM | 5 kg | Standing spec | MCX Silver Mini specification; Dhan |
| RELIANCE, TCS | Revised half-yearly | Latest NSE stock lot file | NSE 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 * lotsIndex 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.
| Contract | Trading unit | Quote | Tick | Session (IST) | Expiry |
|---|---|---|---|---|---|
| GOLDM | 100 g | ₹ per 10 g | ₹1 | 09:00 to 23:30 / 23:55 | 5th of contract month |
| SILVERM | 5 kg | ₹ per kg | ₹1 | 09:00 to 23:30 / 23:55 | Last 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
| Symbol | Exchange | Kind | Expiry rule | Session (IST) |
|---|---|---|---|---|
| NIFTY | NSE | Index | Weekly Tuesday, monthly last Tuesday | 09:15 to 15:30 |
| BANKNIFTY | NSE | Index | Monthly last Tuesday | 09:15 to 15:30 |
| MIDCPNIFTY | NSE | Index | Monthly last Tuesday | 09:15 to 15:30 |
| SENSEX | BSE | Index | Weekly Thursday, monthly last Thursday | 09:15 to 15:30 |
| GOLDM | MCX | Commodity | 5th of contract month | 09:00 to 23:30 / 23:55 |
| SILVERM | MCX | Commodity | Last calendar day | 09:00 to 23:30 / 23:55 |
| RELIANCE | NSE | Stock | Monthly last Tuesday | 09:15 to 15:30 |
| TCS | NSE | Stock | Monthly last Tuesday | 09: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
The regular NSE cash and F&O session runs 09:15 to 15:30 IST, so the session string is 0915-1530. 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.
Only NIFTY. BANKNIFTY, FINNIFTY and MIDCPNIFTY lost their weekly contracts in November 2024 and now expire monthly on the last Tuesday. NSE weekly expiry moved from Thursday to Tuesday on 1 September 2025. SENSEX on BSE expires weekly on Thursday.
65, down from 75, per NSE circular FAOP/70616 dated 3 October 2025. Lot sizes are revised periodically, so check the NSE contract file before sizing a script.
It is the continuous front-month NIFTY futures ticker. 2! is the next month. Sarathi strips the exchange prefix and the contract rank and resolves the root symbol against its instrument table.
Related
- The pre-live checklist for a Pine strategyTen checks before a TradingView strategy's alerts reach a broker: v6 compile, repainting, alert payloads, sessions, sizing, paper trades and the journal.
- How TradingView webhook alerts workWhat TradingView posts when a webhook alert fires: placeholders, JSON rules, the 3 second timeout, secrets in the URL, and the failures that break a bridge.
- Repainting, lookahead and calc_on_every_tick explainedWhy a Pine strategy trades differently live than in the backtest: lookahead, request.security offsets, calc_on_every_tick, barstate.isconfirmed, how to test.
- Webhooks: in (live) and out (planned)The per-user inbound webhook Sarathi runs today, how TradingView alerts are parsed, and a planned outbound webhook on decision and fill with a proposed payload.
- Paper broker: how Sarathi simulates fillsWhat the paper route fills, what it skips, how the journal records a paper fill, and how to move to a live broker once an adapter ships.