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.

```pine
//@version=6
hh    = 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:

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

TradingView's [sessions guide](https://www.tradingview.com/pine-script-docs/concepts/sessions/) 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.

```pine
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 + lastEntryMin
isEOD    = 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.


  A webhook signal fired at 15:20 is still delivered as an order card and still
  expires on its own clock. The cut-off belongs in the script, not in the hope
  that you will skip it.


## 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](https://support.zerodha.com/category/trading-and-markets/trading-faqs/f-otrading/articles/weekly-expiries-discontinued-for-certain-index-derivatives). From 1 September 2025, NSE moved its expiry day from Thursday to Tuesday and BSE moved to Thursday, per [Strota](https://strota.in/india-expiry-schedule) and [OneTradeJournal](https://onetradejournal.com/fno-lot-size-expiry-calendar).

| 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](https://onetradejournal.com/fno-lot-size-expiry-calendar) and [Strota](https://strota.in/india-expiry-schedule), 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](/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](https://www.coimbatorecapital.com/pdf/circular/885557764Revision-in-Market-Lot-of-Derivative-Contracts-on-Indices.pdf), 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](https://www.sahi.com/blogs/nifty-lot-size-2026-bank-nifty-sensex), [Ventura](https://www.venturasecurities.com/blog/nifty-bank-nifty-lot-size-changes-january-2026-know-how-it-impacts-traders/) (secondary) |
| GOLDM | 100 g | Standing spec | MCX Gold Mini specification; [NiftyTrader](https://www.niftytrader.in/commodities-option-chain-nse/goldm) |
| SILVERM | 5 kg | Standing spec | MCX Silver Mini specification; [Dhan](https://dhan.co/commodity/silver-mini-futures-summary/) |
| 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.


  Lot sizes are inputs, not constants. Put `default_qty_value` behind an
  `input.int()` and check it against the instruments table before each contract
  month. A script hard-coded to 75 NIFTY posts a quantity the broker will
  reject.


```pine
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](https://www.nseindia.com/static/products-services/equity-derivatives-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](https://dhan.co/commodity/silver-mini-futures-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:

```pine
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](/connectors/webhooks) covers the rest of the inbound contract.


  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. Derivatives trading carries substantial risk of
  loss.


## Try it in Sarathi

The [Studio](/dashboard/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.
