I replaced fixed trading rules with an LLM (Claude) for NSE F&O decisions. Week 1 paper results — mostly lessons, not profits.
What this is
An autonomous options trading agent for NIFTY + BANKNIFTY. Instead of coded rules like "if RSI > 70 sell" or "EMA crossover → buy," the agent sends market data to Claude (Anthropic's LLM) every 15 minutes and lets it decide: trade or wait, CE or PE, which strike, when to exit.
The idea: an LLM can weigh 15+ inputs simultaneously and make contextual judgments that fixed rules can't. "Regime is bullish and 6/7 signals agree, but VIX just spiked 3 points in 10 minutes — wait." No indicator combo can reason like that.
Whether this actually works better than a well-tuned rule-based system is what I'm testing. Week 1 results say: maybe, but the exits need serious work.
Architecture (for the technical crowd)
Market Data (Upstox WebSocket + REST API)
│
▼
┌─────────────────────────────┐
│ Data Layer │
│ Spot, Option Chain, Greeks,│
│ VIX, PCR, FII/DII, OI │
│ 15min/5min candles │
└───────────┬─────────────────┘
▼
┌─────────────────────────────┐
│ Agent (Maker) │
│ Claude Haiku — proposes │
│ trade with reasoning │
└───────────┬─────────────────┘
▼
┌─────────────────────────────┐
│ Checker (Validator) │
│ Claude Sonnet — reviews │
│ and approves/rejects │
└───────────┬─────────────────┘
▼
┌─────────────────────────────┐
│ Paper Broker │
│ Real bid/ask fills │
│ Real costs (Upstox API) │
│ Real margin checks │
│ Trailing SL on live ticks │
└─────────────────────────────┘
Dual-agent validation: A cheaper model (Haiku) proposes trades. A smarter model (Sonnet) reviews every proposal before execution. Think of it as trader + risk manager. ~Rs 100-150/day API cost for both combined.
Risk monitor: Background thread checks every few seconds — trailing stop-loss updates on real WebSocket ticks, daily loss halt (4% of capital), smart EOD exit (closes expiring/losing positions at 3:15 PM, holds profitable ones overnight).
Why not just code the rules?
I saw a post here recently: "RS + VWAP on 5min, profit factor < 1." And a comment: "Only indicator based algos will not be consistent in long run." That matched my experience.
The problem with indicator rules isn't the indicators — it's that markets change context. A RSI 70 during a breakout is a continuation signal. A RSI 70 at resistance is exhaustion. A coded rule treats them identically. An LLM can read the surrounding context and distinguish them.
The counter-argument (which I take seriously): maybe Claude is just doing the same pattern matching with extra steps and extra cost. Week 2 will test this specifically — I'm auditing whether Claude actually reasons differently with contextual data, or just mechanically follows regime + RSI like a fancy indicator algo.
What makes the paper trading realistic
This is the part I'm most confident about. Most paper results are fantasy because they fill at LTP with zero slippage. Ours doesn't:
| Factor | Our Approach |
|---|---|
| Fill price | BUY at ask, SELL at bid — real WebSocket depth data, ~1 tick/sec |
| Slippage | Depth-based + VIX/time jitter. Extra penalty if spread > ₹5 |
| Costs | Real Upstox brokerage API (not estimated). STT, exchange txn, GST, stamp duty — all from broker |
| Margins | Real Upstox margin API. Can't enter trades the account can't hold |
| Position monitoring | WebSocket FO ticks for open positions. Trail SL updates on real price movement |
Week 1 results (Jul 1-3) — honest numbers
Capital: ₹5,00,000. NIFTY + BANKNIFTY options, BUY-only directional, 1-2 lots.
| Day | Trades | What happened | Realized P&L |
|---|---|---|---|
| Jul 1 | 3 | Entries correct, exits broken. FO ticks wired mid-day. | ₹0 (held overnight) |
| Jul 2 | 3 | All entries caught direction right. Trail SL too loose — gave back ₹11K unrealized on one trade. | +₹1,746 |
| Jul 3 | 3 | New trail SL deployed (8%→3%→2%). Agent skipped all afternoon cycles. | Testing, not trading |
Net Week 1: +₹1,746 realized. Not meaningful. The real finding is below.
What actually went wrong (the useful part)
1. Trail SL was the #1 problem, not entry signals. On Jul 2, a BANKNIFTY position hit +₹6,295 unrealized within 10 minutes of entry. By EOD it was -₹5,989. That's an ₹11K swing because the trailing stop was set at 35% — way too loose for options that can move 10% in minutes. Fixed to 8%→3%→2% progressive tightening. The entry was right. The exit let the profit evaporate.
2. Claude enters on Cycle 1 every single day. 9:30 AM, first cycle, Claude sees "regime BULLISH, 6/7 signals agree" and enters immediately. Never waits for a pullback, never says "let me observe for 30 minutes." In 5 out of 6 trading days, Cycle 1 = instant entry. This looks like pattern matching, not reasoning.
3. A 0.2% price-move gate killed the entire afternoon. I had a gate: "if market moved < 0.2% since last cycle, skip." On Jul 3, after all positions exited by 10:55 AM, the market went flat. The gate skipped every cycle from 11:17 to market close. With zero positions open, the agent should have been scanning for new entries, not sleeping. A 3-line fix, but it cost an entire afternoon.
4. Cost API was returning ₹0. Upstox brokerage API returns {"charges": {"total": 49.32}} but my code read data.total instead of data.charges.total. Every trade showed Costs = ₹0.00. The kind of bug that looks fine in logs until you check the numbers.
Current input audit
Inspired by that excellent "₹25L → ₹2.7Cr backtest autopsy" post here — I tagged every system input:
| Input | Tag |
|---|---|
| Slippage (depth-based) | MEASURED — real bid/ask |
| Trading costs | MEASURED — real Upstox API |
| Margins | MEASURED — real Upstox API |
| Trail SL percentages | ASSUMED — 3 days data |
| Regime detection | ESTIMATED — EMA/SuperTrend, not validated |
| Cooldown (30 min) | ASSUMED — picked a number |
| Daily loss limit (4%) | ASSUMED — reasonable but arbitrary |
| Taxes | NOT MODELED |
4 measured, 2 estimated, 4 assumed. The assumed column is the real risk.
What's next
- This weekend (Jul 4-5): Adding momentum data (VWAP, change from open, candle trend), IV rank, put/call IV skew — not as rules, but as context for Claude to reason about
- Week 2 (Jul 7-11): Pure observation. Does Claude actually use the new data to make better decisions, or does it keep entering on Cycle 1? If it ignores the data, the features are noise — cut them
- Aug 28: Go/no-go decision for live trading with real (small) capital
Questions for this sub
- For those who've gone from paper → live: what was the biggest gap that paper trading didn't reveal? (Even with realistic fills, I'm sure I'm missing something)
- Has anyone used LLMs for actual trade decisions (not just analysis/summaries)? What was your experience with consistency — does the LLM make the same decision given the same inputs?
- The dual-agent (proposer + reviewer) setup costs ~₹100-150/day in API calls. Is that worth it over a single model, or is the "checker" just rubber-stamping?
905 unit tests. No paid tools — everything runs on Upstox free API + Anthropic API (₹100-150/day). Code is private but happy to share architecture details in comments.