Overview

The Risk Instance keeps order and position states, maintains the credit pool hierarchy, and performs all risk checks. 

The output of the message parser consists of order actions. The risk instance determines the legality of those order actions. To accomplish this, Reflector acts as-if the following steps are taken:

  1. Identity - New order requests must have new IDs. Modify requests must refer to existing and live IDs.
  2. Sanity - Any checks that require validating against prior state. NOTE: The message parser actually performs most of the sanity checks because they can be done a priori.
  3. Order State - A speculative order state is constructed.
  4. Order Diff - A diff between the speculative order state and the previous order state is calculated.
  5. Position Diff - The order state diff is transformed into a position diff.
  6. Position States - For each associated risk pool, a speculative position is created with the old position and the position diff.
  7. Risk Checks - For each associated risk pool, the speculative position is checked against the parameters for that pool.
  8. Success - If risk checks pass, speculative order and position states are made permanent, and order allowed through.
  9. Failure - If risk checks fail, order and position states are rolled back, and order action is denied.


Risk Pool Hierarchy

Definitions:


There are two types of Groups:

Aggregate groups contain other groups.

User groups contain credentials. Credentials are uniquely identified by the ordered triple (Venue, CompID, SubID). Users may be associated with multiple credentials per venue and over multiple venues.


In the following diagram, the BROKER and FUND nodes are aggregates. The access, command/control, and semantics surrounding them are external to the runtime, and are handled elsewhere. The only constraints that Reflector enforces on Aggregates are that they can only contain other groups and their Position is the sum of the Positions of the groups contained by them.

User groups, represented by TRADER in this diagram, contain only credentials and represent the most granular division of risk available in Reflector. Individual credential entries do not keep their own positions.


Position Model

Inside a risk pool, position is stored as an array of arrays.

Expressed more formally:

A position p is an aggregation of outlays of both open and filled portions of orders made by a set of traders.
A formula f is a mapping from positions to non-negative real numbers. f must be convex.
A limit l is an ordered pair of (f, v) where f is a formula and v is a non-negative real number.
A Position p is said to be in violation of limit l under formula f if and only if f(p) > v.

Volatility

Volatility is essentially an additional and independent multiplier that is applied per-currency to allow Risk managers to treat certain currencies as particularly more or less risky than others.

Valid volatility values range from 0.01 to 100.00, inclusive.
All volatility values default to 1.00, and the USD (Reserve Currency) volatility is currently fixed at a baseline of 1.00
Each risk pool can define its own set of volatility values.

Limits

Limits may be categorized as follows:

  1. Fat Finger Checks - These limits are entirely unrelated to the overall position. They either enforce properties of a single order/execution (single limit), or measure some side-channel effect (submission rate).
  2. Tranched Limits - These limits encompass only some defined subset of the overall position, providing fine-grained control:
    1. Pending limit
    2. Currency-exposure limits
    3. DSL
  3. Credit Limits - The following limits accumulate over the entire position, emits an ordering (required for de-escalation mode) and maps to a well known notion of risk. Every pool of risk must choose one of them as its primary measure of risk:
    1. Downside limit
    2. Upside limit
    3. Exposure
    4. Displacement
  4. Daily Credit Limits - Just like credit limits, but divided by settlement date.
  5. Counterparty Credit Limits - Just like credit limits, but divided by settlement counterparty.

Fat-Finger Checks

Submission Rate

The submission rate counter measures the number of risk carrying messages in a rolling window. The restraint placed on it is intended to act as a runaway-algo check.

Risk carrying messages include the following outbound messages:

Rejected risk-carrying orders still increment the count.
Messages that cancel orders are not considered risk-carrying.

Live Order Count Limit

A live order count is maintained and constrained to a live order count limit.

Single Order Limit

The absolute values of both buy and sell outlays are multiplied by their respective conversion rates to USD, then averaged.

Tranched Limits

Pending Limit

This is similar to the Single Order Limit, except this is a summation over all unfilled portions of all orders:


Per-Currency Exposure Limits

A vector of exposure limits, each applying to a single currency, expressed in that currency. This limit can be expressed in either its native currency or in USD (the Reserve Currency), based on a global setting that is loaded at startup:


Two levels of enforcement are offered: nothing or everything.

By default,  per-currency exposure limits are not enforced; meaning the trader is allowed to accumulate any position in any currency, provided that they do not violate other limits.

