TT Lab
Get started
Learn Learning paths Courses

Capital Markets and Settlement

An order has to be stopped before it leaves

Continue in TT Lab

In one line

A person typing one extra digit is bound to happen. What stops it is not human attention but checks built into the order path, and a check does not work just by being switched on — what you put into the cumulative total and in what order you apply the checks change the result.

Why this was needed

Finding something after it executes and stopping it before it goes out are completely different jobs. An order that has gone out is already in the market, and to undo it you have to trade the other way or beg the exchange for a cancel. The price movement in the meantime is a loss, plain and simple. So risk checks are placed on the order path, that is, in the stretch before the order goes out to the market.

In some countries this is not a convention but a rule. The U.S. Securities and Exchange Commission's Rule 15c3-5 requires brokers that provide market access to apply financial and regulatory risk controls before orders go out. The text of the rule can be read in 240.15c3-5 of the eCFR, and why such a rule was needed is recorded in the adopting release in the Federal Register. What the rule requires is "put checks in place," not "set the limit at such-and-such." Each firm sets its own numbers. All the limit values in this reading and in the lab are synthetic.

How it works

Checks usually split into six lines.

Single-order limit. Put an upper bound on the quantity and amount of one order. An order with one extra digit is mostly caught here. The amount is quantity times price, so if you put a bound only on quantity, it leaks through on expensive symbols.

Price band. Block limit prices that stray from the reference price by more than some percent. There is one question you always run into here — what do you do about a symbol that has no reference price? It could be a new listing, a dead market data feed, or a wrong symbol code. If you let it "pass because there is nothing to compare against," the reason for having the check disappears. The orthodox approach is to pull it out as a hold, neither pass nor reject, and have a person look at it. A hold must be counted differently from a reject. That difference opens up a lot later.

Restricted-symbol list and duplicate orders. The former is a simple list match, and the latter catches orders with the same conditions repeating in a short time. Pressing a button twice because you think the screen has frozen, or retry logic that did not get a response and sends again, gets caught here.

Cumulative limit. Put an upper bound on the sum of open exposure per account, trader, or desk. Here is the most important rule in this reading. Rejected orders do not consume the cumulative. It looks obvious but is easy to get wrong — if you scan the order log as is and compute the sum, rejected orders go in too, and the limit fills up faster than it really is, so perfectly good orders get blocked one after another. The blocked person does not know why. The screen says only "limit exceeded," and that person's actual exposure is half the limit.

Kill switch. Individual rejection and blocking everything are different actions. If rejects pile up within a short time, it is more likely not that one order is wrong but that the sending side is broken. In that case you close that path entirely. And this state must be kept in a file or a store. If you keep it only in memory, the block is released the moment the process restarts, and the broken side is still broken.

The order of checks. If the order changes, the reason attached to the same order changes. If only the reason changes, it is a reporting issue, but if the check that separates hold from reject moves earlier or later, the story changes. A hold is not counted as a reject, so just moving the price band check earlier pushes back the moment the kill switch engages. Orders that come in during that time go out without being blocked.

Do amount comparisons with decimal. If you compare limits in floating point, an amount exactly equal to the limit passes on some days and is blocked on others. The field names and meanings of order messages follow what the FIX standards define.

What it looks like in the field

Once, a report came in that a particular desk's orders were being blocked every afternoon. When we counted the exposure, it was half the limit. The cause was that the cumulative was being counted from the order log. A few large orders rejected in the morning were eating into the limit, and rejects were shown nowhere on the screen as exposure.

Another time the kill switch engaged and released itself ten minutes later. A deployment was running, the process restarted, and the block state existed only in memory. The same incident happened two more times that day.

What you will do in the next lab

You build 47 orders and the limit definitions, and starting from the single-order limit you add, one layer at a time, the price band, restricted symbols, duplicates, cumulative exposure, and the kill switch. You compare against a wrong implementation that puts even rejected orders into the cumulative and pull out as a list which orders get unjustly blocked, and then change the check order by one position and confirm that the order on which the kill switch engages changes. At the end you run the same day again with a second configuration with tighter limits and pull out the orders the current configuration was missing.