[ts-gen] Parent/child OCA groups [Was: Cancel Order and OCA Orders]
pippin at owlriver.net
Mon Aug 10 17:35:23 EDT 2009
About OCA groups:
> I see the OCAType table in the database ...
There is an OcaType table, and it has the following contents:
insert into OcaType(uid, type, `desc`)
(1, 'CoFwiB', 'cancel on fill w/ block'),
(2, 'RoFwiB', 'reduce on fill w/ block'),
(3, 'RoFwoB', 'reduce on fill wo block');
This is a finite domain type, a kind of flag, and you can select
the value you want as part of the order template, which includes as
one of its attributes an OcaType record key. The OcaType is not the
same as an oca label, which occurs elsewhere in the database, both
as a possibly null attribute in CreateEvent, and as a reflection of
the IB tws open order message in the ActiveOrder table.
So, the OcaType table is a bit of a red herring for the purposes of
your question. In what follows, I'll first explain implicit OCA
groups provided by the IB tws api as an alternative to explicit,
user-defined OCA labels, and how the shim supports their use; next
list some obsolete code from old regression tests, in case you're
interested; and finally consider the issue of adding the user-defined
variety of OCA groups to the shim's command language.
> ... if anyone has an example of an OCA order, where if one is filled
> all others are cancelled ...
Most of the time, such groups have a shared parent, and for this
common case, you want to use parent-child links between orders, where
the IB tws api protocol defines such children to be in an OCA group.
One nice feature of such implicit OCA groups is that, once staged,
submission of the parent triggers transmission of the children;
another is that the OCA group doesn't become active until the
parent is executed. Such bracket orders are the closest the IB tws
api comes to providing transactional logic, sequenced orders. While
combo bags and user-defined OCA groups only provide conjunctive and
disjunctive sets, bracket order sequencing comes closest to the
conditional logic that is otherwise unavailable via the IB tws api.
Since parent-child bracket orders are the common case for
OCA groups, and the user-defined OCA attribute is ignored when
parent-child links are defined, the IB tws api protocol has in
effect been defined in such a way that, although user-defined OCA
labels are accepted in some cases, they are probably not what you
Instead, the parent id [Template table uid] should be defined for all
child orders that you want to be in an OCA group. The shim sends
the parent id's order identifier with the place order request for the
applicable children, and the IB tws will set up an OCA group for you
to consist of all those children sharing a common parent as long as
that parent is known to it, and either not yet transmitted or still
working, and of course, as long as none of any previous children have
triggered. In addition, I suspect that additional children can be
added to an existing implicit OCA, again as long as none have
triggered, although it's been a while since I checked this. Of
course, in practice you stage everthing via create before submitting
anything, to avoid the obvious race.
When such orders are sent via the api, if you were able to also pass
in a user-defined OCA label --- you can't at this time, since the
shim's command syntax does not include such an attribute --- the IB
tws would ignore it. That is, the parent/child links and explicit
user-defined OCA labels are mutually exclusive.
In more detail, for parent-child bracket orders, you need to:
define a set of related orders as a tree structure, where
all siblings form an OCA group, and none of those are meant
to be accessible to triggering until the parent is working;
set up Template table records for each node in the tree, where
each child node has the par attribute set to the Template table
uid of the parent record, as I do in the sql/risk.sql load
use that tree structure by selecting the appropriate Template
uid indices as the oid attribute of as many bind commands as
you have nodes --- once defined, such a bracket order skeleton
may be used over and over by the shim ---
submit orders in top-down order, so that parents are known to
the IB tws before it sees their children, and observing an
appropriate delay of, say, 300 milliseconds between submitting
the parent and its children [this is precisely where the worst
race in the IB tws order protocol occurs, and it might well be
due to various kinds of transaction processing and margin
requirement checking in the upstream, in which case don't expect
to be able to safely avoid this delay];
recognizing that once you transmit --- submit --- the parent,
the children are submitted as well.
So, in brief, define your bracket order setup via a skeleton of
related records in the Template table, use bind commands to give
the nodes of that skeleton unique names, stage those orders and
bind to a contract via create commands, and only after the tws knows
about all of them, submit the parent. By the way, you should be
able to modify and submit with a single command, so once staged in
this fashion, order submission can be *very* fast.
> ... please post the ... script.
The old ksh orders regression test used to demonstrate bracket orders
via the eponymous function. It's in old tarballs, and I've excerpted
the *obsolete* syntax below:
function bracket # enter a bracket set
BuyOrder='create item 2 3 LMT 2 50.0 0.0;' # AIG
SellHigh='create item 2 4 LMT 2 60.0 0.0;'
StopLoss='create item 2 5 STP 2 0.0 49.0;'
BuyEntry='modify item 2 3 MKT 2 0.0 0.0;'
Terminal='modify item 2 4 MKT 2 0.0 0.0;'
OcaGroup='submit item 2 4;'
Reversal='submit item 2 4;'
KillKill='cancel item 2 5;'
Transmit='submit item 2 3;'
cmd_shim 'bind key(3) to oid(3);' # identity not necessary
cmd_shim 'bind key(4) to oid(4);'
cmd_shim 'bind key(5) to oid(5);'
cmd_shim 'open;' ; sleep 1 # open orders info
cmd_shim "$BuyOrder"; sleep 1 # optimistic order
cmd_shim "$SellHigh"; sleep 1 # limit exit order
cmd_shim "$StopLoss"; sleep 1 # bail on disaster
cmd_shim "$OcaGroup"; sleep 1 # item 3 is parent
cmd_shim "$BuyEntry"; sleep 1 # mod to force buy
cmd_shim "$Transmit"; sleep 1 # send transaction
cmd_shim "$KillKill"; sleep 1 # live dangerously
cmd_shim "$Terminal"; sleep 1 # reverse position
cmd_shim "$Reversal"; sleep 1 # another mkt exit
In the obsolete syntax above, the first index, 2, is the contract,
here AIG, and the second the template order uid. Template uid 3 is
the parent, and 4 and 5 the children, here an exit and stop loss.
There are all kinds of things wrong with the money-management side
of the above script, but to the best of my recollection, it did its
job of setting up an OCA for the stop and exit for testing purposes.
The practice of using Template order uids as keys no longer works;
this script predates order journalling.
As indicated, it's obsolete; AIG has since gone from the dow 30, to
non-existent, to obscure. Also note that this one test is meant
to exercise a number of place order features, and that it's a
regression test, and not useful for an operational system.
Now, by this point you hopefully see how to use parent-child links
to setup reuseable, implicit OCA groups for bracket orders, and if
not, please ask for furthur explanation on the list. Next, the
question of adding user-defined OCA groups to the shim's command
Currently there is no way to define an explicit OCA label via the
create order command. Instead the current design expects you to
instead let the IB tws setup the OCA group for you by defining the
parent id attribute in the child records of your order template
table, as explained above.
I could add support for user-defined OCA labels via an optional
attribute of the create order command, although it would add various
possible error conditions if users got their tree structure tangled
up, or tried to reuse a OCA group label, or mistakenly tried to
use such a disjunctive set for the children of a bracket order,
where the sequential nature of the bracket is key.
If there is significant interest in such, and demonstrated value,
there would still be some delay in implementation, as the current
command language is simple and deterministic, and it's awkward to
add optional values to the command syntax. Later, when the cmd
parser has been redesigned to supplement the current LL0 code
with an operator precedence table, it will be easier to add
optional attributes. At that point adding such a feature would
not burden other users with awkward syntax, and it probably makes
sense to add it then.
For now, I'll consider adding an OCA attribute if and when someone
shows me a convincing use case that is not met by the parent/child
order id coupling. Right now it's not a priority, since the
parent-child approach and IB tws management of OCA group setup has
proved far superior for the common case of bracket orders.
Note that combo orders, say for options, are not such a use case;
the IB tws api supports such directly, via the BAG order type, and
although the shim does not yet support that order type, adding it
is a distinct and far different task than adding a new attribute
to the create order command.
If you want to try out user-defined OCA group labels, make sure to
verify your understanding first using the IB sample client. I think
you'll be surprised at the headaches you run into. I'm convinced
from experience that the parent/child links for IB tws-defined OCA
groups are the way to go, but I'm open to reasoned arguments to the
contrary, and this is why there's an oca attribute in the CreateEvent
Note that user defined OCA labels don't work as part of the IB
tws api protocol with parent/child bracket orders, and note also
that such user-defined labels would require yet one more kind of
user-defined unique key, with the accompanying headaches you've
already observed for the order key. Each order must have one
unique key, both with respect to the IB tws api protocol, and for
order journal identification, and I question the utility of adding
More information about the ts-general