> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.ninjatrader.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.ninjatrader.com/_mcp/server.

# Market Data

The Market Data API provides access to market data such as quotes, DOM, charts, and histograms. It uses JSON for request bodies and response data, exchanged over the [WebSocket protocol](/api/websockets).

Example projects are available in [C#](https://github.com/tradovate/example-api-csharp-trading) and [JavaScript](https://github.com/tradovate/example-api-js/tree/main/tutorial/WebSockets/EX-08-Realtime-Market-Data).

## Subscribing to Market Data

A typical market data scenario follows these steps:

1. **Acquire an access token.** Use the standard [authentication](/api/authentication) procedure.

2. **Open a WebSocket and authorize it.** Open a connection and send your access token using the [WebSocket authorization](/api/websockets#authorization) procedure.

3. **Build a request.** Request parameters are a JSON object. Every real-time request requires a `symbol` parameter identifying the contract — either the contract symbol string or the contract ID integer:

   ```js
   { "symbol": "ESM7" }   // by contract symbol
   { "symbol": 123456 }   // by contract ID
   ```

4. **Subscribe.** Send the request to the server, specifying an endpoint such as `md/subscribeQuote`. The server replies with a [response message](/api/websockets#response-message). On success, the subscription is activated and you begin receiving data; on error, perform [error handling](/api/conventions#error-handling). A client can hold a single subscription of each type (quotes, DOM, or charts) per contract, so it's your responsibility to track the contracts you've subscribed to in order to unsubscribe later.

## Handling Market Data

Market data arrives asynchronously as [event messages](/api/websockets#server-event-message) of type `md` or `chart`. For example:

```js
{
  "e": "md",
  "d": {
    "quotes": [
      {
        "timestamp": "2021-04-13T04:59:06.588Z",
        "contractId": 123456,
        "entries": {
          "Bid": { "price": 4205.25, "size": 12 },
          "TotalTradeVolume": { "size": 841200 },
          "Offer": { "price": 4205.50, "size": 8 },
          "LowPrice": { "price": 4195.25 },
          "Trade": { "price": 4205.25, "size": 3 },
          "OpenInterest": { "size": 2415600 },
          "OpeningPrice": { "price": 4198.75 },
          "HighPrice": { "price": 4210.50 },
          "SettlementPrice": { "price": 4201.00 }
        }
      }
    ]
  }
}
```

## Unsubscribing from Market Data

To unsubscribe, build request parameters as you did to subscribe, specify the matching unsubscribe endpoint such as `md/unsubscribeQuote`, and send it. On success, the server deactivates the subscription and stops sending real-time data.

## Request Reference

### Subscribe Quote

**Endpoint:** `md/subscribeQuote`

**Parameters:**

```js
{ "symbol": "ESM7" } // or { "symbol": 123456 }
```

**Data message:**

```js
{
  "e": "md",
  "d": {
    "quotes": [ // "quotes" may contain multiple quote objects
      {
        "timestamp": "2021-04-13T04:59:06.588Z",
        "contractId": 123456,
        "entries": {
          "Bid": { "price": 4205.25, "size": 12 },
          "TotalTradeVolume": { "size": 841200 },
          "Offer": { "price": 4205.50, "size": 8 },
          "LowPrice": { "price": 4195.25 },
          "Trade": { "price": 4205.25, "size": 3 },
          "OpenInterest": { "size": 2415600 },
          "OpeningPrice": { "price": 4198.75 },
          "HighPrice": { "price": 4210.50 },
          "SettlementPrice": { "price": 4201.00 }
        }
      }
    ]
  }
}
```

### Unsubscribe Quote

**Endpoint:** `md/unsubscribeQuote`

**Parameters:**

```js
{ "symbol": "ESM7" } // or { "symbol": 123456 }
```

### Subscribe DOM

**Endpoint:** `md/subscribeDOM`

**Parameters:**

```js
{ "symbol": "ESM7" } // or { "symbol": 123456 }
```

**Data message:**

```js
{
  "e": "md",
  "d": {
    "doms": [ // "doms" may contain multiple DOM objects
      {
        "contractId": 123456,
        "timestamp": "2021-04-13T11:33:57.488Z",
        "bids": [ // depth may vary depending on available data
          { "price": 4205.25, "size": 34 },
          { "price": 4205.00, "size": 758 }
        ],
        "offers": [
          { "price": 4205.50, "size": 255 },
          { "price": 4205.75, "size": 467 }
        ]
      }
    ]
  }
}
```

### Unsubscribe DOM

**Endpoint:** `md/unsubscribeDOM`

**Parameters:**

```js
{ "symbol": "ESM7" } // or { "symbol": 123456 }
```

### Subscribe Histogram

**Endpoint:** `md/subscribeHistogram`

**Parameters:**

```js
{ "symbol": "ESM7" } // or { "symbol": 123456 }
```

**Data message:**

```js
{
  "e": "md",
  "d": {
    "histograms": [ // "histograms" may contain multiple histogram objects
      {
        "contractId": 123456,
        "timestamp": "2017-04-13T11:33:57.412Z",
        "tradeDate": { "year": 2022, "month": 4, "day": 13 },
        "base": 2338.75,
        "items": { // number of items may depend on data
          "-14": 5907,
          "2": 1235
        },
        "refresh": false
      }
    ]
  }
}
```

### Unsubscribe Histogram

**Endpoint:** `md/unsubscribeHistogram`

**Parameters:**

```js
{ "symbol": "ESM7" } // or { "symbol": 123456 }
```

### Get Chart

A client may hold multiple charts for the same contract, so the response to `md/getChart` contains subscription IDs you use to track and unsubscribe from a real-time chart.

**Endpoint:** `md/getChart`

**Parameters:**

```js
{
  "symbol": "ESM7", // or 123456
  "chartDescription": {
    "underlyingType": "MinuteBar", // Tick, DailyBar, MinuteBar, Custom, DOM
    "elementSize": 15,
    "elementSizeUnit": "UnderlyingUnits", // Volume, Range, UnderlyingUnits, Renko, MomentumRange, PointAndFigure, OFARange
    "withHistogram": true
  },
  "timeRange": {
    // all fields are optional, but at least one is required
    "closestTimestamp": "2017-04-13T11:33Z",
    "closestTickId": 123,
    "asFarAsTimestamp": "2017-04-13T11:33Z",
    "asMuchAsElements": 66
  }
}
```

**Response:** The response contains two subscription IDs, `historicalId` and `realtimeId`. Store `realtimeId` so you can cancel the real-time chart subscription with `md/cancelChart`.

```js
{
  "s": 200,
  "i": 13,
  "d": {
    "historicalId": 32,
    "realtimeId": 31
  }
}
```

**Data message:**

```js
{
  "e": "chart",
  "d": {
    "charts": [ // "charts" may contain multiple chart objects
      {
        "id": 9, // matches historicalId or realtimeId from the response
        "td": 20170413, // trade date as YYYYMMDD
        "bars": [ // "bars" may contain multiple bar objects
          {
            "timestamp": "2017-04-13T11:00:00.000Z",
            "open": 2334.25,
            "high": 2334.5,
            "low": 2333,
            "close": 2333.75,
            "upVolume": 4712,
            "downVolume": 201,
            "upTicks": 1334,
            "downTicks": 83,
            "bidVolume": 2857,
            "offerVolume": 2056
          }
        ]
      }
    ]
  }
}
```

### Cancel Chart

**Endpoint:** `md/cancelChart`

**Parameters:**

```js
{
  "subscriptionId": 123456 // the historical chart subscription ID from the md/getChart response
}
```