> For the complete documentation index, see [llms.txt](https://faq.finerymarkets.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://faq.finerymarkets.com/api-reference/websocket-api/feed-f-firm-market-data.md).

# Feed 'F' - Firm Market Data

**Requests**

{% tabs %}
{% tab title="Subscribe" %}
**For takers:**

```json
{"event": "bind", "feed": "F", "feedId": "BTC-EUR"}
```

{% hint style="info" %}
Use`instrument name` as `"feedId"` value to subscribe on instrument book
{% endhint %}

**For masters, the clientId parameter is used to subscribe on behalf of a sub-taker:**&#x20;

```json
{"event": "bind", "feed": "F", "feedId": {"instrument": "BTC-EUR", "clientId": 5}}
```

{% hint style="info" %}
Use `instrument` and `clientId` as `"feedId"` value to subscribe on client's instrument book
{% endhint %}
{% endtab %}

{% tab title="Unsubscribe" %}
**For takers:**

```json
{"event": "unbind", "feed": "F", "feedId": "BTC-EUR"}
```

**For masters:**&#x20;

```json
{"event": "unbind", "feed": "F", "feedId": {"instrument": "BTC-EUR", "clientId": 5}}
```

{% endtab %}
{% endtabs %}

**Feed handling**

{% tabs %}
{% tab title="Definitions" %}

```json
bookLevel = [
  0: price (Efx::Price)
  1: size (Efx::Size)
]
```

{% hint style="warning" %}
Feed 'F' provides incremental updates
{% endhint %}

For a detailed book description

{% content-ref url="/pages/KGixTxfDw51J82MQ1xrB" %}
[book](/api-reference/rest-api/trading/orders-and-order-book/book.md)
{% endcontent-ref %}
{% endtab %}

{% tab title="Possible updates" %}

```json
// snapshot
['F', feed_id, 'S', [
  array of bid bookLevel,
  array of ask boolLevel
]]

// book levels modified
['F', feed_id, 'M', [
  array of bid bookUpdate,
  array of ask bookUpdate,
]]

// book levels added
['F', feed_id, 'M', [[['+', 300000000000, 10000000]], []]]

// book level size modified
['F', feed_id, 'M', [[['M', 300000000000, 10000000]], []]]

// book levels removed
['F', feed_id, 'M', [[['-', 300000000000, 10000000]], []]]

// till specified price, price and size of a new top level are returned
// (both zeros if book side became empty)
['F', feed_id, 'M', [[['~', 300000000000, 10000000]], []]]

// failed to subscribe
['F', feed_id, 'Z', 2]

// unsubscribed
['F', feed_id, 'U', 0]
```

{% endtab %}

{% tab title="Feed update example" %}

```javascript
applyToSnapshot(prevSnapshot, feed, action, data) {
    switch (feed) {
        case 'F': {
            switch (action) {
                case 'S' : {
                    return [[...data[0]], [...data[1]]]
                }
                case 'M' : {
                    data[0].forEach(item => {
                        var side = prevSnapshot[0]
                        switch (item[0]) {
                            case '+': {
                                var found = false
                                for (var i in side) {
                                    if (side[i][0] < item[1]) {
                                        side.splice(i, 0, [item[1], item[2]])
                                        found = true
                                        break
                                    }
                                }
                                if (!found) {
                                    side.push([item[1], item[2]])
                                }
                                break
                            }
                            case 'M': {
                                for (var i in side) {
                                    if (side[i][0] == item[1]) {
                                        side[i][1] = item[2]
                                        break
                                    }
                                }
                                break
                            }
                            case '-': {
                                for (var i in side) {
                                    if (side[i][0] == item[1]) {
                                        side.splice(i, 1)
                                        break
                                    }
                                }
                                break
                            }
                            case '~': {
                                if (item[1]) {
                                    for (var i in side) {
                                        if (side[i][0] == item[1]) {
                                            side[i][1] = item[2]
                                            if (i > 0) {
                                                side.splice(0, i)
                                            }
                                            break
                                        }
                                    }
                                } else {
                                    side.length = 0
                                }
                                break
                            }
                        }
                    })
                    data[1].forEach(item => {
                        var side = prevSnapshot[1]
                        switch (item[0]) {
                            case '+': {
                                var found = false
                                for (var i in side) {
                                    if (side[i][0] > item[1]) {
                                        side.splice(i, 0, [item[1], item[2]])
                                        found = true
                                        break
                                    }
                                }
                                if (!found) {
                                    side.push([item[1], item[2]])
                                }
                                break
                            }
                            case 'M': {
                                for (var i in side) {
                                    if (side[i][0] == item[1]) {
                                        side[i][1] = item[2]
                                        break
                                    }
                                }
                                break
                            }
                            case '-': {
                                for (var i in side) {
                                    if (side[i][0] == item[1]) {
                                        side.splice(i, 1)
                                        break
                                    }
                                }
                                break
                            }
                            case '~': {
                                if (item[1]) {
                                    for (var i in side) {
                                        if (side[i][0] == item[1]) {
                                            side[i][1] = item[2]
                                            if (i > 0) {
                                                side.splice(0, i)
                                            }
                                            break
                                        }
                                    }
                                } else {
                                    side.length = 0
                                }
                                break
                            }
                        }
                    })
                    break
                }
            }
            break
        }
    }
    return prevSnapshot
}
```

{% endtab %}
{% endtabs %}
