How to Build a Paper Trading Bot for NIFTY Options on Free Data
How to build a paper trading bot for NIFTY options on free NSE data: a defined-risk iron condor, Zerodha-style charge modelling, drawdown guards, SQLite store.

To build a paper trading bot for NIFTY options you need a data source for the index and the option chain, a position builder for the structure you want to study, a cost model that charges what an Indian broker and the exchange would actually charge, a set of guards that stop the simulation when drawdown limits are hit, and a store where every simulated trade is recorded for later review. You do not need a broker API, a paid data feed or a live account. NSE's public endpoints provide enough to simulate a defined-risk strategy honestly, provided the cost model is realistic.
I built one around a NIFTY iron condor, and the thing that separates it from a spreadsheet is the charge modelling. On Indian index options, brokerage, exchange transaction charges, securities transaction tax, GST, SEBI fees and stamp duty materially change the outcome of a four-leg structure traded weekly. A simulation that ignores them is not a simulation of anything you could trade. This post explains how to build a paper trading bot for NIFTY options that tells you the truth, and why it should never be allowed to place a live order. It is a research tool, not financial advice; past simulated results do not predict anything.
What should a NIFTY options paper trading bot simulate?
Pick one structure and model it completely before adding a second. Mine is the iron condor: sell an out-of-the-money call spread and an out-of-the-money put spread at the same time, collecting premium with a defined maximum loss on each side. It is a good first structure for a paper bot because:
- The maximum loss is known at entry, so drawdown guards have a clean number to work with.
- It has four legs, which forces the cost model to be right or the results are obviously wrong.
- Its behaviour depends on the index staying in a range, which makes the effect of real events visible in the trade log.
The bot decides strikes from the current index level and a distance rule, sizes the position in lots, records the entry premium and the defined risk, and then marks the position each session until exit by target, stop or expiry.
Where do you get free NIFTY data that is good enough?
NSE publishes the index level, the option chain with per-strike last price, bid and ask, open interest and volume, and historical index data through its public website endpoints. These are adequate for a paper bot that trades at session granularity. What they are not: a tick feed, a guaranteed-uptime API, or a licensed data product. Design for that:
- Fetch at a modest cadence and cache every response with a timestamp.
- Treat a failed fetch as a missing mark, not as a zero price, and carry the last good value with a flag.
- Fill simulated entries at a conservative price inside the bid-ask spread, never at the mid, because real fills on wide out-of-the-money strikes are not at the mid.
If the bot ever graduates to live trading, the data layer is the first thing that must change to a broker feed. Keeping the data interface narrow makes that swap possible.
How do you model Zerodha-style charges correctly?
This is the part most paper bots skip and the part that decides whether the result means anything. For each leg, on each side (entry and exit), the model charges:
- Brokerage per executed order, capped per order as flat-fee brokers cap it.
- Exchange transaction charges as a percentage of premium turnover.
- Securities transaction tax on the sell side of option premium.
- GST on brokerage and transaction charges.
- SEBI turnover fees.
- Stamp duty on the buy side.
An iron condor is four legs in and up to four legs out, so eight orders of charges per round trip. On a weekly cadence those charges are a meaningful fraction of the premium collected on conservative strikes. The bot shows gross and net profit and loss per trade side by side, and the gap is the education. Rates change, so the model keeps them as configuration with the date they were last checked, not as constants buried in logic.
What guards should a paper bot enforce?
A paper bot that keeps trading through a 60 percent drawdown teaches nothing except that you did not look. Guards I enforce, all configurable:
- Daily loss limit: stop opening new positions for the day once simulated losses pass a threshold.
- Running drawdown limit from peak equity: halt the bot entirely and require a manual reset.
- Maximum concurrent positions and maximum lots per position.
- An event filter that skips entries on days flagged as high-impact (budget, policy announcements, expiry-day idiosyncrasies).
When a guard trips, the bot records why in the trade store. That log of "did not trade because" is as informative as the trades themselves when you review a quarter of simulated activity.
Why store every trade in a database?
Because the point of paper trading is review, and review needs queryable history. Each simulated trade row holds the entry and exit timestamps, every leg's strike and price, lots, gross and net profit and loss, the charges broken down, the exit reason (target, stop, expiry, guard), and the index level at entry and exit. With a few hundred rows you can answer the questions that matter: how often did the stop side get hit, what did charges cost as a percentage of premium, how did results differ on expiry weeks, and what would a different strike distance have done. SQLite is enough; it is a single file, needs no server, and every analysis tool can read it.
Why must a paper bot never place live orders?
Partly discipline and partly architecture. The bot has no broker credentials and no order-placement code path at all, so the question of accidentally going live cannot arise. If the research ever justifies a live version, that is a separate program with authentication, a broker API, risk limits enforced at the broker and a human confirmation gate. Mixing the two in one codebase is how people end up with a simulation flag that someone flips at the wrong time.
How I built this: the NIFTY Options Paper-Trading Bot
The NIFTY Options Paper-Trading Bot is a Python application that simulates a defined-risk iron condor on free NSE data with realistic charges, drawdown guards and a SQLite trade store, and by design places no live orders. Its workflow is:
- Fetch the NIFTY level and option chain from free NSE endpoints at session cadence, caching every response.
- Build the iron condor from a strike-distance rule and size it in lots, filling at conservative prices inside the spread.
- Apply the Zerodha-style charge model to every leg at entry and exit, recording gross and net separately.
- Mark the position each session and exit on target, stop or expiry.
- Check the daily loss, drawdown, concurrency and event guards before any new entry and log the reason when one trips.
- Store every trade and every guard decision in SQLite for review.
Design decisions: one structure modelled completely, free data with a narrow interface, charges as dated configuration, guards that explain themselves, and no live code path at all. The outcome is a tool anyone can run without a paid feed or a broker connection to study an options strategy with the costs that a real account would net. When a strategy does earn a live attempt, the execution side looks like my TradingView to Zerodha automation, which is a different program on purpose, and the broader Zerodha options lab is where I take the research further.
FAQ
Can this bot trade live if I add my broker key?
No, and that is deliberate. There is no order-placement code to enable. A live version would be a separate application with its own risk controls and a confirmation gate, built only after the paper results justify it.
How accurate are simulated fills on NSE option data?
Session-granularity data with conservative fills inside the spread gives a pessimistic but honest picture for liquid weekly strikes. Illiquid far strikes have unreliable quotes, and the bot keeps its distance rule inside the liquid band for that reason.
Why an iron condor and not a simpler long option?
A long option has a trivial cost model and teaches little about why charges matter. The condor's four legs make the cost reality unavoidable and give the guards a defined maximum loss to work with.
Can I change the broker charge model?
Yes. The rates live in configuration with a last-checked date. Swap in another flat-fee broker's schedule and the bot recomputes net results; comparing brokers on the same simulated trades is a useful exercise in itself.
If you want a paper-trading or research bot like this built around your own strategy, tell me about it on the contact page.
Building something in this space? I ship trading automation, Pine Script, MQL5 EAs, and full-stack tools with source and docs.
Start a project →