When we first built SIQ's paper trading system, we took the simplest approach that could work: when the AI agent decided to trade, we recorded the trade immediately with whatever price we had.
It was our MVP. It worked. We could track portfolios, see returns, and validate that our AI agents were making sensible decisions. But as we tested more strategies and talked to users, we realized something was off.
The returns looked good on paper. But they weren't realistic.
What We Built First
Our initial system was straightforward. The AI agent would analyze a portfolio, decide on trades, and we'd record them immediately. Agent decides at 10 PM? Trades executed at 10 PM. Simple.
This approach had real benefits during early development:
- Easy to reason about: One event, one timestamp, one price
- Fast iteration: We could test AI behavior without worrying about market schedules
- No complexity: No pending states, no queues, no partial executions
But we were essentially lying to ourselves about how the strategy would perform with real money.
The Realization
The problem became obvious when we started testing strategies with global portfolios. Our AI agent would decide to rebalance a portfolio containing both US and Indian stocks at 10 PM Eastern. We'd record all the trades at 10 PM prices.
But US markets closed at 4 PM. Those prices were six hours stale. And Indian markets wouldn't open for another six hours. The "execution prices" in our paper portfolio didn't reflect any actual market reality.
We asked ourselves: if we can't actually trade at 10 PM, why should our paper portfolio pretend we did?
Paper trading should mirror reality. If real execution would wait for market open, our paper trades should too.
This insight changed how we thought about the entire system. We weren't just building a way to track AI decisions; we were building something that should predict what would actually happen if you connected it to a real broker.
Before and After
Our First Approach
- Execute immediately at decision time
- Use whatever price is available
- Single timestamp for everything
- No visibility into overnight gaps
- Global portfolios execute "instantly"
What We Built Now
- Queue trades as "pending" at decision time
- Execute at real prices when markets open
- Track decision time vs execution time
- Measure price drift between the two
- Each exchange executes independently
The new approach required us to rethink several assumptions. Trades aren't just records of what happened; they have a lifecycle. They go through states: pending, executing, executed, cancelled, failed.
The Key Insight: Dollar Amounts, Not Shares
One thing we learned while rebuilding: at decision time, you don't know what the execution price will be.
When our AI decides "increase Apple exposure by 5% of portfolio," it's thinking in terms of portfolio weight and dollar allocation. Storing that as "buy 47 shares of AAPL" would be wrong because we don't know what Apple will trade for when NYSE opens.
We now store the intended dollar investment. When execution actually happens, we calculate share quantities from the live price. If Apple gaps up 3% overnight, you get slightly fewer shares. If it gaps down, you get more. This matches how real market-on-open orders work.
How It Works Now
Here's what happens when an AI agent makes a decision outside market hours:
Our Pending Trades panel showing 11 trades queued at 6:57 PM, waiting for the NSE to open. Each trade shows the decision price and tracks price drift until execution.
Handling Global Portfolios
This architecture naturally handles something that was awkward before: portfolios spanning multiple time zones.
| Time | Event | US Trades | India Trades | Overall Status |
|---|---|---|---|---|
| 10:00 PM | Agent decides | pending | pending | pending |
| 3:45 AM | NSE opens | pending | executed | partially executed |
| 9:30 AM | NYSE opens | executed | executed | completed |
This mirrors what would actually happen with real brokers in different countries. Your performance tracking now reflects reality, not a convenient fiction.
What We Learned About Price Drift
Building this system gave us a new metric we didn't have before: price drift.
When our agent decides at 10 PM and trades execute at 9:30 AM, the stock might have moved. Maybe it gapped up on overnight news. Maybe it gapped down. The difference between decision price and execution price is valuable information.
We now track this for every trade, and it tells us things we couldn't see before:
- Execution quality: Consistent positive drift on buys means we're systematically paying more than expected. Maybe the AI is chasing momentum, or overnight gaps work against the strategy.
- Timing insights: If drift is always large, maybe we should run agents closer to market open.
- Accurate returns: Performance is now calculated at execution prices. Our backtesting results actually predict what would happen with real money.
An Unexpected Benefit: Cancellation Windows
Something we didn't plan for turned out to be really useful: the time between decision and execution creates a natural cancellation window.
Users can review pending trades and cancel ones they disagree with. Maybe you saw news that changes your view. Maybe you want to override the AI on a specific position. Maybe you just want to pause and think.
When you cancel a trade, the reason is stored. The AI sees this on subsequent runs, so it doesn't blindly repeat the same recommendation. If you cancelled because "market conditions changed," the system knows to re-evaluate.
This transforms AI trading from "fire and forget" into a collaborative process. The AI proposes, you have final say before execution.
What This Enables
The new architecture opens up possibilities we're now building toward:
- Price thresholds: Only execute if price hasn't drifted more than a specified percentage
- Limit order simulation: Queue trades with price limits, execute only if the market reaches them
- Execution optimization: For dual-listed securities, route to whichever market opens first
- Conditional cancellation: Automatically cancel if certain conditions are met before execution
None of this would be possible with our original immediate-execution approach.
We started simple and evolved as we learned. The gap between decision and execution isn't a problem to hide; it's how markets actually work.
The Takeaway
Building realistic paper trading meant accepting that real markets have constraints. We initially ignored those constraints because it was simpler. As we learned more about what users actually needed, and what would make our backtesting results meaningful, we realized we had to mirror reality.
Now when our AI agent makes a decision at 10 PM, the trades wait until markets are actually open, execute at real prices, and track how reality differed from expectation.
That's what we should have built from the start. But we learned by building, and this is where we are now.