This page explains the full lifecycle of index settings — from Zerodha instrument sync through live pricing to automated trading and end-of-day refresh. For field-level UI guides see Create and edit; for the schema see Index Setting model.

1. What index settings are

Each tradable symbol (e.g. nifty, banknifty) has one Index Setting document in MongoDB (AppSetting collection). Settings combine two layers: Only indices with isActive: true participate in live market data streaming and automated order services. Source of truth: nifty_fifty_bank_nifty_NodeJS/src/models/indexSetting.model.ts

2. Fetching settings from Zerodha

Instrument metadata is refreshed by syncIndexSettings() in indexSettingGenerator.ts. It requires a valid Zerodha access token and calls Kite Connect getInstruments() in parallel for NSE, NFO, MCX, and CDS.

What gets populated from Zerodha

What is preserved on sync

Admin-controlled fields are not overwritten when sync runs:
  • isActive
  • Recurring buy/sell flags (isCallRecurringBuy, isPutRecurringBuy, isRecurringSell, etc.)
  • Quantities, durations, limits, market protection values
  • callDifference, putDifference, strike match values
  • lastActiveRight (CALL / PUT)
Only broker metadata (tokens, chains, expiries) is refreshed.

Expiry rollover

When sync runs after market close, expired contracts roll forward automatically:
  • Futures: pickDefaultFuturesExpiry() selects the next valid expiry
  • Options: resolveOptionExpiryAfterInstrumentSync() advances option expiry
Logs: Futures expiry rolled over / Option expiry advanced

When sync runs

Admin API save emits indexSettingUpdated but does not re-fetch the full Kite instrument dump. See Instrument sync for details.

3. Real-time prices from settings

Index settings are the subscription map for Kite WebSocket streaming. Without valid instrumentToken values in settings, the backend cannot stream live prices.

Token sources from settings

Only indices with isActive: true are loaded by ZerodhaEventProcessor (zerodha-event.utils.ts). When the options underlying LTP moves, the processor calculates which strikes to track and subscribes up to 8 option leg tokens (CE/PE for ATM and offset strikes). Option leg prices live in the liveData Map and are read at snapshot build time.

Snapshot output (baseValue)

The activeSegment setting decides the reference price in each 1-second snapshot: Each snapshot is emitted to three destinations:
  1. React UI — ${indexName}TickData via Socket.io
  2. latestDataMap — in-memory cache used by trading automation
  3. IndexData collection — historical tick storage
Streaming starts after Zerodha login via handlePostZerodhaLogin() → ensureMarketDataRunning(). See Event processor and latestDataMap.

4. Settings in trading

Settings define what to trade, when, and how much. Live prices come from latestDataMap; symbol resolution always comes from settings.

Field → consumer mapping

Recurring buy (by segment)

Skips when exchange is closed or tick data is missing. See Recurring buy.

Trailing / scheduled sell (options only)

Uses isRecurringSell, lastActiveRight, sell durations, target prices, and strike-match differences from settings. Watches baseValue from live ticks for exit conditions:
  • PUT: sell when baseValue >= strikeMatchPrice OR baseValue <= targetPrice
  • CALL: sell when baseValue <= strikeMatchPrice OR baseValue >= targetPrice
See Trailing sell and Trading settings reference.

When admin changes settings

On update via API (indexSetting.controller.ts):
  1. Save to MongoDB — admin cannot edit optionChainByExpiry or futuresChainByExpiry (those come from Zerodha sync only)
  2. Emit indexSettingUpdated
  3. Socket.io → clients refetch via fetchIndexSettingData
  4. ZerodhaEventProcessor reloads subscriptions (new tokens, cleared strike cache)

5. Market end auto-update

Settings and trading services are managed by scheduled jobs in app.ts using node-schedule and marketSessionManager.ts.

Session close handlers

What happens at market close

  1. Stop order services — recurring buy and schedule order intervals are stopped; recurringStatus set to false in DB
  2. Full instrument sync — syncIndexSettings() refreshes tokens, option chains, and expiries from Zerodha
  3. WebSocket resubscribe — for active symbols, indexSettingUpdated triggers token reload on the live processor
  4. Strike price refresh (equity close only) — sechduleUpdateStrikePrice() updates pending ScheduleOrder documents with final candle min/max as strikeMatchPrice (from IndexData aggregation). This does not modify the IndexSetting document.

Next-day market open

On open, startOrderServicesForSymbol() restarts schedule orders and recurring buy from saved admin settings — no full Zerodha sync until the next session close. Market hours are configurable via env vars in marketHours.ts: NFO_START_HOUR, NFO_END_HOUR, MCX_END_HOUR, CDS_END_HOUR, etc. See Market sessions and Market hours.

6. Daily lifecycle timeline

  1. Server startup — backfillOptionExpiriesMap() runs; market data starts only after Zerodha login
  2. Market open — initializeMarketServices() starts recurring buy and trailing sell from saved settings
  3. During market — settings drive WebSocket subscriptions; 1s snapshots feed UI and latestDataMap; trading reads settings + live prices
  4. Market close — order services stop; syncIndexSettings() refreshes broker metadata and rolls expiries; equity close also refreshes pending schedule strike prices
  5. Next day open — order services restart from same admin settings; new instrument tokens from yesterday’s sync are already in DB