¿ªÔÆÌåÓý

ctrl + shift + ? for shortcuts
© 2025 ¿ªÔÆÌåÓý

Pairs trading: Parent vs Child order placement


 

Hello Group,

Currently implementing mean reverting pairs trading (e.g. long SLV, short SSLN), would like to have the second leg order conditional on the execution of the first leg order.

Tried an approach similar to the??hedging one (with hedgeType='P'),
but I get the below "missing parent order" error despite giving it a few seconds between the two.
  • ERROR 2001 320 Error reading request. Missing parent order: server: 0 order: 2001 parent: 2000 hedge:[P]

Then I tried to attach the order?? ,
which is essentially a regular order with the parentId specified, but then it gives me the absurd:
  • Child must have the same contract as parent order
Can you please enlighten me? All I need is to execute an order properly and quickly, ideally limit at the last price,
then once that one is completed, trigger another one which deals with the hedging leg asap, on another contract/instrument.
Should I track the order execution via?execDetails? or is there a simpler way to attach them that works?

Thanks,
Jonathan


 

Actually regarding the missing parent order, I believe I need to add transmit =False on the child order too,
unlike the example given in?

It then appears to work, at least it populated the orders correctly as conditionals in TWS,
but then it give me the button "Transmit" and it seems like the orders are just parked there waiting for me to manually click "Transmit" ?


 

A few quick thoughts, John:
  • The last order in a series of orders with transmit=false must have transmit=true or all orders of the series are held in TWS and are not transmitted to IBKR for processing (as you experience with the transmit button).
  • The IBKR APi documentation mentions in a couple places that TWS may need a brief period of time to process parent orders and that "missing parent order" errors may occur. when child orders are placed too quickly. IBKR suggests pacing the first child order by 50ms in these cases, but I would expect error code 10006, not error 320 that you receive.
  • How would you place the kind of orders you are looking for manually in TWS? You should be able to model that process via the API.
  • You mentioned a couple approaches you tried, but how about , , or for the second order?
´³¨¹°ù²µ±ð²Ô


 

When I was still pairs trading I submitted my orders as combo orders (REL+LMT). This worked well.


 

Thank you very much both.

With trial and error, I found that Transmit=False is of no use in this case, as I need the orders transmitted; the child order got blocked in the current format as not on the same contract.
I did not manage to use?hedgeType='P', hedgeParams=f'ratio = {self.ratio}', it seems like whatever I put in hedgeParam(s?) I get an "invalid ratio" error in return.

How would I place these conditional orders manually, that's an excellent question and I honestly don't know.
Algos seem interesting and I would love to do some profiling with them at a later stage, but these are not available for testing on paper money as I understand, so no use at this time for me.
Execution Conditions seem to offer every possible condition, except the condition of another order getting executed, or maybe I am missing something.

Combo orders might be closest to what I am looking for, but I spent a few hours on it thus far without understanding the concept..
Apparently I need to define a "BAG" contract like "AAPL, AMZN", put an action "BUY"/"SELL" and a ratio on each leg, and then append both legs to a?contract.comboLegs object.
What is not clear at all from?
is what to do next with this contract.comboLegs object?

According to??I need to define an order with the orderComboLegs properties in there,
but it suggests that this order must also have an action, and orderType e.g. "LMT", a quantity and/or a limit price? what does that mean? the quantity of what? the limit price of what exactly?

Also how does the guaranteed flag work? if I need both legs or nothing, I should simply not mention it?


 

For context, the goal is pairs trading, but one of the two securities is somewhat less liquid than the other,
hence the desired prioritization/conditionality of the most liquid order on the execution of the least liquid one first.


 

