REST API
WebSocket API
Introduction
The WebSocket API provides developers a way to access streaming data from our backend engines.
The URLs are:
- sandbox: wss://node1.modulusexchange.com/ws
- production: wss://node1.modulusexchange.com/ws
Using WebSocket API you can:
- Access real time price points for products
- Reduce the latency introduced by polling the REST API
- Access real time Market updates, Balance Updates & Chart updates
Upon connection, if no message is sent via the WebSocket connection (typically not being subscribed to any instrument) within 60 seconds, the connection will be considered idle and will be dropped.
We currently only allow three concurrent WebSocket connections Any new connection that is made that exceeds this limit will cause the disconnection of the oldest WebSocket connection. For example, in the UAT environment: If client A connects, followed by client B, followed by client C, client A will be disconnected. We encourage WebSocket clients to be configured to automatically reconnect in the event of a disconnection.
The WebSocket API provides developers a way to access streaming data from our pricing engines.
Methods
Method Name | Description |
---|---|
login | used for authenticating a user to receive user specific tickers |
logout | used for closing the authenticated session |
subscribe | used to subscribe specific event see events table below |
unsubscribe | used for closing existing open subscriptions |
Events
Event Code | Event Name | User Specific (Auth Required) | Extra Params |
---|---|---|---|
MK | Markets | ||
OB | Order Books | ||
RT | Recent Trades | ||
OT | Order Book Totals | ||
CH | Charts | Intervals: 1, 5, 15 & 60 mins | |
BL | Balances | Yes | |
PO | Pending Orders | Yes |
Authentication
For security reasons, IP whitelisting is required to consume our API and whitelists are different for each environment. To authenticate a request, the token key must be included in its Authorization HTTP header. The key must be prefixed by the string literal “Token ”. For instance:
Authorization: Token 9b44b09199c61bcf9416ad846dd0e4
Once authenticated, you will receive a message containing your tradable instruments.
Using Bearer Token
Request:
{
"method":"login",
"token":"your_bearer_token"
}
Response:
{
"method":"login",
"status":"success",
"message":"Logged in."
}
To authenticate a request, the bearar token must be included in its Authorization HTTP header.
Using API Keys
// recvWindow: 45 sec
Request:
{
"method": "login",
"api": {
"public_key": "api-public-key",
"timestamp": 1608028160
},
"hmac": "computed-hmac-of-only-api-object"
}
Response:
{
"method":"login",
"status":"success",
"message":"Logged in."
}
Closing Authenticated Session
Request:
{
"method":"logout"
}
Response:
{
"method":"logout",
"status":"success",
"message":"Logged out."
}
Subscribing
The WebSocket API works on a subscription model. After subscribing to an event, you will receive the response with status field set to success. Following the subscription, you will receive updates untill you unsubscribe or close the connection.
Markets
{
"method": "stream",
"event": "MK",
"data": [
{
"base": "XLM",
"quote": "BTC",
"price": 600.00000000,
"change_in_price": 119999900.00000000,
"prev_price": 0.00050000,
"base_volume": 29178.00000000,
"quote_volume": 48.63000000,
"full_name": "Stellar",
"low_24hr": 0.00050000,
"high_24hr": 600.00000000,
"maker_fee": 1.00000000,
"taker_fee": 2.00000000,
"maker_fee_pro": 1.00000000,
"taker_fee_pro": 2.00000000,
"min_trade_amount": 0.00000001,
"min_tick_size": 0.00000001,
"min_order_value": 0.00000001
},
{
"base": "BCH",
"quote": "USD",
"price": 600.00000000,
"change_in_price": 100.00000000,
"prev_price": 0.00000000,
"base_volume": 29172.00000000,
"quote_volume": 48.62000000,
"full_name": "BCH",
"low_24hr": 600.00000000,
"high_24hr": 600.00000000,
"maker_fee": 1.00000000,
"taker_fee": 1.00000000,
"maker_fee_pro": 1.00000000,
"taker_fee_pro": 1.00000000,
"min_trade_amount": 0.00000001,
"min_tick_size": 0.00000001,
"min_order_value": 0.00000001
},
{
"base": "BTC",
"quote": "USD",
"price": 600.00000000,
"change_in_price": -94.29588933,
"prev_price": 10518.73000000,
"base_volume": 3690.00000000,
"quote_volume": 6.15000000,
"full_name": "BTC",
"low_24hr": 600.00000000,
"high_24hr": 600.00000000,
"maker_fee": 1.00000000,
"taker_fee": 1.00000000,
"maker_fee_pro": 1.00000000,
"taker_fee_pro": 1.00000000,
"min_trade_amount": 0.00000001,
"min_tick_size": 0.00000001,
"min_order_value": 0.00000001
}
]
}
Request
method | event |
---|---|
subscribe | 'MK' |
Example
{ "method": "subscribe", "events": [ "MK" ] } |
---|
Order Books
// bid/ask, array of [price,size]
{
"method":"stream",
"event":"OB.BTC_USD",
"data":{
"bids":[
599.0000000,
212.2500000
],
"asks":[
[
600.00000000,
125.27000000
]
]
}
}
Request
method | event |
---|---|
subscribe | 'OB.BTC_USD' OR 'OB.BCH_USD' |
Example
{ "method": "subscribe", "events": [ "OB.BTC_USD", "OB.BCH_USD" ] } |
---|
Order Books Differential
Stream:
{
"method": "stream",
"event": "OD.LTC_BTC",
"data": {
"bids": {
"inserted": [],
"removed": [],
"changed": []
},
"asks": {
"inserted": [
[
0.00473426,
1.00000000
]
],
"removed": [],
"changed": []
}
}
}
Request
method | event |
---|---|
subscribe | 'OD.LTC_BTC' |
Example
{ "method": "subscribe", "events": [ "OD.LTC_BTC" ] } |
---|
Recent Trades
// Recent 100 trades, sent every second
{
"method":"stream",
"event":"RT.BTC_USD",
"data":[
{
"order_id": 1607425823,
"rate": 600.00000000,
"volume": 0.01000000,
"execution_side": "BUY",
"timestamp": "2020-12-08T11:10:23.442Z"
},
{
"order_id": 1607425823,
"rate": 600.00000000,
"volume": 0.01000000,
"execution_side": "BUY",
"timestamp": "2020-12-08T11:10:23.442Z"
}
]
}
Request
method | event |
---|---|
subscribe | 'RT.BTC_USD' OR 'RT.BCH_USD' |
Example
{ "method": "subscribe", "events": [ "RT.BTC_USD", "RT.BCH_USD" ] } |
---|
Pending Orders
{
"method":"stream",
"event":"PO.ALL",
"data":[
{
"order_id": 123722351,
"user_id": 102999,
"base": "ETH",
"quote": "EUR",
"rate": 20.00000000,
"volume": 1.50000000,
"pending": 1.50000000,
"type": "LIMIT",
"tif": "GTC",
"side": "BUY",
"timestamp": "2020-12-14T10:12:23.8824761Z"
}
]
}
{
"method":"stream",
"event":"PO.ETH_EUR",
"data":[
{
"order_id": 123722351,
"user_id": 102999,
"base": "ETH",
"quote": "EUR",
"rate": 20.00000000,
"volume": 1.50000000,
"pending": 1.50000000,
"type": "LIMIT",
"tif": "GTC",
"side": "BUY",
"timestamp": "2020-12-14T10:12:23.8824761Z"
}
]
}
Request
method | event |
---|---|
subscribe | 'PO.BTC_USD' OR 'PO.BCH_USD' |
Example
{ "method": "subscribe", "events": [ "PO.BTC_USD", "PO.BCH_USD" ] } |
---|
Balances
{
"method":"stream",
"event":"BL",
"data":{
"ALGO":{
"balance":0.0,
"balance_in_trade":0.0
},
"BCH":{
"balance":0.0,
"balance_in_trade":0.0
},
"BTC":{
"balance":0.0,
"balance_in_trade":0.0
},
"EUR": {
"balance": 580.0,
"balance_in_trade": 270.0
}
}
}
Request
method | event |
---|---|
subscribe | 'BL' |
Example
{ "method": "subscribe", "events": [ "BL" ] } |
---|
Charts
// BTC_USD charts for 1 minute interval.
{
"method":"stream",
"event":"CH.BTC_USD.1",
"data":{
"time":1607938920000,
"open":600.00000000,
"close":600.00000000,
"high":600.00000000,
"low":600.00000000,
"volume":0.00000000
}
}
Request
method | event |
---|---|
subscribe | 'CH.BTC_USD.5' OR 'CH.BCH_USD.15' |
Example
{ "method": "subscribe", "events": [ "CH.BTC_USD.5", "CH.BCH_USD.15" ] } |
---|
Order Book Totals
{
"method":"stream",
"event":"OT.BTC_USD",
"data":{
"total_buys_base":0.0,
"total_buys_quote":0.0,
"total_sells_base":125.27,
"total_sells_quote":75162.0
}
}
Request
method | event |
---|---|
subscribe | 'OT.BTC_USD' OR 'OT.BCH_USD' |
Example
{ "method": "subscribe", "events": [ "OT.BTC_USD", "OT.BCH_USD" ] } |
---|
FIX API
Introduction
This API documentation describes FIX 5.0 (SP2) specification for connecting with Modulus Exchange (Spot). After connecting, logging on, and synchronizing sequence numbers, the client can submit orders.
Download
For your convenience, Modulus maintains our custom dictionary in QuickFIX XML form:
Environment | File |
---|---|
Production | http://api.modulusexchange.com/uploads/FIX50SP2-Dictionary.zip |
Connecting
Modulus's primary trading platform and network point of presence (PoP) is housed in the OVH UK data center in London, United Kingdom. Customers can cross connect from their infrastructure or leverage an approved extranet provider to access Modulus production Market Data feeds, and Order Entry sessions.
Steps to get connected to our FIX infrastructure:
Complete Account Verification
If your firm has not done so already, please complete the Institutional Account Verification Process and obtain our FIX server's IP and Port Number while getting your public IP whitelisted.
Get connected
Once on-boarded as a Modulus customer, generate an API key-pair from your account.
Sandbox and Testing
Modulus operates a Sandbox environment which acts as a replica of our production environment. Modulus strongly recommends that all FIX customers create a Sandbox account to test their workflows. Please follow these steps to get a FIX Sandbox environment setup:
SETUP A SANDBOX ACCOUNT
Create a Sandbox account by going to: https://demo.modulusexchange.com
PERMISSION YOUR TEST IP
E-mail deployment@modulus.io and specify the email address used to setup your Sandbox account and the Source IP that you will be using to connect to the FIX Sandbox. We will respond back once the IP addresses have been enabled. We will also provide you with the Sender and Target CompId that should be used to connect to the test environment.
TEST YOUR WORKFLOW THOROUGHLY
Test all messaging workflows specified in our FIX API documentation. (Modulus currently only supports FIX 5.0 (SP2))
Submitting an order
- Client sends server → New Order Single Limit
message or a New Order Single Market message - Does Modulus accept the order?
- Yes, order is accepted for initial processing
- Server sends client ← an Execution Report <8> for a new order with:
- ExecType <150> set to
0 = New
- OrdStatus <39> set to
0 = New
- ExecType <150> set to
- Is the order marketable?
- Yes, server executes one or more initial fills
- Server sends client ← an Execution Report <8> for each fill or partial fill (see below for more details)
- Does the order have remaining quantity?
- Yes, server puts the remaining quantity on the book
- No, server closes the order
- No, server puts the entire quantity of the order on the book
- Server sends client ← an Execution Report <8> for a new order with:
- No, order is rejected
- Server sends client ← an Execution Report <8> indicating the order was rejected with:
- ExecType <150> set to
8 = Rejected
- OrdStatus <39> set to
8 = Rejected
- ExecType <150> set to
- Server sends client ← an Execution Report <8> indicating the order was rejected with:
- Yes, order is accepted for initial processing
Submitting a stop limit order
- Client sends server → New Order Single Stop Limit
message or with OrdType <40> 4 = Stop Limit, and either a StopPx <99> value less than or equal to Price <44> on a Side <54> 1 = Buy, or a StopPx <99> value greater than or equal to Price <44> on a Side <54> 2 = Sell. - Does Modulus accept the order?
- Yes, order is accepted for initial processing
- Server sends client ← an Execution Report <8> for a new order with:
- ExecType <150> set to
0 = New
- OrdStatus <39> set to
0 = New
- StopPx <99> set to same StopPx value provided on entry
- ExecType <150> set to
- Has a trade occurred that would trigger your stop order?
- Yes, the stop order triggers and sends client ← an Execution Report <8> message with the child limit order details.
- No, the stop order stays hidden and resting until a qualifying trade triggers it, or until the order is cancelled.
- Is the order marketable?
- Yes, server executes one or more initial fills
- Server sends client ← an Execution Report <8> for each fill or partial fill (see below for more details)
- Does the order have remaining quantity?
- Yes, server puts the remaining quantity on the book
- No, server closes the order
- No, server puts the entire quantity of the order on the book
- Server sends client ← an Execution Report <8> for a new order with:
- No, order is rejected
- Server sends client ← an Execution Report <8> indicating the order was rejected with:
- ExecType <150> set to
8 = Rejected
- OrdStatus <39> set to
8 = Rejected
- ExecType <150> set to
- Server sends client ← an Execution Report <8> indicating the order was rejected with:
- Yes, order is accepted for initial processing
When trades occur
In the event of a partial fill, Modulus sends an Execution Report <8> with:
- ExecType <150> set to
F = Trade
- OrdStatus <39> set to
1 = Partially filled
When the order is completely filled, Modulus sends an Execution Report <8> with:
- ExecType <150> set to
F = Trade
- OrdStatus <39> set to
2 = Filled
Canceling an order
- Client sends an Order Cancel Request
- If successful, Modulus responds with an Execution Report <8> with:
- ExecType <150> set to
4 = Canceled
- OrdStatus <39> set to
4 = Canceled
- ExecType <150> set to
- If unsuccessful, Modulus responds with an Order Cancel Reject <9> explaining why the request to cancel the order could not be fulfilled.
Canceling all orders
- Client sends an Order Mass Cancel Request
- Modulus responds with an Order Mass Cancel Report <35> with:
We only support MassCancelRequestType <530> with value 1 = Cancel orders for a security
Requesting order status
- Client sends an Order Status Request
- Modulus responds with an Execution Report <8> with:
Supported symbols
The following symbols are valid values for a Symbol <55> field.
Symbols are formatted as BTC_USD where prices are in USD and quantities are in BTC.
Precision on the exchange
Quantity and price on incoming orders are strictly held to the minimums and increments on the table shown above.
However, once on the exchange, quantities and notional values may exhibit additional precision down to two decimal places past the "minimum order increment" listed above. For instance, it is possible that a btcusd trade could execute for a quantity of 0.0000000001 (1e-10) BTC. This is due to:
incoming market orders that may result in partial fills fees holds This additional precision is marketable once on the exchange.
Your account balances are maintained to full fractional precision in each currency.
Understanding price and quantity
RAW
8=FIX.5.0.SP2|9=137|35=D|34=2237|49=CLIENT|52=20160218-22:25:24.277|56=Modulus|11=SOME_ORDER|38=5|40=2|44=420.18|54=1|55=BTCUSD|59=1|60=20160218-17:24:15.0.SP253|10=066|
HEADER
8 BeginString: FIX.5.0.SP2
9 BodyLength: 137
34 MsgSeqNum: 2237
35 MsgType: NewOrderSingle (D)
49 SenderCompID: CLIENT
52 SendingTime: 20160218-22:25:24.277
56 TargetCompID: Modulus
BODY
11 ClOrdID: SOME_ORDER
38 OrderQty: 5
40 OrdType: LIMIT (2)
44 Price: 420.18
54 Side: BUY (1)
55 Symbol: BTCUSD
59 TimeInForce: GOOD_TILL_CANCEL (1)
60 TransactTime: 20160218-17:24:15.0.SP253
TRAILER
10 CheckSum: 066
In a New Order Single
Currency-denominated fields
Message | Fields denominated in price currency | Fields denominated in quantity currency |
---|---|---|
New Order Single |
Price <44> |
OrderQty <38>
MinQty <110> |
Order Cancel Request |
OrderQty <38> | |
Execution Report <8> |
Price <44>
AvgPx <6> LastPx <31> |
OrderQty <38>
CumQty <14> LeavesQty <151> LastQty <32> |
IOI <6> | StipulationValue <234> when StipulationType <233> is PRICE |
IOIQty <27>
StipulationValue <234> when StipulationType <233> is MINQTY |
FEES
The amount in Commission <12> is denominated in the currency specified by the currency code value in CommCurrency <479>.
Identifiers assigned by Modulus
Tag | Name | Defined in | Description |
---|---|---|---|
49 | SenderCompID | Standard Header |
Assigned value used to identify the firm sending the message.
|
56 | TargetCompID | Standard Header |
Assigned value used to identify the firm sending the message.
|
37 | OrderID |
Globally unique order identifier assigned by Modulus. This order id is assigned to an individual order for the lifetime of the order. When the order appears in an Execution Report <8> with ExecType <150> = 0 = New and OrdStatus <39> = 0 = New, then the order is on the book. In the case of an order cancel reject, the value of this field is NONE. |
|
17 | ExecID |
Globally unique event identifier assigned by Modulus. In context, this event id may refer to any of the following events:
|
Standard header
The Standard Header is required on every message.
PossResend <97> is not supported. Modulus will report the last sequence number that the exchange received in the header of the Logon message. The client should assume that any events that the server requests to be replayed have not been acted upon: see Beginning a session for details.
Tag | Name | Req | Description |
---|---|---|---|
8 | BeginString | Y | Identifies the beginning of new message and protocol version. Always the first tag in the message. Valid value:
|
9 | BodyLength | Y | Message length, in bytes, forward to the CheckSum <10> field. Always the second tag in the message. |
35 | MsgType | Y | Defines message type. Always the third tag in the message. |
34 | MsgSeqNum | ||
49 | SenderCompID | Y | Assigned value used to identify the firm sending the message. |
43 | PossDupFlag | N* | Indicates possible retransmission of message with this sequence number. Valid value:
|
52 | SendingTime | Y | Time of message transmission (always expressed in UTC). |
56 | TargetCompID | Y | Assigned value used to identify the firm receiving the message. |
115 | OnBehalfOfCompID | N* | Assigned value used to identify firm originating message if the message was delivered by a third party such as an OMS or OEMS: required when an OMS/OEMS submits or cancels orders on behalf of another Modulus account.
|
122 | OrigSendingTime | N* | Original time of message transmission (always expressed in UTC) when transmitting orders as the result of a resend request. *Required for a re-transmitted message. |
Standard Trailer
The Standard Trailer is required on every message.
Tag | Name | Req | Description |
---|---|---|---|
10 | CheckSum | Y | Three byte, simple checksum. Always the last tag in the message. |
Session-Level Messages
Establishing a connection
- Client sends server →
Logon <A>
message - Is client ResetSeqNumFlag <141> to Y?
- Yes, reset sequence numbers and proceed.
- server resets next expected client client sequence number
- server resets its own sequence number
- server responds with ←
Logon <A>
message with reset sequence number - client sends server → Heartbeat <0>
- No, negotiate sequence numbers on both sides
- Is client MsgSeqNum <34> value what the server is expecting?
- No, value is greater than expected
- server responds with ←
Logon <A>
message - server sends client ← Resend Request <2>
- client sends server → Sequence Reset <4> ( GapFillFlag <123> =
Y
)
- server responds with ←
- No, value is less than expected
- server disconnects
- after checking what happened, client re-sends
Logon <A>
message with ResetSeqNumFlag <141> field set toY
- client sends server → Sequence Reset <4> ( GapFillFlag <123> =
Y
)
- Otherwise
- server sends client ← Heartbeat <0>
- No, value is greater than expected
- Is server MsgSeqNum <34> value what the client is expecting?
-
No, value is greater than expected
- server responds with ←
Logon <A>
message - client sends server → Resend Request <2>
- replay from server to client proceeds
- server responds with ← message PossDupFlag <43> = Y
- replay from server to client is complete
- server responds with ← Heartbeat <0>
- server responds with ←
- No, value is less than expected
- client disconnects or sends server → Logout <5>
- Modulus coordinates with the client to triage so the FIX connection can be re-established
- Otherwise
- client sends server → Heartbeat <0>
-
No, value is greater than expected
- Is client MsgSeqNum <34> value what the server is expecting?
- Yes, reset sequence numbers and proceed.
3. Success! Your FIX connection is established.
When can sequence numbers be reset?
Modulus runs the server side of the FIX connection ("acceptor"). Modulus never resets sequence numbers on the server side during the logon workflow unless the client explicitly requests it.
The client ("initiator") can reset sequence numbers during Logon <A>
by setting ResetSeqNumFlag <141> to Y
.
Modulus recommends that client consider configuring the FIX initiator to automatically reset sequence numbers under the following conditions:
- logon
- logout
- disconnect
- error
While synchronizing sequence numbers after a replay, the client may send a Sequence Reset <4> with GapFillFlag <123> = Y
in lieu of a replay.
Ending a connection
The client may send the server an optional Logout <5> message but the exchange will not interpret its absence as being an abnormal condition.
Under certain conditions, the server may send the client a Logout <5> message where the Text <58> field contains the reason, such as scheduled maintenance.
Logon <A>
The Logon <A>
message must be the first message sent by the application requesting to initiate a FIX session. The Logon <A>
message authenticates an institution establishing a connection to Modulus.
Upon receipt of a Logon <A>
message, Modulus will authenticate the institution requesting connection by validating Username <553> , SenderCompID <49> and TargetCompID <56> identifying the institution. The server will then issue a Logon <A>
message as acknowledgment that the connection request has been accepted. The acknowledgment Logon can also be used by the institution to validate that the connection was established with the correct party. If validation fails, the connection will be dropped without a Reject <2>.
Tag | Name | Req | Description |
---|---|---|---|
Standard Header | Y | MsgType = A | |
141 | ResetSeqNumFlag | N | Should be set to `Y` when the client wants to indicates that the both sides of the FIX session should reset sequence numbers. |
98 | EncryptMethod | Y | Modulus does not support encryption. Valid value:
|
108 | HeartBtInt | Y | Heartbeat interval in seconds. Valid value:
|
Standard Trailer | Y |
Heartbeat <0>
The Heartbeat <0> monitors the status of the communication link and identifies when the last of a string of messages was not received. The only supported heartbeat interval, as specified by the Logon <A>
message, is 30 seconds.
When either end of a FIX connection has not sent any data for HeartBtInt <108> seconds, it will transmit a Heartbeat <0> message. When either end of the connection has not received any data for ( HeartBtInt <108> + "some reasonable transmission time") seconds, it will transmit a Test Request <1> message. If there is still no Heartbeat <0> message received after ( HeartBtInt <108> + "some reasonable transmission time") seconds then the connection should be considered lost and corrective action be initiated.
Note that a Test Request <1> message can still be sent independent of the value of the HeartBtInt <108>, which will force a Heartbeat <0> message.
Heartbeats issued as the result of Test Request <1> must contain the TestReqID <112> transmitted in the Test Request <1> message. This is useful to verify that the Heartbeat <0> is the result of the Test Request <1> and not as the result of a regular timeout.
Tag | Name | Req | Description |
---|---|---|---|
Standard Header | Y | MsgType = 0 | |
112 | TestReqID | N* | Required when the heartbeat is the result of a Test Request <1> message |
Standard Trailer | Y |
Test Request <1>
The Test Request <1> message forces a heartbeat from the opposing application. The Test Request <1> message checks sequence numbers or verifies communication line status. The opposite application responds to the Test Request <1> with a Heartbeat <0> containing the TestReqID <112>.
The TestReqID <112> verifies that the opposite application is generating the heartbeat as the result of Test Request <1> and not a normal timeout. The opposite application includes the TestReqID <112> in the resulting Heartbeat <0>. Any string can be used as the TestReqID <112> (one suggestion is to use a timestamp string).
Tag | Name | Req | Description |
---|---|---|---|
Standard Header | Y | MsgType = 0 | |
112 | TestReqID | Y | Identifier included in Test Request <1> message to be returned in resulting Heartbeat <0> |
Standard Trailer | Y |
Resend Request <2>
The resend request is sent by the receiving application to initiate the retransmission of messages. This function is utilized if a sequence number gap is detected, if the receiving application lost a message, or as a function of the initialization process.
The resend request can be used to request a single message, a range of messages or all messages subsequent to a particular message.
Note: the sending application may wish to consider the message type when resending messages; e.g. if a new order is in the resend series and a significant time period has elapsed since its original inception, the sender may not wish to retransmit the order given the potential for changed market conditions. (The Sequence Reset <4> - Gap Fill message is used to skip messages that a sender does not wish to resend.)
Note: it is imperative that the receiving application process messages in sequence order, e.g. if message number 7 is missed and 8-9 received, the application should ignore 8 and 9 and ask for a resend of 7-9, or, preferably, 7-0 (0 represents infinity). This latter approach is strongly recommended to recover from out of sequence conditions as it allows for faster recovery in the presence of certain race conditions when both sides are simultaneously attempting to recover a gap.
- To request a single message: BeginSeqNo <7> = EndSeqNo <16>
- To request a range of messages: BeginSeqNo <7> = first message of range, EndSeqNo <16> = last message of range<
- To request all messages subsequent to a particular message: BeginSeqNo <7> = first message of range, EndSeqNo <16> = 0 (represents infinity) .
Tag | Name | Req | Description |
---|---|---|---|
Standard Header | Y | MsgType = 2 | |
7 | BeginSeqNo | Y | |
16 | EndSeqNo | Y | |
Standard Trailer | Y |
Reject <3>
Modulus sends a Reject <3> message when a message is received but cannot be properly processed due to a session-level rule violation. A reject is typically a serious error in the trading application's session logic.
Tag | Name | Req | Description |
---|---|---|---|
Standard Header | Y | MsgType = 3 | |
45 | RefSeqNum | Y | MsgSeqNum <34> of the rejected message. |
58 | Text | N | Explanation for rejection |
371 | RefTagID | N | The tag number of the FIX field being referenced. |
372 | RefMsgType | N | The MsgType <35> of the rejected message. |
373 | SessionRejectReason | N | Code to identify the reason for the Reject <3> message. Valid values:
|
Standard Trailer | Y |
Sequence Reset <4>
The Sequence Reset <4> message is used in response to a Resend Request <2> message when one or more messages must be skipped over for the following reasons:
- During normal resend processing, the sending application may choose not to send a message (e.g. an aged order).
- During normal resend processing, a number of administrative messages are skipped and not resent (such as Heartbeat <0> and Test Request <1>).
Modulus does not support Reset mode ( GapFillFlag <123> not present or equal to N).
Tag | Name | Req | Description |
---|---|---|---|
Standard Header | Y | MsgType = 4 | |
36 | NewSeqNo | Y | New sequence number. The receiver should expect this to be the sequence number of the following message. |
123 | GapFillFlag | Y | Indicates that the sender is skipping messages rather than resending them. Valid values:
|
Standard Trailer | Y |
Logout <5>
The Logout <5> message initiates or confirms the termination of a FIX session.
Tag | Name | Req | Description |
---|---|---|---|
Standard Header | Y | MsgType = 5 | |
58 | Text | N | Reason for logging out. |
Standard Trailer | Y |
Exchange-Bound Messages
Symbol List Request
A Symbol List Request
See Examples: Request for the symbol list for sample requests and responses.
Tag | Name | Req | Description |
---|---|---|---|
Standard Header | Y | MsgType = X | |
320 | SecurityReqID | Y | Unique identifier of this request. |
559 | SecurityListRequestType | Y | The type/criteria of the request. Valid values:
|
Standard Trailer | Y |
Symbol List <y>
A Symbol List
See Examples: Request for the symbol list for sample requests and responses.
Tag | Name | Req | Description |
---|---|---|---|
Standard Header | Y | MsgType = y | |
320 | SecurityReqID | Y | Unique identifier of the Symbol List Request |
322 | SecurityResponseID | Y | Identifier for this message. |
560 | SecurityRequestResult | Y | The result of this request. Valid values:
|
146 | NoRelatedSym | Y | Specifies the number of returned symbols. |
55 | Symbol | Y | Market data symbol requested.
See Symbol List |
Standard Trailer | Y |
Market Data Request <V>
Subscribes the current session to a Market Data - Snapshot/Full Refresh
See Examples: Market Data Requests for sample requests and responses.
Tag | Name | Req | Description |
---|---|---|---|
Standard Header | Y | MsgType = V | |
262 | MDReqID | Y | Unique identifier of the market data request. Uniqueness must be guaranteed by the institution for the duration of the connection to the market data channel. |
263 | SubscriptionRequestType | Y | Indicates what type of response is expected. Valid values:
|
264 | MarketDepth | Y | Depth of the book to receive snapshot and updates for. Valid values:
|
267 | NoMDEntryTypes | Y | Number of MDEntryType <269> fields requested. |
269 | MDEntryType | Y | Type of market data entry to receive snapshots and updates for. Valid values:
|
146 | NoRelatedSym | Y | Number of symbols requested. |
55 | Symbol | Y | Market data symbol requested.
See Symbol List |
Standard Trailer | Y |
Market Data - Snapshot / Full Refresh <W>
The initial response to a Market Data Request
Tag | Name | Req | Description |
---|---|---|---|
Standard Header | Y | MsgType = W | |
262 | MDReqID | Y | This message is in response to the Unique identifier of the Market Data Request |
55 | Symbol | Y | Symbol of market data entry. |
268 | NoMDEntries | Y | Number of entries in this message. |
269 | MDEntryType | Y | Type of market data update. Valid values:
|
270 | MDEntryPx | Y | Price of market data entry. |
271 | MDEntrySize | Y | Quantity of market data entry. |
Standard Trailer | Y |
Market Data - Incremental Refresh <X>
The initial response to a Market Data Request
See Examples: Market Data Responses for examples of bids, offers events.
Tag | Name | Req | Description |
---|---|---|---|
Standard Header | Y | MsgType = X | |
262 | MDReqID | Y | This message is in response to the Unique identifier of the Market Data Request |
268 | NoMDEntries | Y | Number of entries in this message. |
279 | MDUpdateAction | Y | Type of market data update. Valid values:
|
269 | MDEntryType | Y | Type of market data entry. Valid values:
|
55 | Symbol | Y | Symbol of market data entry. Required when MDEntryType is not `3 = Index Value` |
270 | MDEntryPx | Y | Price of market data entry. |
271 | MDEntrySize | N* | Quantity of market data entry. Required when MDEntryType is not `3 = Index Value` |
Standard Trailer | Y |
Market Data Request Reject <Y>
Tag | Name | Req | Description |
---|---|---|---|
Standard Header | Y | MsgType = X | |
262 | MDReqID | Y | Unique identifier of the market data request being rejected. |
281 | MDReqRejReason | N | Reason why Market Data Request Valid values:
|
Standard Trailer | Y |
New Order Single <D> (LIMIT)
To submit a new limit order to Modulus, send a New Order Single
Modulus will respond to a New Order Single
Tag | Name | Req | Description |
---|---|---|---|
Standard Header | Y | MsgType = D | |
11 | ClOrdID | Y | Unique identifier of the order as assigned by the institution. Uniqueness must be guaranteed by the institution for the duration of the connection to the order entry channel. |
38 | OrderQty | Y | Decimal quantity. Full quantity will be visible on the book. |
40 | OrdType | Y | Order type. Valid values:
|
44 | Price | Y | Decimal price. |
54 | Side | Y | Side of the order. Valid values:
|
55 | Symbol | Y | Ticker symbol of the order. e.g. BTC_USD |
59 | TimeInForce | Y | Specifies how long the order remains in effect. Use 7 (At the close) for Auction orders Valid values:
|
60 | TransactTime | Y | Time of order creation (expressed in UTC). |
Standard Trailer | Y |
New Order Single <D> (MARKET)
To submit a new limit order to Modulus, send a New Order Single
Modulus will respond to a New Order Single
Tag | Name | Req | Description |
---|---|---|---|
Standard Header | Y | MsgType = D | |
11 | ClOrdID | Y | Unique identifier of the order as assigned by the institution. Uniqueness must be guaranteed by the institution for the duration of the connection to the order entry channel. |
38 | OrderQty | Y | Decimal quantity. Full quantity will be visible on the book. |
40 | OrdType | Y | Order type. Valid values:
|
54 | Side | Y | Side of the order. Valid values:
|
55 | Symbol | Y | Ticker symbol of the order. e.g. BTC_USD |
60 | TransactTime | Y | Time of order creation (expressed in UTC). |
Standard Trailer | Y |
New Order Single <D> (STOP LIMIT)
To submit a new limit order to Modulus, send a New Order Single
Modulus will respond to a New Order Single
Tag | Name | Req | Description |
---|---|---|---|
Standard Header | Y | MsgType = D | |
11 | ClOrdID | Y | Unique identifier of the order as assigned by the institution. Uniqueness must be guaranteed by the institution for the duration of the connection to the order entry channel. |
38 | OrderQty | Y | Decimal quantity. Full quantity will be visible on the book. |
40 | OrdType | Y | Order type. Valid values:
|
44 | Price | Y | Decimal price. |
99 | StopPx | Y | Decimal price. StopPx is required when OrdType<40> is 4 = Stop Limit. |
54 | Side | Y | Side of the order. Valid values:
|
55 | Symbol | Y | Ticker symbol of the order. e.g. BTC_USD |
59 | TimeInForce | Y | Specifies how long the order remains in effect. Use 7 (At the close) for Auction orders Valid values:
|
60 | TransactTime | Y | Time of order creation (expressed in UTC). |
Standard Trailer | Y |
Order Cancel Request <F>
The Order Cancel Request
Modulus cancels order on the basis of the value in the OrigClOrdID <41> field. All other fields are required in the FIX specs but will be disregarded.
- if the order can successfully be canceled before being completely filled, an Execution Report <8> with ExecType <150> set to
4 = Canceled
- if the request fails, an Order Cancel Reject <9> message with CxlRejReason <102> of 1 = Unknown order
Tag | Name | Req | Description |
---|---|---|---|
Standard Header | Y | MsgType = F | |
11 | ClOrdID | Y | Unique identifier of the order as assigned by the institution. Uniqueness must be guaranteed by the institution for the duration of the connection to the order entry channel. |
41 | OrigClOrdID | Y | ClOrdID <11> of the order to cancel. Needs to correspond to a current outstanding order submitted during this trading session. |
38 | OrderQty | Y | Quantity in the order referred to by OrigClOrdID <41> |
54 | Side | Y | Side of the order. Valid values:
|
55 | Symbol | Y | Ticker symbol of the order. e.g. BTC_USD |
60 | TransactTime | Y | Time of order creation (expressed in UTC). |
Standard Trailer | Y |
Execution Report <8>
Modulus uses the Execution Report <8> message to:
- confirm the receipt of an order
- confirm a stop order has triggered
- confirm the successful cancellation of an order
- relay fill information on orders
- reject orders
Each execution report contains two fields which are used to communicate both the current state of the order as understood by the exchange ( OrdStatus <39>) and the purpose of the message ( ExecType <150>).
Tag | Name | Req | Description |
---|---|---|---|
Standard Header | Y | MsgType = 8 | |
37 | OrderID | Y | Unique order identifier assigned by Modulus. |
11 | ClOrdID | Y | Unique identifier of the order as assigned by the institution. |
41 | OrigClOrdID | N* | ClOrdID <11> of the order to cancel. Needs to correspond to a current outstanding order submitted during this trading session. * Required for a response to an Order Cancel Request |
17 | ExecID | Y | Unique event ID assigned by Modulus. |
150 | ExecType | Y | Describes the purpose of the Execution Report. Valid values:
|
18 | ExecInst | N | Indicates if an order was Maker-or-Cancel. Valid values:
|
39 | OrdStatus | Y | Describes the current order status. Valid values:
|
55 | Symbol | Y | Ticker symbol of the order. e.g. BTC_USD |
54 | Side | Y | Side of the order. Valid values:
|
44 | Price | N* | Limit price of the order. * Required if ExecType <150> is not `8 = Rejected`. |
99 | StopPx | N* | Stop price of the order. * Required if ExecType <150> is not `8 = Rejected` and responding to a OrdType <40> is `4 = Stop Limit` order entry. |
6 | AvgPx | Y | Calculated average price of fills on this order. Zero for order with no fills. |
31 | LastPx | N* | Price of the fill. This field is only present when the order is updated due to a match on the exchange. * Required if ExecType <150> is `F = Trade`. |
14 | CumQty | Y | Total quantity of the order that is filled. |
38 | OrderQty | N* | Decimal amount of BTC to purchase. The general rule is: OrderQty <38> = CumQty <14> + LeavesQty <151>. * Required if ExecType <150> is not `8 = Rejected`. |
151 | LeavesQty | Y | Quantity <53> open for further execution. If the OrdStatus <39> is `4 = Canceled` or `8 = Rejected` (in which case the order is no longer active) then LeavesQty <151> could be 0, otherwise LeavesQty <151> = OrderQty <38> - CumQty <14>. |
32 | LastQty | N* | Quantity of the fill. This field is only present when the order is updated due to a match on the exchange. * Required if ExecType <150> is `F = Trade`. |
103 | OrdRejReason | N* | Reason the order was rejected. Valid values:
|
58 | Text | N* | Reason the order was rejected or canceled. * Required if OrdRejReason <103> is 99 = Other, or if OrdStatus <39> is 4 = Canceled and ExecType <150> is 4 = Canceled. |
59 | TimeInForce | Y | Specifies how long the order remains in effect. Valid values:
|
60 | TransactTime | Y | Time the transaction represented by this Execution Report <8> occurred (expressed in UTC). |
Standard Trailer | Y |
Order Cancel Reject <9>
Modulus sends an Order Cancel Reject <9> message when the exchange receives an Order Cancel Request
- Order Cancel Request
message has an unknown OrigClOrdID <41> - the order referred to by OrigClOrdID <41> exists, but cannot be canceled because it is not currently active:
- rejected
- already filled
- already canceled
Tag | Name | Req | Description |
---|---|---|---|
Standard Header | Y | MsgType = 9 | |
11 | ClOrdID | Y | Unique identifier of the order as assigned by the institution. |
37 | OrderID | Y | Unique identifier for the order as assigned by Modulus. Uniqueness is guaranteed for the trading session. The value is `NONE` for unknown orders. |
39 | OrdStatus | Y | Identifies the current status of order. The status is `8 = Rejected` if the order is unknown. Valid values:
|
41 | OrigClOrdID | Y | ClOrdID <11> of the order to cancel. Needs to correspond to a current outstanding order submitted during this trading session. |
60 | TransactTime | Y | Time of order creation (expressed in UTC). |
102 | CxlRejReason | N | Code to identify reason for cancel rejection. Valid values:
|
434 | CxlRejResponseTo | Y | Indicates the type of request that the message is in response to. Valid values: |
Standard Trailer | Y |
Examples
Market Data Requests
These are some examples of FIX market data requests. These requests only need to be made once per session to setup a FIX connection for market data.
Notes:
SubscriptionRequestType <263> = 1 SNAPSHOT_PLUS_UPDATES
allows the sender to subscribe to the data feed and receive updates.
REQUEST FOR TOP OF BOOK (BIDS)
This is a request for the Top of Book BTCUSD bids:
RAW
8=FIXT.1.1|9=114|35=V|34=2|49=TRADEBOTMD002|52=20180425-17:51:40.000|56=Modulus|262=2|263=1|264=1|265=0|146=1|55=BTCUSD|267=1|269=0|10=016|
HEADER
8 BeginString: FIXT.1.1
9 BodyLength: 114
34 MsgSeqNum: 2
35 MsgType: MarketDataRequest (V)
49 SenderCompID: TRADEBOTMD002
52 SendingTime: 20180425-17:51:40.000
56 TargetCompID: Modulus
BODY
262 MDReqID: 2
263 SubscriptionRequestType: SNAPSHOT_PLUS_UPDATES (1)
264 MarketDepth: TOP_OF_BOOK (1)
265 MDUpdateType: FULL_REFRESH (0)
NoRelatedSym: count = 1
55 Symbol: BTCUSD
NoMDEntryTypes: count = 1
269 MDEntryType: BID (0)
TRAILER
10 CheckSum: 016
and the corresponding response:
RAW
8=FIXT.1.1|9=114|35=V|34=2|49=TRADEBOTMD002|52=20180425-17:51:40.000|56=Modulus|262=2|263=1|264=1|265=0|146=1|55=BTCUSD|267=1|269=0|10=016|
HEADER
8 BeginString: FIXT.1.1
9 BodyLength: 114
34 MsgSeqNum: 2
35 MsgType: MarketDataRequest (V)
49 SenderCompID: TRADEBOTMD002
52 SendingTime: 20180425-17:51:40.000
56 TargetCompID: Modulus
BODY
262 MDReqID: 2
263 SubscriptionRequestType: SNAPSHOT_PLUS_UPDATES (1)
264 MarketDepth: TOP_OF_BOOK (1)
265 MDUpdateType: FULL_REFRESH (0)
NoRelatedSym: count = 1
55 Symbol: BTCUSD
NoMDEntryTypes: count = 1
269 MDEntryType: BID (0)
TRAILER
10 CheckSum: 016
Market Data Responses
These are some examples of FIX market data sent from ModulusMKT to TESTMKT001 with price, liquidity, and trade information. Note that this is public data, so no assumption about the trade’s counterparty should be made.
FULL SNAPSHOT
The initial response to a Market Data Request
HEADER
8 BeginString: FIXT.1.1
9 BodyLength: 19924
34 MsgSeqNum: 4
35 MsgType: MarketDataSnapshotFullRefresh (W)
49 SenderCompID: ModulusMKT
52 SendingTime: 20180121-03:48:39.102
56 TargetCompID: TESTMKT001
BODY
55 Symbol: ETHBTC
262 MDReqID: 39
NoMDEntries: count = 685
269 MDEntryType: BID (0)
270 MDEntryPx: 0.00001
271 MDEntrySize: 10111
----
...
----
269 MDEntryType: BID (0)
270 MDEntryPx: 0.08989
271 MDEntrySize: 8.918
----
269 MDEntryType: BID (0)
270 MDEntryPx: 0.0899
271 MDEntrySize: 8.8828
----
269 MDEntryType: OFFER (1)
270 MDEntryPx: 0.09032
271 MDEntrySize: 45.134
----
269 MDEntryType: OFFER (1)
270 MDEntryPx: 0.09049
271 MDEntrySize: 1.2
----
...
----
269 MDEntryType: OFFER (1)
270 MDEntryPx: 1000.00000
271 MDEntrySize: 3
TRAILER
10 CheckSum: 084
ADDING QUANTITY FOR A GIVEN PRICE
This message shows a new bid for 2.8749 ETH priced at 988.88 USD.
HEADER
8 BeginString: FIXT.1.1
9 BodyLength: 125
34 MsgSeqNum: 5696449
35 MsgType: MarketDataIncrementalRefresh (X)
49 SenderCompID: ModulusMKT
52 SendingTime: 20180123-04:07:42.101
56 TargetCompID: TESTMKT001
BODY
262 MDReqID: 40
NoMDEntries: count = 1
55 Symbol: ETHUSD
269 MDEntryType: BID (0)
270 MDEntryPx: 988.88
271 MDEntrySize: 2.8749
279 MDUpdateAction: NEW (0)
TRAILER
10 CheckSum: 187
CHANGING QUANTITY FOR A GIVEN PRICE
This message shows a new offer for 0.20503505 BTC available at price 10949.04 USD.
HEADER
8 BeginString: FIXT.1.1
9 BodyLength: 131
34 MsgSeqNum: 5696384
35 MsgType: MarketDataIncrementalRefresh (X)
49 SenderCompID: ModulusMKT
52 SendingTime: 20180123-04:07:40.057
56 TargetCompID: TESTMKT001
BODY
262 MDReqID: 38
NoMDEntries: count = 1
55 Symbol: BTCUSD
269 MDEntryType: OFFER (1)
270 MDEntryPx: 10949.04
271 MDEntrySize: 0.20503505
279 MDUpdateAction: CHANGE (1)
TRAILER
10 CheckSum: 199
REMOVING QUANTITY FOR A GIVEN PRICE
This message shows an ETHBTC bid priced at 0.09156 BTC being removed.
HEADER
8 BeginString: FIXT.1.1
9 BodyLength: 115
34 MsgSeqNum: 5696454
35 MsgType: MarketDataIncrementalRefresh (X)
49 SenderCompID: ModulusMKT
52 SendingTime: 20180123-04:07:42.279
56 TargetCompID: TESTMKT001
BODY
262 MDReqID: 39
NoMDEntries: count = 1
55 Symbol: ETHBTC
269 MDEntryType: BID (0)
270 MDEntryPx: 0.09156
279 MDUpdateAction: DELETE (2)
TRAILER
10 CheckSum: 197
TRADES
This message provides information about a new trade and a corresponding offer deletion. This message implies that the incoming order was a bid because the standing offer priced at 10907.54 USD was deleted.
HEADER
8 BeginString: FIXT.1.1
9 BodyLength: 166
34 MsgSeqNum: 5696411
35 MsgType: MarketDataIncrementalRefresh (X)
49 SenderCompID: ModulusMKT
52 SendingTime: 20180123-04:07:40.740
56 TargetCompID: TESTMKT001
BODY
262 MDReqID: 38
NoMDEntries: count = 2
55 Symbol: BTCUSD
269 MDEntryType: TRADE (2)
270 MDEntryPx: 10907.54
271 MDEntrySize: 0.00059578
279 MDUpdateAction: NEW (0)
----
55 Symbol: BTCUSD
269 MDEntryType: OFFER (1)
270 MDEntryPx: 10907.54
279 MDUpdateAction: DELETE (2)
TRAILER
10 CheckSum: 209
SHOWING MAKER SIDE FOR TRADES
To enable showing the maker side of trades, create a Market Data Request
This example shows a trade where an incoming offer hit a standing bid at for 0.001 BTC at 7544.94 USD.
RAW
8=FIXT.1.1|9=125|35=X|34=3|49=Modulus|52=20180809-15:59:16.698|56=TRADEBOTMD002|262=2|268=1|279=0|269=2|55=BTCUSD|270=7544.94|271=0.001|9002=1|10=107|
HEADER
8 BeginString: FIXT.1.1
9 BodyLength: 125
34 MsgSeqNum: 3
35 MsgType: MarketDataIncrementalRefresh (X)
49 SenderCompID: Modulus
52 SendingTime: 20180809-15:59:16.698
56 TargetCompID: TRADEBOTMD002
BODY
262 MDReqID: 2
NoMDEntries: count = 1
55 Symbol: BTCUSD
269 MDEntryType: TRADE (2)
270 MDEntryPx: 7544.94
271 MDEntrySize: 0.001
279 MDUpdateAction: NEW (0)
9002 MDEntryMakerSide: BUY (1)
TRAILER
10 CheckSum: 107
This example shows a trade where an incoming bid lifted a standing offer at for 0.001 BTC at 7549.89 USD.
RAW
8=FIXT.1.1|9=125|35=X|34=3|49=Modulus|52=20180809-15:59:22.882|56=TRADEBOTMD002|262=2|268=1|279=0|269=2|55=BTCUSD|270=7549.89|271=0.001|9002=2|10=109|
HEADER
8 BeginString: FIXT.1.1
9 BodyLength: 125
34 MsgSeqNum: 3
35 MsgType: MarketDataIncrementalRefresh (X)
49 SenderCompID: Modulus
52 SendingTime: 20180809-15:59:22.882
56 TargetCompID: TRADEBOTMD002
BODY
262 MDReqID: 2
NoMDEntries: count = 1
55 Symbol: BTCUSD
269 MDEntryType: TRADE (2)
270 MDEntryPx: 7549.89
271 MDEntrySize: 0.001
279 MDUpdateAction: NEW (0)
9002 MDEntryMakerSide: SELL (2)
TRAILER
10 CheckSum: 109
REJECTED SYMBOL
RAW
8=FIXT.1.1|9=67|35=Y|34=2|49=ModulusMKT|52=20180511-21:37:57.971|56=TESTMKT001|262=badsym|281=0|10=038|
HEADER
8 BeginString: FIXT.1.1
9 BodyLength: 67
34 MsgSeqNum: 2
35 MsgType: MarketDataRequestReject (Y)
49 SenderCompID: ModulusMKT
52 SendingTime: 20180511-21:37:57.971
56 TargetCompID: TESTMKT001
BODY
262 MDReqID: badsym
281 MDReqRejReason: UNKNOWN_SYMBOL (0)
TRAILER
10 CheckSum: 03
REJECTED MD ENTRY TYPE
RAW
8=FIXT.1.1|9=70|35=Y|34=2|49=ModulusMKT|52=20180511-21:44:14.765|56=TESTMKT001|262=badmd|281=8|10=121|
HEADER
8 BeginString: FIXT.1.1
9 BodyLength: 70
34 MsgSeqNum: 2
35 MsgType: MarketDataRequestReject (Y)
49 SenderCompID: ModulusMKT
52 SendingTime: 20180511-21:44:14.765
56 TargetCompID: TESTMKT001
BODY
262 MDReqID: badmd
281 MDReqRejReason: UNSUPPORTED_MDENTRYTYPE (8)
TRAILER
10 CheckSum: 121
REJECTED SUBSCRIPTION REQUEST
RAW
8=FIXT.1.1|9=67|35=Y|34=2|49=ModulusMKT|52=20180514-13:59:56.187|56=TESTMKT001|262=badsub|281=4|10=048|
HEADER
8 BeginString: FIXT.1.1
9 BodyLength: 67
34 MsgSeqNum: 2
35 MsgType: MarketDataRequestReject (Y)
49 SenderCompID: ModulusMKT
52 SendingTime: 20180514-13:59:56.187
56 TargetCompID: TESTMKT001
BODY
262 MDReqID: badsub
281 MDReqRejReason: UNSUPPORTED_SUBSCRIPTIONREQUESTTYPE (4)
TRAILER
10 CheckSum: 048
New Order Single
This is a New Order Single (D in MsgType <35>) request:
RAW
8=FIXT.1.1|9=144|35=D|34=2|49=TRADEBOTOE002|52=20180425-17:56:41.000|56=Modulus|11=iWM60sx3dreT9N9yEE|38=1|40=2|44=10000|54=1|55=BTCUSD|59=1|60=20180425-17:56:41|10=073|
HEADER
8 BeginString: FIXT.1.1
9 BodyLength: 144
34 MsgSeqNum: 2
35 MsgType: NewOrderSingle (D)
49 SenderCompID: TRADEBOTOE002
52 SendingTime: 20180425-17:56:41.000
56 TargetCompID: Modulus
BODY
11 ClOrdID: iWM60sx3dreT9N9yEE
38 OrderQty: 1
40 OrdType: LIMIT (2)
44 Price: 10000
54 Side: BUY (1)
55 Symbol: BTCUSD
59 TimeInForce: GOOD_TILL_CANCEL (1)
60 TransactTime: 20180425-17:56:41
TRAILER
10 CheckSum: 073
Execution Reports
The following section contains examples of execution reports.
Notes:
- Explanatory notes about the execution report fields are provided after each example. Additional information about the fields can be found in the Execution Report <8> documentation.
- Modulus associates the following OrdStatus <39> outcomes with each supported ExecType <150>:
ExecType <150> | OrdStatus <39> |
---|---|
0 = New |
|
F = Trade |
|
4 = Canceled |
|
8 = Rejected |
|
EXECUTION REPORT FOR A NEW ORDER
This is an example of an Execution Report <8> in response to TRADEBOTOE002's New Order Single
RAW
8=FIXT.1.1|9=195|35=8|34=2|49=Modulus|52=20180425-17:56:42.071|56=TRADEBOTOE002|6=0|11=iWM60sx3dreT9N9yEE|14=0|17=335278099|37=335278098|38=1|39=0|44=10000|54=1|55=BTCUSD|59=1|60=20180425-17:56:42.071|150=0|151=1|10=163|
HEADER
8 BeginString: FIXT.1.1
9 BodyLength: 195
34 MsgSeqNum: 2
35 MsgType: ExecutionReport (8)
49 SenderCompID: Modulus
52 SendingTime: 20180425-17:56:42.071
56 TargetCompID: TRADEBOTOE002
BODY
6 AvgPx: 0
11 ClOrdID: iWM60sx3dreT9N9yEE
14 CumQty: 0
17 ExecID: 335278099
37 OrderID: 335278098
38 OrderQty: 1
39 OrdStatus: NEW (0)
44 Price: 10000
54 Side: BUY (1)
55 Symbol: BTCUSD
59 TimeInForce: GOOD_TILL_CANCEL (1)
60 TransactTime: 20180425-17:56:42.071
150 ExecType: NEW (0)
151 LeavesQty: 1
TRAILER
10 CheckSum: 163
EXECUTION REPORT FOR A FILL
In this scenario, TRADEBOTOE002
's order fills at 8400.00. In this case, TRADEBOTOE002
is on the taker side and pays the base fee of 100bps (1.00%). This is an example of an associated execution report:
RAW
8=FIXT.1.1|9=248|35=8|34=3|49=Modulus|52=20180516-22:03:10.031|56=TRADEBOTOE002|6=8400.00|11=af9hLHqlLYAYb3ErKJ|12=8.400000|13=3|14=1|17=336157291|31=8400.00|32=1|37=336157289|38=1|39=2|44=10000|54=1|55=BTCUSD|59=1|60=20180516-22:03:10.030|150=F|151=0|479=USD|851=2|10=116|
HEADER
8 BeginString: FIXT.1.1
9 BodyLength: 248
34 MsgSeqNum: 3
35 MsgType: ExecutionReport (8)
49 SenderCompID: Modulus
52 SendingTime: 20180516-22:03:10.031
56 TargetCompID: TRADEBOTOE002
BODY
6 AvgPx: 8400.00
11 ClOrdID: af9hLHqlLYAYb3ErKJ
12 Commission: 8.400000
13 CommType: ABSOLUTE (3)
14 CumQty: 1
17 ExecID: 336157291
31 LastPx: 8400.00
32 LastQty: 1
37 OrderID: 336157289
38 OrderQty: 1
39 OrdStatus: FILLED (2)
44 Price: 10000
54 Side: BUY (1)
55 Symbol: BTCUSD
59 TimeInForce: GOOD_TILL_CANCEL (1)
60 TransactTime: 20180516-22:03:10.030
150 ExecType: TRADE (F)
151 LeavesQty: 0
479 CommCurrency: USD
851 LastLiquidityInd: REMOVED_LIQUIDITY (2)
TRAILER
10 CheckSum: 116
EXECUTION REPORT FOR A PARTIAL FILL
In this example, TRADEBOTOE002
is on the maker side and receives an execution report for an order with an original quantity of 20 BTC that was partially filled for 10 BTC with 10 BTC remaining for a fee of 0.00%:
RAW
8=FIXT.1.1|9=254|35=8|34=5|49=Modulus|52=20180517-15:07:16.894|56=TRADEBOTOE002|6=8338.67|11=1tfX3IJi9HP87dkqlo|12=0.000000|13=3|14=10|17=336933409|31=8338.67|32=10|37=336933405|38=20|39=1|44=8338.67|54=1|55=BTCUSD|59=3|60=20180517-15:07:16.892|150=F|151=10|479=USD|851=1|10=001|
HEADER
8 BeginString: FIXT.1.1
9 BodyLength: 254
34 MsgSeqNum: 5
35 MsgType: ExecutionReport (8)
49 SenderCompID: Modulus
52 SendingTime: 20180517-15:07:16.894
56 TargetCompID: TRADEBOTOE002
BODY
6 AvgPx: 8338.67
11 ClOrdID: 1tfX3IJi9HP87dkqlo
12 Commission: 0.000000
13 CommType: ABSOLUTE (3)
14 CumQty: 10
17 ExecID: 336933409
31 LastPx: 8338.67
32 LastQty: 10
37 OrderID: 336933405
38 OrderQty: 20
39 OrdStatus: PARTIALLY_FILLED (1)
44 Price: 8338.67
54 Side: BUY (1)
55 Symbol: BTCUSD
59 TimeInForce: IMMEDIATE_OR_CANCEL (3)
60 TransactTime: 20180517-15:07:16.892
150 ExecType: TRADE (F)
151 LeavesQty: 10
479 CommCurrency: USD
851 LastLiquidityInd: ADDED_LIQUIDITY (1)
TRAILER
10 CheckSum: 001
EXECUTION REPORT FOR AN ORDER CANCELLATION
In this example, TRADEBOTOE002
receives an execution report, in response to a previously sent Order Cancel Request GHDzdNUUXaMMDZdfwe
was cancelled:
RAW
8=FIXT.1.1|9=220|35=8|34=3|49=Modulus|52=20180425-17:57:59.538|56=TRADEBOTOE002|6=0|11=GHDzdNUUXaMMDZdfwe|14=0|17=335278132|37=335278128|38=1|39=4|41=z35u64KR1gen7f2SpB|44=93392.64|54=2|55=BTCUSD|58=REQUESTED|59=1|60=20180425-17:57:59.537|150=4|151=0|10=254|
HEADER
8 BeginString: FIXT.1.1
9 BodyLength: 220
34 MsgSeqNum: 3
35 MsgType: ExecutionReport (8)
49 SenderCompID: Modulus
52 SendingTime: 20180425-17:57:59.538
56 TargetCompID: TRADEBOTOE002
BODY
6 AvgPx: 0
11 ClOrdID: GHDzdNUUXaMMDZdfwe
14 CumQty: 0
17 ExecID: 335278132
37 OrderID: 335278128
38 OrderQty: 1
39 OrdStatus: CANCELED (4)
41 OrigClOrdID: z35u64KR1gen7f2SpB
44 Price: 93392.64
54 Side: SELL (2)
55 Symbol: BTCUSD
58 Text: REQUESTED
59 TimeInForce: GOOD_TILL_CANCEL (1)
60 TransactTime: 20180425-17:57:59.537
150 ExecType: CANCELED (4)
151 LeavesQty: 0
TRAILER
10 CheckSum: 254
In this next example, TRADEBOTOE002
first sent an Order Cancel Request 1tfX3IJi9HP87dkqlo
that was previously partially filled. This is an execution report for the cancellation of the remaining quantity:
RAW
8=FIXT.1.1|9=238|35=8|34=7|49=Modulus|52=20180517-15:07:16.896|56=TRADEBOTOE002|6=8338.67|11=1tfX3IJi9HP87dkqlo|14=10|17=336933412|37=336933405|38=20|39=4|44=8338.67|54=1|55=BTCUSD|58=BLOCK_TRADE_UNFILLED_QUANTITY|59=3|60=20180517-15:07:16.892|150=4|151=0|10=080|
HEADER
8 BeginString: FIXT.1.1
9 BodyLength: 238
34 MsgSeqNum: 7
35 MsgType: ExecutionReport (8)
49 SenderCompID: Modulus
52 SendingTime: 20180517-15:07:16.896
56 TargetCompID: TRADEBOTOE002
BODY
6 AvgPx: 8338.67
11 ClOrdID: 1tfX3IJi9HP87dkqlo
14 CumQty: 10
17 ExecID: 336933412
37 OrderID: 336933405
38 OrderQty: 20
39 OrdStatus: CANCELED (4)
44 Price: 8338.67
54 Side: BUY (1)
55 Symbol: BTCUSD
58 Text: BLOCK_TRADE_UNFILLED_QUANTITY
59 TimeInForce: IMMEDIATE_OR_CANCEL (3)
60 TransactTime: 20180517-15:07:16.892
150 ExecType: CANCELED (4)
151 LeavesQty: 0
TRAILER
10 CheckSum: 080
EXECUTION REPORT FOR A REJECT
In this scenario, TRADEBOTOE002 sent another New Order Single
Because the symbol is invalid, the server rejects the order. This is an example of an associated execution report:
RAW
8=FIXT.1.1|9=237|35=8|34=2|49=Modulus|52=20180516-22:09:05.019|56=TRADEBOTOE002|6=0|11=7v1cs7HFCT2WehadcO|14=0|17=1526508545018|37=0|38=10.4|39=8|44=0.05|54=2|55=ABCDEF|58=Unsupported Symbol value 'ABCDEF'|59=1|60=20180516-22:09:05.018|103=99|150=8|151=0|10=090|
HEADER
8 BeginString: FIXT.1.1
9 BodyLength: 237
34 MsgSeqNum: 2
35 MsgType: ExecutionReport (8)
49 SenderCompID: Modulus
52 SendingTime: 20180516-22:09:05.019
56 TargetCompID: TRADEBOTOE002
BODY
6 AvgPx: 0
11 ClOrdID: 7v1cs7HFCT2WehadcO
14 CumQty: 0
17 ExecID: 1526508545018
37 OrderID: 0
38 OrderQty: 10.4
39 OrdStatus: REJECTED (8)
44 Price: 0.05
54 Side: SELL (2)
55 Symbol: ABCDEF
58 Text: Unsupported Symbol value 'ABCDEF'
59 TimeInForce: GOOD_TILL_CANCEL (1)
60 TransactTime: 20180516-22:09:05.018
103 OrdRejReason: OTHER (99)
150 ExecType: REJECTED (8)
151 LeavesQty: 0
TRAILER
10 CheckSum: 090
Order Cancel Request
This is an Order Cancel Request that cancels an order of 1 BTC that was previously entered with an CLOrdID of z35u64KR1gen7f2SpB
:
RAW
8=FIXT.1.1|9=147|35=F|34=3|49=TRADEBOTOE002|52=20180425-17:57:59.000|56=Modulus|11=GHDzdNUUXaMMDZdfwe|38=1|41=z35u64KR1gen7f2SpB|54=2|55=BTCUSD|60=20180425-17:57:59|10=185|
HEADER
8 BeginString: FIXT.1.1
9 BodyLength: 147
34 MsgSeqNum: 3
35 MsgType: OrderCancelRequest (F)
49 SenderCompID: TRADEBOTOE002
52 SendingTime: 20180425-17:57:59.000
56 TargetCompID: Modulus
BODY
11 ClOrdID: GHDzdNUUXaMMDZdfwe
38 OrderQty: 1
41 OrigClOrdID: z35u64KR1gen7f2SpB
54 Side: SELL (2)
55 Symbol: BTCUSD
60 TransactTime: 20180425-17:57:59
TRAILER
10 CheckSum: 185
and its associated Execution Report response:
RAW
8=FIXT.1.1|9=220|35=8|34=3|49=Modulus|52=20180425-17:57:59.538|56=TRADEBOTOE002|6=0|11=GHDzdNUUXaMMDZdfwe|14=0|17=335278132|37=335278128|38=1|39=4|41=z35u64KR1gen7f2SpB|44=93392.64|54=2|55=BTCUSD|58=REQUESTED|59=1|60=20180425-17:57:59.537|150=4|151=0|10=254|
HEADER
8 BeginString: FIXT.1.1
9 BodyLength: 220
34 MsgSeqNum: 3
35 MsgType: ExecutionReport (8)
49 SenderCompID: Modulus
52 SendingTime: 20180425-17:57:59.538
56 TargetCompID: TRADEBOTOE002
BODY
6 AvgPx: 0
11 ClOrdID: GHDzdNUUXaMMDZdfwe
14 CumQty: 0
17 ExecID: 335278132
37 OrderID: 335278128
38 OrderQty: 1
39 OrdStatus: CANCELED (4)
41 OrigClOrdID: z35u64KR1gen7f2SpB
44 Price: 93392.64
54 Side: SELL (2)
55 Symbol: BTCUSD
58 Text: REQUESTED
59 TimeInForce: GOOD_TILL_CANCEL (1)
60 TransactTime: 20180425-17:57:59.537
150 ExecType: CANCELED (4)
151 LeavesQty: 0
TRAILER
10 CheckSum: 254
New Market BUY Order
This is an example of a request for a market BUY order.
RAW
8=FIXT.1.1|9=126|35=D|34=2|49=DEV|52=20181023-17:49:51.691|56=Modulus|11=FLWC3iFi6ygIxFSKVY|40=1|54=1|55=BTCUSD|60=20150218-18:45:02.003|152=500.0|10=235|
HEADER
8 BeginString: FIXT.1.1
9 BodyLength: 126
34 MsgSeqNum: 2
35 MsgType: NewOrderSingle (D)
49 SenderCompID: DEV
52 SendingTime: 20181023-17:49:51.691
56 TargetCompID: Modulus
BODY
11 ClOrdID: FLWC3iFi6ygIxFSKVY
40 OrdType: MARKET (1)
54 Side: BUY (1)
55 Symbol: BTCUSD
60 TransactTime: 20150218-18:45:02.003
152 CashOrderQty: 500.0
TRAILER
10 CheckSum: 235
and the associated Execution Report for a market BUY order.
RAW
8=FIXT.1.1|9=163|35=8|34=2|49=Modulus|52=20181023-17:49:51.943|56=DEV|6=0|11=FLWC3iFi6ygIxFSKVY|14=0|17=43|37=42|39=0|54=1|55=BTCUSD|60=20150218-18:45:02.042|150=0|151=500.0|152=500.0|10=069|
HEADER
8 BeginString: FIXT.1.1
9 BodyLength: 163
34 MsgSeqNum: 2
35 MsgType: ExecutionReport (8)
49 SenderCompID: Modulus
52 SendingTime: 20181023-17:49:51.943
56 TargetCompID: DEV
BODY
6 AvgPx: 0
11 ClOrdID: FLWC3iFi6ygIxFSKVY
14 CumQty: 0
17 ExecID: 43
37 OrderID: 42
39 OrdStatus: NEW (0)
54 Side: BUY (1)
55 Symbol: BTCUSD
60 TransactTime: 20150218-18:45:02.042
150 ExecType: NEW (0)
151 LeavesQty: 500.0
152 CashOrderQty: 500.0
TRAILER
10 CheckSum: 069
New Market SELL Order
This is an example of a request for a market SELL order.
RAW
8=FIXT.1.1|9=126|35=D|34=2|49=DEV|52=20181023-17:49:51.691|56=Modulus|11=YLWC3xFi6ygIxFSKVY|40=1|54=1|55=BTCUSD|60=20150218-18:45:02.003|152=500.0|10=112|
HEADER
8 BeginString: FIXT.1.1
9 BodyLength: 126
34 MsgSeqNum: 2
35 MsgType: NewOrderSingle (D)
49 SenderCompID: DEV
52 SendingTime: 20181023-17:49:51.691
56 TargetCompID: Modulus
BODY
11 ClOrdID: YLWC3xFi6ygIxFSKVY
38 OrderQty: 2.0
40 OrdType: MARKET (1)
54 Side: SELL (2)
55 Symbol: BTCUSD
60 TransactTime: 20150218-18:45:02.010
TRAILER
10 CheckSum: 112
and the associated Execution Report for a market SELL order.
RAW
8=FIXT.1.1|9=161|35=8|34=2|49=Modulus|52=20181023-20:26:27.359|56=DEV|6=0|11=YLWC3xFi6ygIxFSKVY|14=0|17=43|37=42|38=2.0|39=0|54=2|55=BTCUSD|60=20150218-18:45:02.042|150=0|151=2.0|10=113|
HEADER
8 BeginString: FIXT.1.1
9 BodyLength: 161
34 MsgSeqNum: 2
35 MsgType: ExecutionReport (8)
49 SenderCompID: Modulus
52 SendingTime: 20181023-20:26:27.359
56 TargetCompID: DEV
BODY
6 AvgPx: 0
11 ClOrdID: YLWC3xFi6ygIxFSKVY
14 CumQty: 0
17 ExecID: 43
37 OrderID: 42
38 OrderQty: 2.0
39 OrdStatus: NEW (0)
54 Side: SELL (2)
55 Symbol: BTCUSD
60 TransactTime: 20150218-18:45:02.042
150 ExecType: NEW (0)
151 LeavesQty: 2.0
TRAILER
10 CheckSum: 113
Market Order Fill
This is an example of an Execution Report for a filled market BUY order
RAW
8=FIXT.1.1|9=297|35=8|34=3|49=Modulus|52=20181023-17:49:51.958|56=DEV|6=448.06|11=FLWC3iFi6ygIxFSKVY|12=9.80392156863|13=3|14=1.0940411517|17=44|31=448.06|32=1.0940411517|37=42|39=2|54=1|55=BTCUSD|60=20150218-18:45:02.043|150=F|151=0|152=500.0|479=USD|851=2|10=089|
HEADER
8 BeginString: FIXT.1.1
9 BodyLength: 297
34 MsgSeqNum: 3
35 MsgType: ExecutionReport (8)
49 SenderCompID: Modulus
52 SendingTime: 20181023-17:49:51.958
56 TargetCompID: DEV
BODY
6 AvgPx: 448.06
11 ClOrdID: FLWC3iFi6ygIxFSKVY
12 Commission: 9.8039215686
13 CommType: ABSOLUTE (3)
14 CumQty: 1.0940411517
17 ExecID: 44
31 LastPx: 448.06
32 LastQty: 1.0940411517
37 OrderID: 42
39 OrdStatus: FILLED (2)
54 Side: BUY (1)
55 Symbol: BTCUSD
60 TransactTime: 20150218-18:45:02.043
150 ExecType: TRADE (F)
151 LeavesQty: 0
152 CashOrderQty: 500.0
479 CommCurrency: USD
851 LastLiquidityInd: REMOVED_LIQUIDITY (2)
TRAILER
10 CheckSum: 089
Market Order Partial Fill
In the rare case a market order sweeps the book and only partially fills, two Execution Reports will be generated: one describing the partial fill and another cancelling the market order as it was only partially filled.
Here is an example of the partial fill Execution Report.
RAW
8=FIXT.1.1|9=237|35=8|34=3|49=Modulus|52=20181023-18:05:07.978|56=DEV|6=448.06|11=CLWC3iFi6ygIyFSKVY|12=8.9612|13=3|14=1.0|17=44|31=448.06|32=1.0|37=42|39=1|54=1|55=BTCUSD|60=20150218-18:45:02.043|150=F|151=42.9788|152=500.0|479=USD|851=2|10=172|
HEADER
8 BeginString: FIXT.1.1
9 BodyLength: 237
34 MsgSeqNum: 3
35 MsgType: ExecutionReport (8)
49 SenderCompID: Modulus
52 SendingTime: 20181023-18:05:07.978
56 TargetCompID: DEV
BODY
6 AvgPx: 448.06
11 ClOrdID: CLWC3iFi6ygIyFSKVY
12 Commission: 8.9612
13 CommType: ABSOLUTE (3)
14 CumQty: 1.0
17 ExecID: 44
31 LastPx: 448.06
32 LastQty: 1.0
37 OrderID: 42
39 OrdStatus: PARTIALLY_FILLED (1)
54 Side: BUY (1)
55 Symbol: BTCUSD
60 TransactTime: 20150218-18:45:02.043
150 ExecType: TRADE (F)
151 LeavesQty: 42.9788
152 CashOrderQty: 500.0
479 CommCurrency: USD
851 LastLiquidityInd: REMOVED_LIQUIDITY (2)
TRAILER
10 CheckSum: 172
and the following Execution Report representing a cancellation of the order.
RAW
8=FIXT.1.1|9=199|35=8|34=4|49=Modulus|52=20181023-18:05:07.984|56=DEV|6=448.06|11=CLWC3iFi6ygIyFSKVY|14=1.0|17=46|37=42|39=4|54=1|55=BTCUSD|58=MARKET_ORDER_SWEPT_BOOK|60=20150218-18:45:02.045|150=4|151=0|152=500.0|10=TRAILER|
HEADER
8 BeginString: FIXT.1.1
9 BodyLength: 199
34 MsgSeqNum: 4
35 MsgType: ExecutionReport (8)
49 SenderCompID: Modulus
52 SendingTime: 20181023-18:05:07.984
56 TargetCompID: DEV
BODY
6 AvgPx: 448.06
11 ClOrdID: CLWC3iFi6ygIyFSKVY
14 CumQty: 1.0
17 ExecID: 46
37 OrderID: 42
39 OrdStatus: CANCELED (4)
54 Side: BUY (1)
55 Symbol: BTCUSD
58 Text: MARKET_ORDER_SWEPT_BOOK
60 TransactTime: 20150218-18:45:02.045
150 ExecType: CANCELED (4)
151 LeavesQty: 0
152 CashOrderQty: 500.0
TRAILER
10 CheckSum: 184