By Scalpel Team. . 12 min read.
In short
You can scalp through the Interactive Brokers TWS API: orders, Level 2, tick-by-tick prints and IBKR's market scanner all work, including in the pre-market. The limits are what shape the tool. A default account gets 100 market data lines, only 3 Level 2 books and 5 tick-by-tick streams at once, 50 API requests a second, and 10 scanner subscriptions of 50 rows each. Stop orders cannot protect a pre-market trade, so a scalping app has to watch its own exits.
We built Scalpel, a Rust desktop trading cockpit, on the TWS API. Every quote, Level 2 row, print, scan and LIVE order in it goes through the API socket of TWS or IB Gateway on the trader's own machine. This post is what we learned: the documented limits that matter for a scalper, the undocumented behavior we hit, and the design choices they forced. The scanner findings come from a live TWS session in October 2026; the limits were checked against IBKR's documentation on October 15, 2026. Scalpel is independent and not affiliated with or endorsed by Interactive Brokers.
The TWS API is not a web API. Your program opens a TCP socket to TWS or IB Gateway, which must be running and logged in, and those programs talk to IBKR's servers for you. Three consequences follow:
Default socket ports are 7496 (TWS live), 7497 (TWS paper), 4001 (IB Gateway live) and 4002 (IB Gateway paper). From the API's point of view TWS and IB Gateway are identical; IB Gateway just has no trading screens. We compare them for day trading in IB Gateway vs TWS.
Everything you stream costs a market data line, and lines are shared across TWS's own windows and every API connection on the same username. IBKR's market data lines page gives the example: 50 symbols in a TWS watchlist plus 25 on one API connection leaves 25 for a second connection. Go over and requests fail with error 101, "Max number of tickers has been reached".
Every user starts with 100 lines. After the first month the allowance is the greater of 100, monthly commissions in USD divided by 8, or equity times 100 divided by $1,000,000 (how lines are allocated). For a small account that means 100. The other way up is a Quote Booster pack: IBKR's market data pricing page lists them at USD 30.00 a month for 100 more lines (price checked on October 15, 2026).
To see how many lines you are using, press Ctrl+Alt+= in TWS on Windows.
Depth of book and tick-by-tick prints get their own, much smaller caps, both tied to your line count. From IBKR's specialized market data lines table:
| Market data lines | Tick-by-tick streams | Level 2 books |
|---|---|---|
| 100 (the default) | 5 | 3 |
| 101 to 200 | 10 | 3 |
| 401 to 500 | 25 | 4 |
| 601 to 700 | 35 | 6 |
| 1001 to 1100 | 55 | 10 |
Tick-by-tick scales at 5% of your lines. Level 2 is roughly one book per 100 lines, never fewer than 3. The pricing page adds that each Quote Booster pack brings one more depth-of-book symbol, which the table does not show, so after you change anything, check the real count in TWS rather than trusting either page.
The depth cap counts unique symbols: several windows or requests on the same stock use one slot. Ask for a fourth symbol on a default account and you get error 309, "Max number (3) of market depth requests has been reached".
For a scalper this is the number that decides your layout. A cockpit with one Level 2 per symbol can show three symbols with full depth on a default account. Scalpel runs up to six desks; on a default account the desks past the cap show Depth unavailable and keep their quote, chart and tape (market data guide).
This surprises people. The ordinary streaming quote you get from reqMktData is not every tick: IBKR's docs describe it as "aggregate snapshots taken several times per second", every 250 ms for US stocks. Market depth "is sent without sampling or filtering", and tick-by-tick data is the same feed as TWS's Time and Sales window.
That matters for exit logic. A pre-market small cap can print through your level and back inside 250 ms: tick-by-tick sees that print, the Level 1 last price may not. Which one you trigger on is a design choice. Tick-by-tick costs one of only 5 streams on a default account; Level 1 is cheap and ignores single-print wicks. Scalpel's desks use tick-by-tick for the tape, SMART depth for the ladder, and the Level 1 stream for the quote line and the last price its stops check. Two more rules from the tick-by-tick docs: no more than one tick-by-tick request per instrument every 15 seconds, and odd lots are not in the depth feed.
IBKR paces requests, not data. A subscription costs one request when you open it, however much data it then streams. The current pacing rule is your market data lines divided by 2, per second: 50 requests a second on the default 100 lines.
What happens when you break it is a setting in TWS and IB Gateway, under API > Settings: "Reject messages above maximum allowed message rate vs applying pacing". Ticked, you get error 100, and the third breach ends the API session. Unticked, TWS queues your requests and slows you down quietly (pacing behavior). For an app that also places orders, a quiet queue in front of a sell order is not what you want, so do not lean on it: stay well under the rate.
Historical data has older, stricter rules for bars of 30 seconds or less (pacing violations for small bars):
Error 162 is the historical data service error you see when one of these trips. The practical lesson: a trader flipping symbols on a desk can burn 60 history requests in ten minutes without trying. Scalpel loads the 1-minute series first because it is the usual view and the VWAP source, fetches other timeframes in turn, falls back to a shorter span if IBKR rejects the first, and gives background feeds a lighter history (1-minute and 5-minute only) so they do not eat the budget the trader's desks need.
IBKR's market scanner over the API is the same engine as TWS's Advanced Market Scanner. It costs nothing extra, which is why Scalpel's scanner is built on it (set up the IBKR scanner). Here is what we found running it against a live account before the open in October 2026.
| What | What we found |
|---|---|
| Rows per scan | 50 at most, as documented |
| Simultaneous scans | 10 at a time. The 11th failed with error 322, IBKR's generic "Server error when processing an API client request", not a clear limit message |
| Refresh | About every 30 seconds |
| What comes back | Contracts only: no price, change or volume. You enrich each one with a market data request, which uses a line |
| Pre-market gainers | TOP_PERC_GAIN with priceAbove and priceBelow filters returned real pre-market gainers |
| Gap scans before the open | Open-gap scans such as HIGH_OPEN_GAP returned nothing: there is no open yet. They fill at 09:30 ET |
| Float | Refused. floatSharesBelow returned error 10360, "Scan filter floatSharesBelow is not allowed" |
| Error 165 | TWS sends it alongside scanner results, sometimes before the data |
Three of those rows cost us time.
Float is not available. For a small-cap momentum scanner that hurts, because float is the first thing a trader asks about. The scanner does accept a shares-outstanding cap (numSharesBelow), and shares outstanding is never below the float, so it works as a ceiling. For the number shown next to each name, Scalpel reads shares outstanding from SEC EDGAR filings, which are free.
Contracts only means lines. A 50-row scan is 50 symbols with no numbers. To rank them live you need quotes, and every quote is a line. Scalpel's list defaults to 30 names for that reason: it leaves room in the 100-line budget for the desks.
Error 165 can end your stream. Error 165 is officially the "Historical market Data Service query message", and TWS also sends it with scanner results, as an "N items retrieved" notice. Some client libraries treat any error on a scanner request as the end of the stream. The open-source Rust client we use did, except for the "no items retrieved" form, so the 3-minute volume and halted scans never delivered a single row. We carry a one-line patch that treats every 165 on a scanner request as informational. If your scans connect and then go quiet, check this first.
A minimal pre-market gainers request in IBKR's Python client looks like this:
from ibapi.scanner import ScannerSubscription
from ibapi.tag_value import TagValue
sub = ScannerSubscription()
sub.instrument = "STK"
sub.locationCode = "STK.US.MAJOR"
sub.scanCode = "TOP_PERC_GAIN"
sub.numberOfRows = 50
filters = [TagValue("priceAbove", "1"), TagValue("priceBelow", "20")]
app.reqScannerSubscription(7001, sub, [], filters)
Scalpel runs five scans side by side (top gainers, 3-minute volume spikes, halted, hot by volume and gappers) and merges them, so it uses half of the 10-scan allowance. Anything else on the same login that runs API scans shares the rest.
One TWS or IB Gateway session accepts up to 32 API connections at once, each identified by a client id you choose (connectivity docs). Reuse an id that is already connected and TWS turns you away with error 326, "Unable to connect as the client id is already in use".
We use that headroom on purpose: one connection per job.
| Connection | Client id | Carries |
|---|---|---|
| Account | 1 | Account summary, positions, P&L |
| Orders | 2 | LIVE order placement, order status, fills, commissions |
| Desks | 10 and up, one per desk | That desk's Level 2, tick-by-tick prints, quote and bars |
| Scanner quotes | 70 | Level 1 for the names on the scanner list |
| News | 71 | Headlines on the account's IBKR news feeds |
| Scanner | 72 | IBKR's market scans |
The reason is head-of-line blocking. Level 2 on an active small cap is a firehose of inbound messages. If orders shared a socket with it, a sell could sit behind a depth burst. On its own connection, an order message never waits for anyone else's data, and a desk that loses its feed can be torn down and rebuilt without touching orders. Each connection reconnects on its own with capped backoff, so one failure does not take down the rest.
Two warnings if you do the same. Connections share the account's line, depth and tick-by-tick limits: splitting sockets does not buy you more data. And another API tool on the same machine must not use your client ids, or the two will keep knocking each other off.
The API can place essentially every order type TWS can: limit, market, stop, stop-limit, trailing, brackets, one-cancels-all groups and IBKR's algos. For extended hours, each order carries an outsideRth flag, the API version of TWS's "Fill outside RTH" box. Without it, a limit order sent at 07:00 ET waits for the open.
Before 09:30 and after 16:00 ET, US exchanges run limit-only sessions: every order needs a price (extended hours). Scalpel sends only marketable limit orders: a buy priced at or above the ask, a sell at or below the bid, with outsideRth set when the trader allows extended-hours fills. The same order type works at 06:00 and at 11:00.
Two more things from building the order path:
This is the single biggest constraint for a pre-market scalper, and the reason Scalpel's stops work the way they do.
A stop order becomes a market order when it triggers, and there are no market orders before the open. A stop-limit can be set to work outside regular hours, but in a thin pre-market book price can gap straight through its limit, and the order then sits unfilled while the stock falls. We walk through that failure, and what you can do about it in TWS alone, in why your stop did not trigger in the pre-market.
The API way around it is an app-monitored exit. The app holds the stop, watches the last trade price, and when price trades through the level it sends a marketable limit sell with outsideRth set, which the exchange accepts at any session. In Scalpel's LIVE mode that exit is a sell limit 5 cents under the last trade, re-priced if the market runs away from it (pre-market stops guide).
We will not quote a millisecond figure: it depends on your machine, your connection and the stock. What we can say is where the time goes.
For a human scalper reading Level 2, the API path is not the bottleneck. Hesitation, a modal dialog or a mouse is.
If you would rather trade than build, Scalpel is this design, finished: up to six desks with Level 2, tape and chart, hotkey entries sized by shares, dollars or risk, app-monitored stops dragged on the chart, IBKR's scanner pre-market included, and SIM against the live book. It is long only, uses only IBKR data and free public sources, and never trades for you. It runs next to TWS or IB Gateway on the same computer: connect Scalpel to Interactive Brokers walks through it.
If you want a full trading interface without writing code, TWS itself does all of this by hand, and our pillar on day trading on Interactive Brokers covers that setup end to end.
Trading carries a significant risk of loss. Nothing here is financial advice.