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 bysyncIndexSettings() 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 valueslastActiveRight(CALL / PUT)
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
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 validinstrumentToken values in settings, the backend cannot stream live prices.
Token sources from settings
Only indices withisActive: 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:
- React UI —
${indexName}TickDatavia Socket.io latestDataMap— in-memory cache used by trading automationIndexDatacollection — historical tick storage
handlePostZerodhaLogin() → ensureMarketDataRunning(). See Event processor and latestDataMap.
4. Settings in trading
Settings define what to trade, when, and how much. Live prices come fromlatestDataMap; 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)
UsesisRecurringSell, lastActiveRight, sell durations, target prices, and strike-match differences from settings. Watches baseValue from live ticks for exit conditions:
- PUT: sell when
baseValue >= strikeMatchPriceORbaseValue <= targetPrice - CALL: sell when
baseValue <= strikeMatchPriceORbaseValue >= targetPrice
When admin changes settings
On update via API (indexSetting.controller.ts):
- Save to MongoDB — admin cannot edit
optionChainByExpiryorfuturesChainByExpiry(those come from Zerodha sync only) - Emit
indexSettingUpdated - Socket.io → clients refetch via
fetchIndexSettingData ZerodhaEventProcessorreloads subscriptions (new tokens, cleared strike cache)
5. Market end auto-update
Settings and trading services are managed by scheduled jobs inapp.ts using node-schedule and marketSessionManager.ts.
Session close handlers
What happens at market close
- Stop order services — recurring buy and schedule order intervals are stopped;
recurringStatusset tofalsein DB - Full instrument sync —
syncIndexSettings()refreshes tokens, option chains, and expiries from Zerodha - WebSocket resubscribe — for active symbols,
indexSettingUpdatedtriggers token reload on the live processor - Strike price refresh (equity close only) —
sechduleUpdateStrikePrice()updates pending ScheduleOrder documents with final candle min/max asstrikeMatchPrice(fromIndexDataaggregation). 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
- Server startup —
backfillOptionExpiriesMap()runs; market data starts only after Zerodha login - Market open —
initializeMarketServices()starts recurring buy and trailing sell from saved settings - During market — settings drive WebSocket subscriptions; 1s snapshots feed UI and
latestDataMap; trading reads settings + live prices - Market close — order services stop;
syncIndexSettings()refreshes broker metadata and rolls expiries; equity close also refreshes pending schedule strike prices - Next day open — order services restart from same admin settings; new instrument tokens from yesterday’s sync are already in DB