Class FixOrderEncoder
java.lang.Object
com.quantfinlib.fix.FixOrderEncoder
Garbage-free FIX 4.4 NewOrderSingle encoder — the hot-lane counterpart of
the String-based
NewOrderSingle/FixMessage codec, for
venues that only speak FIX (where the sbe binary adapters aren't
an option, order entry IS the FIX edge, and per-order String building
would put allocation back on the measured path).
Techniques, all standard in commercial garbage-free FIX engines:
- One reusable byte buffer — the body is written at a fixed
offset, then the
8=FIX.4.4|9=len|prefix is written backwards in front of it (no copy, no second pass), and10=checksum|appended; - ASCII digit writers — longs and scaled decimal prices are
rendered digit-by-digit; no
Long.toString, no format calls; - Prices as scaled longs —
mantissa × 10^-decimals(e.g. 1.08505 = mantissa 108505, decimals 5), the venue-grade representation; doubles never touch the encoder; - Cached timestamp date part — the
yyyyMMdd-prefix is recomputed only when the UTC day changes (once per day, off the per-order path); intraday time renders from millis by division; - Symbols pre-registered — dense symbol id → ASCII bytes at setup; the hot path never encodes a String.
Correctness is pinned by round-trip tests: every encoded message is
parsed back by the validated FixMessage.parse(byte[]) (which checks
BodyLength and CheckSum) and field-compared. Zero allocation per encode
is asserted with the allocation-counter test, like every hot-path claim
in this library. Single-threaded: one encoder per session, like the
session itself.
-
Constructor Summary
ConstructorsConstructorDescriptionFixOrderEncoder(String senderCompId, String targetCompId, int maxSymbols, int bufferSize) -
Method Summary
Modifier and TypeMethodDescriptionbyte[]buffer()The reusable buffer holding the last encoded message.intencodeLimit(long msgSeqNum, long clOrdId, int symbolId, Side side, long quantity, long priceMantissa, int priceDecimals, long epochMillis) Encodes a limit NewOrderSingle into the reusable buffer.intencodeMarket(long msgSeqNum, long clOrdId, int symbolId, Side side, long quantity, long epochMillis) Market NewOrderSingle (40=1, no price tag).intlength()Length of the last message.intoffset()Start offset of the last message withinbuffer().registerSymbol(int symbolId, String symbol) Registers a tradeable symbol (cold path, before trading).
-
Constructor Details
-
FixOrderEncoder
-
-
Method Details
-
registerSymbol
Registers a tradeable symbol (cold path, before trading). -
encodeLimit
public int encodeLimit(long msgSeqNum, long clOrdId, int symbolId, Side side, long quantity, long priceMantissa, int priceDecimals, long epochMillis) Encodes a limit NewOrderSingle into the reusable buffer. Zero allocation. The encoded message occupies[offset(), offset() + length())ofbuffer()until the next encode.- Parameters:
msgSeqNum- session sequence number (tag 34)clOrdId- client order id, numeric (tag 11)priceMantissa- price × 10^priceDecimalsas a longpriceDecimals- decimal places (5 for EURUSD, 3 for USDJPY)epochMillis- UTC time for tags 52/60- Returns:
- message length in bytes
-
encodeMarket
public int encodeMarket(long msgSeqNum, long clOrdId, int symbolId, Side side, long quantity, long epochMillis) Market NewOrderSingle (40=1, no price tag). Zero allocation. -
buffer
public byte[] buffer()The reusable buffer holding the last encoded message. -
offset
public int offset()Start offset of the last message withinbuffer(). -
length
public int length()Length of the last message.
-