# Market Data

The Market Data session provides real-time order book streaming via the FIX 4.4 protocol. Use this session to subscribe to price updates for specific trading instruments and receive continuous market data.

{% hint style="warning" %}
For FIX connection settings (host, port, SenderCompID, TargetCompID, credentials), contact your broker.
{% endhint %}

{% hint style="info" %}
This page covers the **Market Data** session only. For trading operations (order placement, execution reports), use the [Trading](https://api-docs.b2trader.b2broker.com/fix-api/trading) session.
{% endhint %}

{% file src="<https://506308843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWqnNf2YTrJmFWsk6j8yo%2Fuploads%2Fgit-blob-be8761bf7689579219523ad1da211923485647e7%2FBbpFIX44.xml?alt=media>" %}
FIX 4.4 Data Dictionary
{% endfile %}

## Supported message types

The following values can be assigned to the `<35>` MsgType field:

* `A` — Logon (Client → B2TRADER)
* `0` — Heartbeat (Client ↔ B2TRADER)
* `1` — Test Request (Client ↔ B2TRADER)
* `3` — Reject (Client ← B2TRADER)
* `4` — Sequence Reset (Client ↔ B2TRADER)
* `5` — Logout (Client ↔ B2TRADER)
* `V` — Market Data Request (Client → B2TRADER)
* `W` — Market Data — Snapshot/Full Refresh (Client ← B2TRADER)
* `X` — Market Data — Incremental Refresh (Client ← B2TRADER)
* `Y` — Market Data Request Reject (Client ← B2TRADER)
* `j` — Business Reject (Client ← B2TRADER)

## Getting started

### Connection

To connect to the Market Data session, use the following parameters provided by B2TRADER:

* **Host and port**: The Market Data endpoint (provided separately from the Trading endpoint)
* **SenderCompID**: Your client identifier for the Market Data session
* **TargetCompID**: The server identifier for the Market Data session
* **Protocol**: FIX 4.4

{% hint style="warning" %}
The Market Data connection does not require SSL.
{% endhint %}

### Message structure

{% hint style="info" %}
**Standard Header**

All FIX messages must begin with a Standard Header containing the following fields:

**`8 BeginString`** `String`

Identifies the FIX version (`FIX.4.4`). Always the first field in a message.

**`9 BodyLength`** `int`

The automatically computed message length, in bytes. Always the second field.

**`35 MsgType`** `String`

The message type. See [Supported message types](#supported-message-types) for possible values. Always the third field.

**`34 MsgSeqNum`** `int`

The message sequence number, incremented by 1 for each consecutive message.

**`49 SenderCompID`** `String`

The identifier of the message sender. Provided by B2TRADER.

**`52 SendingTime`** `Timestamp`

The date and time when the message was sent, in UTC: `YYYYMMDD-HH:MM:SS.sss`.

**`56 TargetCompID`** `String`

The identifier of the message recipient. Provided by B2TRADER.

***

**Standard Trailer**

All FIX messages must end with a Standard Trailer:

**`10 CheckSum`** `int`

A three-digit checksum. Always the last field in a message.
{% endhint %}

### Logon (A)

This message is sent by the client to initiate a FIX session. It must be the first message in each connection.

{% columns %}
{% column width="60%" %}
**`1 Account`** `String`

The account identifier. Required. Provided by B2TRADER.

**`98 EncryptMethod`** `int`

The encryption method. Required. Must be `0` (no encryption).

**`108 HeartBtInt`** `int`

The heartbeat interval, in seconds. Required. Indicates how often the server sends Heartbeat messages as part of a connection health check.

**`141 ResetSeqNumFlag`** `Boolean`

Indicates whether both parties should reset the currently used sequence numbers. Optional.

**`553 Username`** `String`

The client username. Required. Provided by B2TRADER.

**`554 Password`** `String`

The client password. Required. Provided by B2TRADER.
{% endcolumn %}

{% column width="40%" %}
{% code title="Request (Client → B2TRADER)" overflow="wrap" %}

```
8=FIX.4.4^9=138^35=A^1=68a4446ac84827ff5cd35c74^34=1^52=20231218-07:59:06.000^49=sender_b2trader^56=target_b2trader^554=password^553=username^98=0^108=30^10=139^
```

{% endcode %}

{% code title="Response (B2TRADER → Client)" overflow="wrap" %}

```
8=FIX.4.4^9=112^35=A^1=68a4446ac84827ff5cd35c74^34=1^49=target_b2trader^52=20231218-07:59:06.655^56=sender_b2trader^98=0^108=30^10=009^
```

{% endcode %}
{% endcolumn %}
{% endcolumns %}

### Session maintenance

#### Heartbeat (0)

This message is sent back and forth between the server and the client to check the connection status and in response to Test Request messages.

{% columns %}
{% column width="60%" %}
**`112 TestReqID`** `String`

The identifier of a Test Request in response to which this Heartbeat is sent. Required when the Heartbeat is a response to a Test Request.
{% endcolumn %}

{% column width="40%" %}
{% code title="Example" overflow="wrap" %}

```
8=FIX.4.4^9=73^35=0^34=2^52=20231218-07:59:36.000^49=sender_b2trader^56=target_b2trader^10=202^
```

{% endcode %}
{% endcolumn %}
{% endcolumns %}

#### Test Request (1)

This message is sent back and forth between the server and the client as a means of connectivity check. If a Heartbeat is not received within the expected interval, a Test Request is sent; the recipient must respond with a Heartbeat containing the same `<112>` TestReqID.

{% columns %}
{% column width="60%" %}
**`112 TestReqID`** `String`

The identifier of a Test Request. Optional.
{% endcolumn %}

{% column width="40%" %}
{% code title="Example" overflow="wrap" %}

```
8=FIX.4.4^9=81^35=1^34=137^52=20231218-10:12:38.000^49=sender_b2trader^56=target_b2trader^112=2^10=040^
```

{% endcode %}
{% endcolumn %}
{% endcolumns %}

#### Sequence Reset (4)

This message indicates the sequence number of the next message from the sender, immediately following the Sequence Reset. This may be necessary to recover from a disconnect when some messages were lost or their resending is not desirable.

{% columns %}
{% column width="60%" %}
**`123 GapFillFlag`** `Boolean`

Indicates that this message replaces missing messages that won't be resent. Optional.

Possible values:

* `Y` — Gap fill: `<34>` MsgSeqNum is valid and indicates the beginning of the gap fill range
* `N` — Sequence reset: `<34>` MsgSeqNum is ignored. Should only be used in disaster recovery situations

**`36 NewSeqNo`** `int`

The new sequence number. Required.
{% endcolumn %}

{% column width="40%" %}
{% code title="Example" overflow="wrap" %}

```
8=FIX.4.4^9=84^35=4^34=6^49=target_b2trader^52=20231219-21:11:38.578^56=sender_b2trader^123=Y^36=8^10=231^
```

{% endcode %}
{% endcolumn %}
{% endcolumns %}

#### Logout (5)

This message is sent by the client or server to terminate a session. When terminated, the possible reason is specified in the `<58>` Text field.

{% columns %}
{% column width="60%" %}
**`58 Text`** `String`

The detailed information about the reason for logging out. Optional.
{% endcolumn %}

{% column width="40%" %}
{% code title="Request (Client → B2TRADER)" overflow="wrap" %}

```
8=FIX.4.4^9=83^35=5^34=5^52=20231218-13:40:48.000^49=sender_b2trader^56=target_b2trader^58=ST1234^10=229^
```

{% endcode %}

{% code title="Response (B2TRADER → Client)" overflow="wrap" %}

```
8=FIX.4.4^9=75^35=5^34=748^49=target_b2trader^52=20231218-13:40:49.016^56=sender_b2trader^10=064^
```

{% endcode %}
{% endcolumn %}
{% endcolumns %}

### Reject (3)

This message is sent by the server upon receiving a malformed message from the client. The rejection reason is specified in the `<373>` SessionRejectReason field.

{% hint style="warning" %}
This message is unrelated to application-level rejections (Market Data Request Reject and Business Reject).
{% endhint %}

{% columns %}
{% column width="60%" %}
**`45 RefSeqNum`** `int`

The sequence number of the rejected message (`<34>` MsgSeqNum). Required.

**`371 RefTagID`** `int`

The tag number of the field that caused message rejection. Optional.

**`372 RefMsgType`** `String`

The type of the rejected message (`<35>` MsgType). Optional.

**`373 SessionRejectReason`** `int`

The reason why the message is rejected. Optional.

Possible values:

* `0` — Invalid tag number
* `1` — Required tag missing
* `2` — Tag not defined for this message type
* `3` — Undefined tag
* `4` — Tag has no value assigned
* `5` — Value is incorrect (out of range) for this tag
* `6` — Incorrect value data format
* `7` — Decryption issue
* `8` — Signature problem
* `9` — CompID issue
* `10` — SendingTime accuracy issue
* `11` — Invalid MsgType
* `12` — XML validation error
* `13` — Same tag appears more than once
* `14` — Tag specified not in required order
* `15` — Wrong order of repeating group fields
* `16` — Incorrect NumInGroup count for repeating group
* `17` — Non-"Data" value includes field delimiter (SOH character)
* `99` — Other

**`58 Text`** `String`

The detailed information about the rejection reason. Optional.
{% endcolumn %}

{% column width="40%" %}
{% code title="Example (B2TRADER → Client)" overflow="wrap" %}

```
8=FIX.4.4^9=125^35=3^34=193^52=20231219-22:41:16.000^49=target_b2trader^56=sender_b2trader^45=18^371=262^372=V^373=1^58=Required tag missing^10=122^
```

{% endcode %}
{% endcolumn %}
{% endcolumns %}

***

## Market Data Request (V)

This message is sent by the client to subscribe to real-time quoting data for a specified ticker symbol.

After subscribing, the server sends an initial Market Data — Snapshot/Full Refresh, followed by continuous Market Data — Incremental Refresh messages with each market data update.

To subscribe to multiple symbols, send a separate Market Data Request for each symbol. To unsubscribe, send a Market Data Request with `<263>` SubscriptionRequestType set to `2`. All subscriptions are also terminated when the session is closed via Logout.

{% columns %}
{% column width="60%" %}
**`262 MDReqID`** `String`

The identifier of the Market Data Request. Required. Must be unique for the duration of each session. When unsubscribing, specify the ID of a previous request to discard.

**`263 SubscriptionRequestType`** `int`

The type of response expected from the server. Required.

Possible values:

* `1` — Subscribe: receive updates as the market status changes
* `2` — Unsubscribe: stop streaming market data for the specified symbol

**`264 MarketDepth`** `int`

The market depth for an order book snapshot. Required.

Possible values:

* `0` — Full order book
* `1` — Top-of-the-book prices

**`265 MDUpdateType`** `int`

The update type. Required. Must be `1` (incremental updates for changed price levels only).

**`267 NoMDEntryTypes`** `int`

The number of `<269>` MDEntryType entries requested. Required.

> Repeating group:

**`269 MDEntryType`** `int`

The side of the quote. Required.

Possible values:

* `0` — Bid
* `1` — Ask

**`146 NoRelatedSym`** `int`

The number of ticker symbols. Required. Must be `1`. To subscribe to multiple symbols, send a separate request for each.

> Repeating group:

**`55 Symbol`** `String`

The market identifier. Required. Format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`.
{% endcolumn %}

{% column width="40%" %}
{% code title="Example (Client → B2TRADER)" overflow="wrap" %}

```
8=FIX.4.4^9=141^35=V^34=7^52=20231220-08:11:50.000^49=sender_b2trader^56=target_b2trader^262=1235^263=1^264=0^265=1^267=2^269=0^269=1^146=1^55=spot.btc_usdt^10=250^
```

{% endcode %}
{% endcolumn %}
{% endcolumns %}

## Market Data — Snapshot/Full Refresh (W)

This message is sent by the server after the client subscribes to a ticker symbol. It contains the full current state of the order book. Subsequent updates are delivered as Market Data — Incremental Refresh messages.

{% columns %}
{% column width="60%" %}
**`55 Symbol`** `String`

The market identifier. Format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`.

**`262 MDReqID`** `String`

The identifier of the originating Market Data Request.

**`268 NoMDEntries`** `int`

The number of market data entries following. The value is `0` if the order book is empty.

> Repeating group (present when `<268>` NoMDEntries > 0):

**`269 MDEntryType`** `int`

The side of the quote. Conditional — required if `<268>` NoMDEntries is not `0`.

Possible values:

* `0` — Bid
* `1` — Ask

**`270 MDEntryPx`** `Price`

The price of the market data entry. Conditional — required if `<268>` NoMDEntries is not `0`.

**`271 MDEntrySize`** `Qty`

The tradable volume of the market data entry. Conditional — required if `<268>` NoMDEntries is not `0`.

**`278 MDEntryID`** `String`

A unique market data entry identifier. Conditional — required if `<268>` NoMDEntries is not `0`.
{% endcolumn %}

{% column width="40%" %}
{% code title="Example (B2TRADER → Client)" overflow="wrap" %}

```
8=FIX.4.4^9=507^35=W^34=48^49=target_b2trader^52=20231222-14:40:39.983^56=sender_b2trader^55=spot.btc_usdt^262=1235^268=9^269=1^270=1.10338^271=3000000^278=4441516524^269=1^270=1.10337^271=1000000^278=4441516521^269=1^270=1.10339^271=5000000^278=4441516523^269=1^270=1.10335^271=600000^278=4441516522^269=0^270=1.10333^271=500000^278=4441516520^269=0^270=1.10332^271=1000000^278=4441516517^269=0^270=1.10331^271=3000000^278=4441516516^269=0^270=1.10334^271=100000^278=4441516519^269=0^270=1.1033^271=5000000^278=4441516518^10=025^
```

{% endcode %}
{% endcolumn %}
{% endcolumns %}

## Market Data — Incremental Refresh (X)

This message is continuously sent by the server after the initial Snapshot/Full Refresh. Each message includes only the changes since the previous update.

{% columns %}
{% column width="60%" %}
**`55 Symbol`** `String`

The market identifier. Format: `{marketType}.{baseAssetId}_{quoteAssetId}`, for example: `cfd.eth_eur`.

**`262 MDReqID`** `String`

The identifier of the originating Market Data Request.

**`268 NoMDEntries`** `int`

The number of market data entries following. The value is `0` if the order book is empty.

> Repeating group (present when `<268>` NoMDEntries > 0):

**`269 MDEntryType`** `int`

The side of the quote. Conditional — required if `<268>` NoMDEntries is not `0`.

Possible values:

* `0` — Bid
* `1` — Ask

**`270 MDEntryPx`** `Price`

The price of the market data entry. Conditional — required if `<268>` NoMDEntries is not `0`.

**`271 MDEntrySize`** `Qty`

The tradable volume of the market data entry. Conditional — required if `<268>` NoMDEntries is not `0`.

**`278 MDEntryID`** `String`

A unique market data entry identifier. Conditional — required if `<268>` NoMDEntries is not `0`.

* Must be unique among active entries when `<279>` MDUpdateAction is `0` (New)
* Must match the previous `<278>` MDEntryID when `<279>` MDUpdateAction is `1` (Change) or `2` (Delete)

**`279 MDUpdateAction`** `int`

The update type. Conditional — required if `<268>` NoMDEntries is not `0`.

Possible values:

* `0` — New
* `1` — Change
* `2` — Delete

**`58 Text`** `String`

Additional context. Optional.
{% endcolumn %}

{% column width="40%" %}
{% code title="Example (B2TRADER → Client)" overflow="wrap" %}

```
8=FIX.4.4^9=201^35=X^34=52^49=target_b2trader^52=20231222-14:40:41.150^56=sender_b2trader^55=spot.btc_usdt^262=1235^268=2^279=1^269=0^270=1.10334^271=200000^278=4441516519^279=2^269=1^270=1.10339^271=0^278=4441516523^10=092^
```

{% endcode %}
{% endcolumn %}
{% endcolumns %}

## Market Data Request Reject (Y)

This message is sent by the server to reject a Market Data Request due to business or technical reasons.

{% columns %}
{% column width="60%" %}
**`262 MDReqID`** `String`

The identifier of the rejected Market Data Request. Required.

**`281 MDReqRejReason`** `int`

The reason why the request is rejected. Optional.

Possible values:

* `0` — Unknown symbol
* `1` — Duplicate MDReqID
* `2` — Insufficient bandwidth
* `3` — Insufficient permissions
* `4` — Unsupported SubscriptionRequestType
* `5` — Unsupported MarketDepth
* `6` — Unsupported MDUpdateType
* `8` — Unsupported MDEntryType

**`58 Text`** `String`

The detailed information about the rejection reason. Optional.
{% endcolumn %}

{% column width="40%" %}
{% code title="Example (B2TRADER → Client)" overflow="wrap" %}

```
8=FIX.4.4^9=118^35=Y^34=3^49=target_b2trader^52=20231221-10:25:11.849^56=sender_b2trader^262=1234^58=symbol 'btcusd' is not supported^10=104^
```

{% endcode %}
{% endcolumn %}
{% endcolumns %}

## Business Reject (j)

This message is sent by the server to reject a message due to a business-level issue not addressed by the standard Market Data Request Reject or session-level Reject.

{% columns %}
{% column width="60%" %}
**`45 RefSeqNum`** `int`

The sequence number of the rejected message (`<34>` MsgSeqNum). Required.

**`372 RefMsgType`** `String`

The type of the rejected message (`<35>` MsgType). Optional.

**`380 BusinessRejectReason`** `int`

The reason why the request is rejected. Required.

Possible values:

* `0` — Other
* `1` — Unknown ID
* `2` — Unknown Security
* `3` — Unsupported MsgType
* `4` — Application not available
* `5` — Conditionally required field missing
* `6` — Not authorized
* `7` — DeliverTo firm not available at this time

**`58 Text`** `String`

The detailed information about the rejection reason. Optional.
{% endcolumn %}

{% column width="40%" %}
{% code title="Example (B2TRADER → Client)" overflow="wrap" %}

```
8=FIX.4.4^9=120^35=j^34=2^49=target_b2trader^52=20231219-22:30:39.617^56=sender_b2trader^45=133^58=Unsupported Message Type^372=V^380=3^10=166^
```

{% endcode %}
{% endcolumn %}
{% endcolumns %}
