marketdata-shootout/marketdata.xml

85 lines
4.6 KiB
XML

<?xml version="1.0" encoding="UTF-8"?>
<sbe:messageSchema xmlns:sbe="http://fixprotocol.io/2016/sbe"
package="marketdata_sbe"
id="1"
version="0"
semanticVersion="5.2"
description="Trivial market data schema">
<types>
<!-- "common types" used by SBE -->
<composite name="messageHeader" description="Message identifiers and length of message root.">
<type name="blockLength" primitiveType="uint16"/>
<type name="templateId" primitiveType="uint16"/>
<type name="schemaId" primitiveType="uint16"/>
<type name="version" primitiveType="uint16"/>
</composite>
<composite name="groupSizeEncoding" description="Repeating group dimensions.">
<type name="blockLength" primitiveType="uint16"/>
<type name="numInGroup" primitiveType="uint16"/>
</composite>
<composite name="varStringEncoding" description="Variable length UTF-8 String.">
<type name="length" primitiveType="uint32" maxValue="1073741824"/>
<type name="varData" primitiveType="uint8" length="0" characterEncoding="UTF-8"/>
</composite>
<composite name="varAsciiEncoding" description="Variable length ASCII String.">
<type name="length" primitiveType="uint32" maxValue="1073741824"/>
<type name="varData" primitiveType="uint8" length="0" characterEncoding="ASCII"/>
</composite>
<composite name="varDataEncoding" description="Variable length binary blob.">
<type name="length" primitiveType="uint32" maxValue="1073741824"/>
<type name="varData" primitiveType="uint8" length="0"/>
</composite>
<!-- types we're actually interested in implementing -->
<composite name="Trade">
<type name="price" primitiveType="uint64"/>
<type name="size" primitiveType="uint32"/>
</composite>
<composite name="Quote">
<type name="price" primitiveType="uint64"/>
<type name="size" primitiveType="uint32"/>
<type name="flags" primitiveType="uint8"/>
<ref name="side" type="Side"/>
</composite>
<enum name="Side" encodingType="uint8">
<validValue name="Buy">0</validValue>
<validValue name="Sell">1</validValue>
</enum>
<enum name="MsgType" encodingType="uint8">
<validValue name="Trade">0</validValue>
<validValue name="Quote">1</validValue>
</enum>
</types>
<sbe:message name="MultiMessage" id="1" description="Wrapper for sending multiple message chunks at a time">
<field name="sequence_number" id="1" type="uint64"/>
<group name="messages" id="2">
<!--
Can't embed messages within each other, so the "MultiMessage" block
actually includes each `message` via a group
-->
<field name="timestamp" id="3" type="int64"/>
<!--
SBE specifically doesn't have "union" types, so we include a type tag, and both
`trade` and `quote` as "optional". This style was chosen to approximate how
Cap'n Proto and Flatbuffers do it:
https://github.com/real-logic/simple-binary-encoding/issues/232
However, space is actually reserved for *both* `trade` and `quote` in the message;
that is, the payload size is the same if neither, one, or both are filled.
Other ways you can try to emulate unions:
1. Use a "payload header" composite type and promote "trade" and "quote" to <sbe:message>;
SBE can distinguish message types based on the SBE header.
2. Create a "group" for each message type; adds an extra `u16` per type, but overall payload
size goes down because we no longer reserve space that is potentially unused.
3. Split up the message components into individual <composite/> blocks, and write
a state machine (by hand) to chain the blocks. For a better explanation,
see "session types" in:
https://polysync.io/blog/session-types-for-hearty-codecs
-->
<field name="msg_type" id="4" type="MsgType"/>
<field name="trade" id="5" type="Trade" presence="optional"/>
<field name="quote" id="6" type="Quote" presence="optional"/>
<data name="symbol" id="100" type="varAsciiEncoding"/>
</group>
</sbe:message>
</sbe:messageSchema>