The short answer
A TWS bracket is three orders, not one: a parent that opens the position, and two children on the opposite side, a limit order to take the profit and a stop to cut the loss, which TWS keeps on hold until the parent fills. The two children sit in a one-cancels-all group, so whichever fills first cancels the other. That is the whole design, and on a clean day it works. The stop that did not fire is almost never a stop that failed. It is a stop that was cancelled by the rules of its group, a stop sized for a position you no longer had, or a stop that was never transmitted at all. This guide is the mechanism, parent, children, OCA and the preset that decides what a partial fill does, followed by the four ways a bracket leaves a position unprotected while the screen looks fine.
How does a bracket order work in TWS?
Start with what IBKR's own pages say the thing is. The order types guide defines a bracket as "an order type designed to help limit your loss and lock in a profit by 'bracketing' an order with two opposite-side orders." The API documentation names the three legs: the parent is a limit order, the profit taker is a limit order, and the stop loss is a stop, each child carrying the parent's id as its parentId.
The part that matters is what "attached" means. From the API page on placing orders: "When an order is attached to another, the system will keep the child order 'on hold' until its parent fills." And then: "Once the parent order is completely filled, its children will automatically become active." Read that word, completely. It comes back in the second failure below.
Once the children are active, IBKR's attached-orders page says what happens: "Once the parent order fills, the opposite side profit taker and stop loss orders are triggered. When one fills, the other is canceled."
Put numbers on it. You buy 4 SPY calls at 1.20, so $480 in, with a bracket: profit taker at 1.80, stop at 0.80. The moment the 4 fill, two sell orders for 4 contracts appear under the parent. Price reaches 1.80 first and the limit fills, the stop is cancelled, you are flat with $240 more than you started. Or the option trades down through 0.80, the stop triggers a market order that fills at whatever price is there, about $160 less than you started, and the profit taker is cancelled instead. Clean either way.
Two details about the stop leg that are easy to miss. First, the order types guide's definition of a stop is "an instruction to submit a buy or sell market order if and when a user-specified stop trigger price is attained or penetrated." A stop is not resting at the exchange waiting to be hit; it is a trigger that becomes a market order. Second, the trigger is not necessarily a print. The API's trigger methods page lists a default trigger method for US options, "Double bid/ask", and says "These trigger methods only apply to stop orders simulated by IB." So for a stop IBKR simulates, and the page gives US options a default for exactly that case, your stop at 0.80 fires when the bid and ask both say 0.80, not when one trade does.
Each child has its own time in force. IBKR's Advanced button page, describing the attached stop loss, says "In the DAY field modify the time in force as needed." DAY is right if you are flat by the close. What DAY versus GTC does to a stop that has to outlive the session is in the stop loss guide, along with the clicks for building the bracket in Mosaic. This guide does not repeat them.
Which order fires: the OCA group and its three settings
The two children are linked by a one-cancels-all group, and the order types guide gives the rule in one sentence: "A group of orders linked by a client-created title for each order. By default, once an order in the group fills, all other linked orders are canceled." So the answer to "which one fires" is the boring one: whichever price the market reaches first, and then the other is gone.
The interesting question is what happens when one of them fills only partly, because that is where a stop gets cancelled on a position you still hold. IBKR's order preset page lists three settings for what a partial fill does to the rest of the group:
- Reduced in size. "Reduces the quantity of other orders in the group by the partially filled quantity of the order."
- Reduced in size with overfill protection. "Designed to reduce quantity of other orders in the group by the partially-filled quantity of the order, and specifies that only one order at a time will be submitted to an exchange to avoid multiple orders filling (overfill)."
- Cancelled. "All orders in the group will be canceled. When selected, 'overfill protection' is automatically enabled to prevent an overfill."
The API calls the same three OCA types 1, 2 and 3: "Cancel all remaining orders with block", "Remaining orders are proportionately reduced in size with block", and "Remaining orders are proportionately reduced in size with no block", where the block means "only one order in the group will be routed at a time to remove the possibility of an overfill."
Back to the 4 SPY calls. Price touches 1.80 and the profit taker fills 2 of the 4, then the bid drops away. Under either reduce setting, the stop is now an order for 2 contracts at 0.80, which is what you want. Under Cancelled, the stop is gone. You hold 2 calls, the screen shows a fill you are pleased with, and nothing is protecting what is left. That is the whole mechanism behind "why was my stop cancelled when my take-profit partially filled". It was not a bug. It was the third setting doing exactly what it says.
Which of the three your preset uses is the thing to check. The preset page describes the options; it does not say which one a fresh installation ships with, and that was not verified for this guide. Open Global Configuration, click Presets in the left pane, and read the OCA group setting on the preset your bracket uses, rather than assuming.
The overfill note is worth a sentence too. The preset page warns that using the reduce option "without overfill protection may likely result in multiple orders being routed to an exchange", and that "This may result in an overfill". An overfill is both children filling on a fast tape, which on a long options position means you sell more contracts than you own. For the profit taker and stop on one position, the setting with protection is the one that cannot do that.
Four ways a bracket leaves you unprotected
None of these is TWS misbehaving. Each is the bracket doing what it was told, on a position that is no longer the one it was told about. The same question for every other way out of a position is on one page, each marked documented, reported or untested.
1. It was never whole. The API page says it plainly: "Since a Bracket consists of three orders, there is always a risk that at least one of the orders gets filled before the entire bracket is sent." The API's answer is the transmit flag, holding the parent and profit taker back until the stop is attached and sending the three together; "When this flag is set to 'false', the TWS will receive the order but it will not send (transmit) it to the servers." In Mosaic the same failure looks like a parent transmitted on its own, with the intention of adding the children after the fill. The gap between filled and protected is exactly the moment you are busiest, and a stop you meant to add after the fill is a stop you can forget to add.
2. The parent half-filled. "Once the parent order is completely filled, its children will automatically become active." A limit to buy 4 that fills 2 and then sits is a position of 2 with two children on hold, waiting for a fill that may never come. How TWS sizes the children if the parent finishes partly filled is not stated on any IBKR page read for this guide, and it has not been tested here; if you use limit entries that can fill in pieces, run it once in paper and watch the child quantities. The other half-fill is the one above, a profit taker that fills part of the position under the Cancelled setting, and that one is documented: the stop goes.
3. You sold part of it yourself. A hotkey that closes a percentage of the position, a sell typed into the ticket. The children are attached to the parent order and sized from it, not from your position. A note from a trading automation platform, TradersPost, puts the arithmetic in one line, and it is the same arithmetic on any platform: "When you exit part of the position (e.g., sell one contract), the remaining orders (set for two contracts) no longer match your position size." What TWS then does with a bracket child specifically is not stated on any IBKR page read for this guide and has not been tested here; the hotkeys guide covers the same partial close from the hotkey's side. Either way, the stop's quantity after any partial close is a number you have to go and read.
4. You closed it another way, or touched one child. IBKR's attached-orders page says what happens when a child fills. Neither it nor the bracket page says what happens to the children when the position goes to zero by a route that is not one of them, and neither says what cancelling one child by hand does to the other. So do not assume. A sell stop for 4 contracts still working after you have sold the 4 some other way is, if it triggers, either a rejection or a sale with no position behind it. The wider list, on any broker, is why a stop loss did not trigger. How to read a rejection is in the guide to IBKR's rejection messages. IBKR's own tool for adding a bracket to a position you already hold is Exit Strategy, whose page says it sets up a bracket "on a current position or working order" and describes "two opposite-side orders that ready to go and are submitted when the price of the instrument penetrates either order's trigger price"; it, too, says nothing about what a partial exit does. After any close, any cancel, any modification, the Orders panel is the only place the truth is.
Notice the shape of all four. None of them is TWS hiding the stop. The working orders it has are in the Orders panel, which is the panel you were not looking at, because you were looking at the fill.
Where Degen Pro fits
Degen Pro is a Mac app for Interactive Brokers that answers "which one fires" by having only one: it keeps a single stop on the position, cancels any other working sell on that contract rather than racing it, and when a key sells part of the position it resizes that stop first, waits for the broker to confirm the new quantity, and only then sells, restoring the original stop and selling nothing if the broker does not confirm. It never loosens the stop; if you cancel it by hand it puts it back and counts the attempt, on the settings where it holds the stop. It gives no signals, opens nothing you did not choose, and needs Trader Workstation on a Mac. What it does and costs is on the front page.
An illustration. The contract and prices are invented.
Before you trust the bracket
- Know which OCA setting your preset carries: reduce, reduce with overfill protection, or cancel. Under cancel, a partial take-profit removes the stop on what is left.
- Transmit the three legs together. A parent sent alone with children to follow is a naked entry until the children exist.
- If your entry is a limit that can fill in pieces, test in paper what the children do when it half-fills. The API says they wait for a complete fill; what TWS does with their size was not verified here.
- After any partial close, by any means, read the stop's quantity in the Orders panel before you look back at the chart.
- After any close by a route that is not a child, confirm the children are gone. Do not assume it.
- Each child has its own time in force; a DAY stop under a GTC position is a stop that ends at the close.
None of this is investment advice. Trading involves risk of loss, and a bracket reduces that risk only while its children still match the position they were built for.