The Lab

Strings

String values will either be the size of the fixed length field or NULL (\0) terminated, if shorter.

Reading

  • If the string is smaller than the field length then it will end with NULL.
  • If the string is the same length as the field length then there is no terminator.


Writing

  • If the string is smaller than the field length, it needs to be terminated with at least one NULL. it is not necessary to ensure that the remainder of the field is all NULL values (although this will work).
  • If the string is the same length as the field length then no terminator is used.

Timestamps

Whisperer's SBE timestamp datatypes (UTCTimestamp and ValidUntilTime) are both of nanosecond precision., but the actual values sent/received to the venue will depend on the precision that the venue supports.

  • Client to Venue - Clients should ideally always ensure that all published timestamps are at the greatest precision that they can support. For fields that will be mapped through to an equivalent field on the outbound venue message (such as TransactTime, ValidUntilTime, EffectiveTime, ExpireTime, etc), Whisperer will always utilise the full precision supported by the venue, with the client value being truncated as necessary.
  • Venue to Client - Whisperer will always publish the full precision available in any timestamp received from the venue. Typically FIX venues provide millisecond values, but some fields may be second, or microsecond precision. Binary APIs will typically offer microsecond or nanosecond precisions.

Prices and Quantities

Overview

Prices and Quantities are represented by PriceNULL and DecimalQtyNULL composites which comprise an int64 mantissa, and an int8 exponent.

These datatypes differ from the equivalents defined in The Whisperer Classic SBE3 Schema, which defines fixed scalings for each.


Whisperer honours the implied precision of all prices and quantities passed between Client and Venue, and Clients should match the decimal precision provided by the Venue for both, by setting mantissa and exponent values for the relevant SBE datatypes  (DecimalQtyNULL and PriceNULL) such that the original representation is preserved.

Fractional Trailing Zeros

A feature of FIX protocol interfaces (vs binary APIs) is that they involve an integer to string conversion when constructing the message. The way this is performed varies not only across venues, but also across individual fields or message types.

The net result is that trailing zeros for a fractional component may not always be published, so that a price could move between "1.1999" and "1.2", vs the "1.2000") that would be most consistent.

Scaling Considerations

The maximum mantissa value is  2^63 - 1 = 9,223,372,036,854,775,807

This is because a 64-bit signed integer uses one bit for the sign (positive or negative) and the remaining 63 bits for the value.

When decimal arithmetic is performed, the new mantissa value is first calculated, and then scaled according to the combined exponents. Inappropriately set precisions may cause problems, especially when multiplications are performed (as is the case when ExecutionReport LegCalculatedCcyQty and LegAllocCalculatedCcyQty values are calculated). For example:

  • LegAllocQty = 1,000,000.000000000 = 1,000,000,000,000,000 * 10-9
  • LastPx = 1.047400 = 1,047,400 * 10-6
  • LegCalculatedCcyQty = (1,000,000,000,000,000 * 1,047,400) * 10-9-6 = 1,047,400,000,000,000,000,000 * 10-15 = 1047400.000000000000000
  • 1,047,400,000,000,000,000,000 > 9,223,372,036,854,775,807 and is thus not representable.

Such problems are easily avoided by ensuring that Quantities in particular are always scaled appropriately. 

Negative Values

DecimalQtyNULL and PriceNULL may both be used to represent negative values:

  • Negative quantities are used in pre-trade allocations to denote the opposite allocation direction vs the net direction for the leg as a whole.
  • Negative prices are used to represent negative Forward Points, where appropriate.

Examples

Examples below:

ValueMantissaExponent
1.234512345-4
1.23123-2
1.230012300-4
123.0012300-2
0.00012341234-7
100000010000000
1567234.56156723456-2
-0.01-1-2
-500000-5000000
000
0.00000-4

Taker Considerations - Orders

In PreviouslyQuoted sessions, it is important that the client takes care to provide both of the following in their NewOrderMultileg messages:

  • Spot rate - tag 44/Price
  • All-In rate for each leg - tag 566/LegPrice

Maker Considerations - Prices

There is a surprising amount of variation across Venues regarding Maker pricing - not just the required precisions that prices must be published to, but also how much looseness they allow across individual components. In order to guarantee a uniform interface, Whisperer essentially has to adopt, and enforce, the strictest rules.  

To assist this, the Whisperer SBE Schema requires that forward points be expressed in a pip-based (scaled) form, rather than arithmetically (unscaled) - this enables run-time inference of the location of the pip to ensure that Fwd Pts are always correctly converted to/from scaled and unscaled forms as necessary to meet specific Venue API requirements.

It should be self-evident that Spot and All-in prices must be quoted to the correct precision for a given Venue and currency pair - e.g. for EUR/USD it would typically be 5dp for Spot (1/10 pip pricing) and 7dp for All-in. The provided Fwd Pts must be consistent with this. E.g. for a EUR/USD 1M quote, we would expect a value to 3dp.

In the context of the SBE schema, this means that attention must paid to the Exponent of the individual PriceNULL fields, since when necessary, Pip location is determined by reference to the difference between All-in and Fwd Pts exponents.  In particular, it is very important to ensure that quoted all-in rates are to the correct all-in precision.


Worked Example for EUR/USD - Pip location is the fourth decimal place:

ComponentValueMantissaExponent
Spot1.10334110334-5
FwdPts25.75125751-3
All-in1.105915111059151-7



Another example (correct):

ComponentValueMantissaExponent
Spot1.10334110334-5
FwdPts25.75025750-3
All-in1.105915011059150-7


Versus (wrong, as it implies pip is at the fifth decimal place):

ComponentValueMantissaExponent
Spot1.10334110334-5
FwdPts25.752575-2
All-in1.105915011059150-7
  • No labels