Up-Candel answers a brief: build a virtual stock trading platform. One user, pretend money, a list of stocks, prices that change, buy and sell, a portfolio with profit and loss, and a transaction history. The brief also asked for the price at any selected date and time. That last line turned out to be the hard part.
You start with ₹10 lakh and ten NSE large caps. The market runs as 30-minute candles across 14 trading days, and you can play it, pause it, step it and rewind it. The candles follow NSE's real session, 09:15 to 15:30, so a day has 13 of them and the last one is only 15 minutes long. The window starts on Ganesh Chaturthi and runs over Gandhi Jayanti, both real NSE holidays, so the replay has a closed day the app has to price and label correctly.
The brief suggested generating the price data with ChatGPT. I wrote a seeded generator instead, mostly so the numbers are reproducible and behave like a market. Each 30-minute move mixes a market factor, a sector factor and stock-specific noise, so the three banks tend to move together and the whole market has good and bad days. Volatility and volume are higher at the open and close than at lunch. Prices sit on NSE's tick grid, and three scripted news days give the replay something to trade around. Starting prices sit near real early September 2026 levels, but everything after that is synthetic, and the README says so plainly. Same seed, same 1,820 rows, byte for byte.
Then the time problem. If you can trade at any moment you select, you can also go back to a moment before trades you've already made. So what does the portfolio look like?
My answer: everything is as of the clock. Jump back to 17 September after trading on 1 October and your holdings, cash and history show exactly what you had on the 17th. You can still trade back there, but before accepting a back-dated order the engine replays the whole ledger in time order. It refuses only if one of your later trades would end up short of cash or shares, and the error names the trade it clashes with. Looking ahead is free, though. Scrub past the moment a resting limit order would fill and you'll see it filled, but nothing is saved until you actually trade at or after that time.
The money rules are boring on purpose. All amounts are stored as integer paise, so no floating point error creeps into totals. P&L uses weighted average cost, and a test checks the invariant that net worth minus starting cash equals realized plus unrealized minus charges. Real brokers and the tax department use FIFO lots, not a running average. For a paper-trading app I think average cost is easier to read, but the README flags the difference. Charges follow Zerodha's published delivery rates (STT, exchange fee, SEBI fee, stamp duty, GST, the DP charge) and you can switch them off.
A few things went past the brief because the screen felt incomplete without them: limit orders that fill during replay, with a gapped candle giving you the better price the way real fills work, a replay tape that never gives away future days, a you-vs-the-market chart and Kite-style keyboard shortcuts.
There are 103 tests across data, pricing, trading rules, P&L invariants, limit fills, charges, back-dated orders, clock edges and API validation. Many of them exist because time travel gives every rule a second case.