Hi Dhan team,
I’m actively using the Expired Options Data API (and /v2/charts/rollingoption) to build an options backtesting engine, and I’ve run into a structural limitation that makes realistic backtests very hard – especially around expiry and rollovers.
Problem
Right now the expired options API / rolling options charts:
• Only expose the option relative to the underlying via strike macros like ATM, ATM+1, ATM-1, etc.
• Use expiry_flag (MONTH / WEEK) and expiry_code (1/2/3) to represent “current / next / far” relative to the trading date.
This design is great for live trading (you always get the current ATM series without worrying about exact contract symbols).
But for backtesting, it creates a big issue:
• “Current expiry, ATM+1” on day D is not the same contract as “current expiry, ATM+1” on day D+1 if an expiry has just passed.
• When I compute things like price % change vs previous close or OI % change, I need to compare today’s series to the same contract’s previous session, not to yesterday’s expired contract at that strike.
• With the current API, I can’t distinguish between:
• NIFTY 25-Oct 25250 CE (yesterday’s expiry)
• NIFTY 1-Nov 25250 CE (today’s new contract)
So on the day after expiry, if I use yesterday’s last ATM+1 candle as a baseline, I end up comparing today’s new contract (say 30 → 50) against yesterday’s expired contract that closed at ₹0.50 — which leads to nonsensical % changes like +4000% or −99% for what is actually a fresh contract.
This makes it very difficult to:
• Reconstruct realistic daily baselines for price change / OI% calculations.
• Backtest strategies that rely on contract-level continuity (e.g., “enter NIFTY 25200 CE on 24-Oct, exit on 25-Oct at close”) because we can’t be sure we’re looking at the same contract across sessions.
What would solve this
It would be extremely helpful if the expired options / rolling option charts API could expose contract-level information in addition to the current rolling identifiers, for example:
• A stable contract identifier (e.g. NIFTY25NOV245250CE or similar), or at least:
• expiry_date (e.g. 2025-11-27)
• strike_price (double / int)
• option_type (CE / PE)
With that, I can define a unique key like:
ContractKey = {
underlying_symbol,
exchange_segment,
instrument, // OPTIDX / OPTSTK
expiry_date, // actual expiry date
strike_price,
option_type // CALL / PUT
}
…and then:
• Compute baselines per contract, not just per underlying.
• Avoid mixing yesterday’s expired contract with today’s new one.
• Run proper, realistic backtests over 5+ years without hand-maintaining separate contract files.
Questions / Suggestions
1. Is there already an API or data file that exposes contract-level information (expiry date, strike, option type) for historical option series that I can join with the rolling option OHLC?
• e.g. GET /v1/options/contracts returning all contracts with their expiry dates and Dhan security_ids for the past X years.
2. If not available today, could you consider:
• Adding expiry_date (and possibly option_type) as extra fields in the rollingoption / expired options responses, and/or
• Providing a separate “contract master” API for historical option contracts, keyed by security_id, expiry_date, option_type, strike_price.
With that information, anyone building backtests or analytics on expired options can:
• Correctly separate contracts by expiry.
• Compute price/OI changes relative to the correct baseline.
• Avoid distortions around weekly/monthly expiry rollovers.
This would make the Expired Options API much more powerful for serious quants/strategy developers, without breaking the existing ATM / ATM±1 UX that live traders like.
Thanks a lot for considering this — happy to provide more examples or collaborate on requirements if that helps.