I do use this type of orders for one special effect, which excludes trading in different securities (it's more of a simpler reversion trade). There are a some quirks to all of varieties of IB's bracket order, this one being no exception. Although my code for managing this was hacked a long time ago and I couldn't find any clear comments or side notes, I found in my code a check giving a strong warning which concerns automatically assigning the calculated values of 'hedgeParam' below 1.0. In particular the only accepted values for the apper to be 0.1, 0.2 and 0.5, which I probably found experientially. Other than that it likely should work.

Hope that helps.

§Ó§ä, 29 §Þ§Ñ§â. 2022 §Ô., 19:09 John <serorjb@...>:

For context, the goal is pairs trading, but one of the two securities is somewhat less liquid than the other,
hence the desired prioritization/conditionality of the most liquid order on the execution of the least liquid one first.


 

Thank you for your support, I had a read at this page:??
which enlightened me a bit; essentially pairs are what I am looking after, however for the two stocks I am after, it cannot be guaranteed, therefore I do not see any interest in using this.
Moreover it only allows a diff trading for convenience, but say you have a stock priced $1 and the other 9$, your pair is co-integrated, you want to buy 9 shared of the first type and sell 1 of the second type.
Well with this tool you only know that you will take a $10 position for your pair, but if you had the 9$ one at a fair price, and the 1$ one you paid a disgusting spread, well your pairs trade is worth much less now because you will have to pay that spread 9 times as opposed to 1 time for the $9 one.

Not sure if the above makes sense, but anyways I will stick to submitting orders 1 after the other, first take position on the $1 at a good limit price, then hedge it immediately with the $9 at any price.


 

I want to add my experience with combo orders. I also was at the beginning worried because they were not guaranteed. However it happened extremely seldom that not both legs filled almost simultaneously. I was usually satisfied with the executions I got. It might be different if one side is illiquid.


 

Came across this behaviour and find it equally perplexing.

Essentially

- Parent orders cannot have child orders on different contracts
- Hedging orders do not allow you to specify quantity
- It doesn't seem to allow children of children orders (at least not in my tests, i might not have been thorough enough here)

This basically means that if you want to do any kind of custom hedging with different contracts or currencies you have to have an IB server locally to respond to all the incoming order updates, vs. just setting up all of the order trees and just forgetting about it.


 

Quick follow up, it is possible to have parent, child and grandchild (and so on) orders when submitted via the API.



 

You might want to read-up on the subtle differences between Bracket orders, Hedge orders, and Once Cancels All orders (OCA). A good start is the of the TWS API Guide and the I explorer..
  • Bracket orders are limited to one symbol but they are linked together very closely so that IBKR even adjusts quantities should the entry order fill only partially.
  • OCA have the least limitations and you can wrap orders for different instruments, brackets, BUY and SELL orders for the same instrument, ...

You can combine Bracket, OCA, and Hedge orders to model quite complex order constructs that are active r pending within the IBKR system regardless of your TWS/IBGW and client application status.

Below an example of an order with several generations of attached orders. This works as long as you meet the of "20 active orders per contract per side per account". The example bracket order has four layers and a total of 12 individual orders:
  • The parent order is a limit entry order
  • It has three child orders in the bracket: profit taker, stop loss, and an auto position close order for 15 min before market close.
  • The profit taker and stop loss orders each are parents for the same construct (profit, loss, auto close)

This was just an example and may not make sense in real trading.

´³¨¹°ù²µ±ð²Ô


 

Thanks for the explanation of the different order types and the example.

Building on your example, I've tried to construct a similar tree of orders by linking parent and child limit orders for the same contract using the parentId attribute:

?ib_order = IBLimitOrder(self.action, self.quantity, limit_price_magnified, orderId=ib.client.getReqId(), transmit=transmit, outsideRth=outsideRth, parentId=parentId)

Here's a visual representation of the order tree I aimed for:

sell 100 @ $20

? |___ sell 125 @ $25

?

? |___ buy 75 @ $15?

However, I've encountered an issue. Even though the orders are submitted to TWS and appear as described in the tree, once they are eventually "transmitted" in the UI, all child order quantities get changed to 100 units (the same value as the parent).

Is there a specific setting or option within the TWS or IBKR API that might be causing this change in order quantities? I'm trying to ensure that the child order quantities remain as defined.



------

Semi-unrelated but it seems like another possible limitation in the TWS API is that you can only attach one hedge order per parent order. At least this appears to be the case via the UI, still need to write a proper code based test case for this.


 

That is how are supposed to work. All orders in the bracket match the parent order quantity as the as long as the parent order exists. IBKR says:
  • The order quantity for the high and low side bracket orders matches the original order quantity.

When you place the bracket order, IBKR adjusts quantities for all attached child orders to match the parent order (desired) quantity. Once the parent order starts filling, IBKR automatically adjusts quantities for all child orders to match the actual filled quantity of the parent until the parent order is considered filled (partially or completely) and becomes inactive.

I say "all child orders" since you are not limited just to a profit taker and stop loss order and you can attach additional child orders to the parent in the bracket. One that comes to mind is a "close position at the end of the session" order that sells the position at some point should neither profit nor loss orders have not triggered yet.

´³¨¹°ù²µ±ð²Ô


On Mon, Aug 14, 2023 at 07:05 AM, HenryE wrote:

Here's a visual representation of the order tree I aimed for:

sell 100 @ $20

? |___ sell 125 @ $25

? |___ buy 75 @ $15?

However, I've encountered an issue. Even though the orders are submitted to TWS and appear as described in the tree, once they are eventually "transmitted" in the UI, all child order quantities get changed to 100 units (the same value as the parent).

Is there a specific setting or option within the TWS or IBKR API that might be causing this change in order quantities? I'm trying to ensure that the child order quantities remain as defined.


 

Thanks again for the very informative message.

This highlights a couple of points of confusion with the TWS API.

  • The API doc describes the order attaching mechanism of bracket and hedge orders. It's implied they are just two order types that happen to make use of the parent-child relationship made available through attaching.
  • When an order is marked as a hedge order quantity must be 0. However, as you say a bracket order also should default to 0 since it matches the parent quantity, so specifying the quantity is irrelevant. Yet they do not show any errors or warnings about setting quantity like they do with hedging.

This implies there's a mechanism by which an order can just be "attached" without being a bracket or a hedge order, and without having its quantities automatically modified.

Maybe there's some way to tell the TWS API that an order is not a bracket order but rather an attached order that should simply execute when the parent executes.

Edit: Actually, I originally misread your screenshot, I mistook different prices on each order to be quantities but now see that the quantity on all child orders is the same, 10 units.

That's too bad anyway if that really is the case. Back to building a function that responds appropriately to incoming events.


 

If you need different quantities for the same security in a cadence where the execution of one order should enable the other order (trading in opposite direction), you can use pair trades mode for the child order with the same security and respective ratio of quantities:

order.HedgeType = "P";
order.HedgeParam = quantityRatio.ToString("F3", CultureInfo.InvariantCulture);
--
Best,
DS