When enabled, then currency limits become mandatory: traders will not be able to trade in a given currency without a limit.

Currency Basket Exposure Limits

A currency basket is an ordered 3-tuple of (name, limit value, currency set).
Each risk can define up to 16 currency baskets.
The set of currency sets defined under one risk pool must be pairwise distinct (e.g.: no currency can appear in more than one basket under the same risk pool).


By default, this option is disabled, and the trader is allowed to accumulate any position in any currency basket, provided that they do not violate other limits.
If enabled, then currency basket limits become mandatory: traders will not be able to trade in currencies that do not belong to a basket.

Daily Settlement Limit

If ZEBRA_DSL is defined, then daily positions are kept. DSL uses whichever position tracking type is chosen for NOP.

Credit Limits

Net Open Position

Reflector uses the following terms to quantify NOP: Downside, Upside, Exposure, Displacement.

Downside Limit

An upper bound on how much the trader can lose.
This limit first assumes that the upside of every pending trade is gone but the downside remains.
Then, it assumes that all the credited currencies are gone while the debited currencies remain.



Upside Limit

An upper bound on how much the trader can make.
This limit first assumes that the downside of every pending trade is gone but the upside remains.
Then, it assumes that all the debited currencies are gone while the credited currencies remain.


Exposure Limit

This formula nominates one currency (usually USD) as a risk-free asset, then considers positions in all other currencies as risk carrying, pursuant to their absolute value, then scaled by the exchange rate & volatility.


Displacement Limit

This formula is very similar to the Exposure Limit formula.
In the exposure formula, the upside and downside are reconciled per currency, then summed up. In this formula, they are summed up independently, then reconciled.

Risk Modes

Reflector has four different risk modes as itemised below (ordered in increasing constriction):


Order Risk Model

Reflector implements an "Order Risk model", not an "Order model". The difference is that only the attributes of an order that has risk implications are modeled.

For taker orders, this means that open orders and fills are separate entities. A given open taker order has exactly 3 possible states: nonexistent, live, and dead. The order is live from the outbound NewOrderSingle until an inbound ExecReport confirms its death. The fills that the open order accumulates have 3 possible states too: nonexistent, filled, and rolled back.

For makers, the inbound order itself is assumed to carry no risk. It is the outbound ExecReport that is being examined for risk. We model that as a fill that can potentially be rolled back; because most maker venues do not ack on accept, and rejects are rather rare.

Daily Settlement Limit

DSL is supported by Reflector, however it shoudl be noted that DSL is primarily a passive post-trade metric - as discussed in the following subsections.

Precision versus Correctness

DSL demands precision on a metric that is inherently ambiguous before an order executes: settlement date. There are three potential sources of truth with regard to settlement date on a spot order:

Implications:


There is essentially no way to perfectly deduce settlement date pre-trade.


False Precision & Perverse Incentives

Even if the precision described in the previous section can be captured correctly, the effort to do so may be in vain.

A trader wishing to load up on risk while evading DSL can simply make sure to spread his orders between different settlement days. Even a trader who is fully compliant in spirit will be incentivized to take on riskier bets with longer settlement terms in the event that his near term position is approaching its DSL limit.

In other words, DSL encourages in practice precisely the kind of behavior it purports to curtail in principle.


Ordering

DSL is weakly ordered. Given two DSL positions, it is not possible in all cases to determine if one position is "more risky", "less risky", or "equally risky" as the other in terms of DSL. This matters a lot when a trader is put in any sort of "deleveraging mode", where only risk decreasing trades are allowed. Since we cannot determine which DSL is "worse" than another, we actually must also run something else to arbitrate, and when the arbitrating metric allows through a trade in deleveraging mode, it must be allowed to bypass DSL even if its limits are bust. DSL is therefore a rule that attempts to preempt extreme situations that actually must be discarded in precisely some of these extreme situations it is charged upon preventing.


The current implementation of DSL deleveraging mode requires that an order not increase worst-case risk assessment in any settlement date it deals in.


Performance

Implementing DSL requires us to multiply the memory required to store a position by 2N, where N is the average number of unsettled date buckets per pool of risk. This effect multiplies with other storage-multiplying features, such as counterparty position and multi-location. Worse yet, we cannot precompute all the dates; which means that we need additional synchronization during runtime to make sure that the web server read the correct memory locations. These factors have a direct impact for a real-time application.