# Get quote/tick data

**URL:** <https://community.tradovate.com/t/get-quote-tick-data/7809>\
**Category:** API Developers\
**Created:** [September 1, 2023, 11:55am UTC](https://community.tradovate.com/t/get-quote-tick-data/7809 "2023-09-01T11:55:50Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![onemanwolfpack](https://avatars.discourse-cdn.com/v4/letter/o/b487fb/32.png) [@onemanwolfpack](https://community.tradovate.com/u/onemanwolfpack)\
**Post date:** [September 1, 2023, 11:55am UTC](https://community.tradovate.com/t/get-quote-tick-data/7809/1 "2023-09-01T11:55:50Z")

</div>

Are there any existing examples on how to pull quote data?

---

<div class="post-metadata">

**Author:** ![Colby\_Gilbert](https://avatars.discourse-cdn.com/v4/letter/c/7cd45c/32.png) [@Colby\_Gilbert](https://community.tradovate.com/u/Colby_Gilbert)\
**Post date:** [September 6, 2023, 8:18am UTC](https://community.tradovate.com/t/get-quote-tick-data/7809/2 "2023-09-06T08:18:27Z")

</div>

What exactly do you mean by pull quote data? Like set up a socket to receive live quote or replay quote data?

---

<div class="post-metadata">

**Author:** ![onemanwolfpack](https://avatars.discourse-cdn.com/v4/letter/o/b487fb/32.png) [@onemanwolfpack](https://community.tradovate.com/u/onemanwolfpack)\
**Post date:** [September 6, 2023, 12:48pm UTC](https://community.tradovate.com/t/get-quote-tick-data/7809/3 "2023-09-06T12:48:16Z")

</div>

Yes, I am using C# and the demo provided has been very helpful. However, I have used other platforms in testing and it was very obvious how to get quote data. I cannot seem to find it here. Also, if they cap it, as I have read, it is probably a waste of time since I pull 1 million+ quotes a day with other brokers and they have no limitations.

---

<div class="post-metadata">

**Author:** ![Colby\_Gilbert](https://avatars.discourse-cdn.com/v4/letter/c/7cd45c/32.png) [@Colby\_Gilbert](https://community.tradovate.com/u/Colby_Gilbert)\
**Post date:** [September 7, 2023, 7:44pm UTC](https://community.tradovate.com/t/get-quote-tick-data/7809/4 "2023-09-07T19:44:47Z")

</div>

I am not very familiar with c# but here is simplified way of doing it in TypeScript. Also here is a short write up from [the Tradovate docs on the parameters for getChart that start a tick stream](https://api.tradovate.com/#section/Request-Reference/Cancel-Chart). [The Tradovate javascript tutorial](https://github.com/tradovate/example-api-js/tree/main/tutorial/WebSockets) shows a way to get tick data too. You can reference these FAQ responses on limits: [1. Limit Requests and Data](https://github.com/tradovate/example-api-faq/blob/main/docs/HowDoesTradovateLimitRequestsAndData.md) and [2. Data Size Limits](https://github.com/tradovate/example-api-faq/blob/main/docs/HowToHandleDataSizeLimits.md).

It does not sound like there are hard limits.

```auto
import WebSocket, {MessageEvent, Data } from 'ws'

// Type for data received by Tick subscription
export type TickPacket = {
    id: number // Subscription ID, the same as historical/real-time subscription IDs from request response.
    eoh?: boolean // End-of-history used in historical data loads indicates that historical ticks are loaded and further packets will contain real-time ticks
    s: string // Source of packet data.
    td: string // Trade date YYYYMMDD.
    bp: number // Base price of the packet (integer number of contract tick sizes). Tick prices are calculated as relative from this one.
    bt: number // Base timestamp of the packet. Tick timestamps are calculated as relative from this value.
    ts: number // Tick size of the contract for which the tick chart is requested.
    tks: TickRaw[]
}

export type TickRaw = {
    id: number // Tick ID
    t: number // Tick relative timestamp. Actual tick timestamp is packet.bt + tick.t
    p: number // Tick relative price (in contract tick sizes). Actual tick price is packet.bp + tick.p
    s: number // Tick size (seems more proper name should be tick volume). Please don't confuse with contract tick size (packet.ts).
    b: number // Bid relative price (optional). Actual bid price is packet.bp + tick.b
    a: number // Ask relative price (optional).Actual ask price is packet.bp + tick.a
    bs: number // Bid size (optional).
    as: number // Ask size (optional).
}
// Id counter be passed every socket request
let requestId = 0

// the id to pass to md/cancelchart when done with tick stream
let cancelId: number

// reference to heartbeat interval to cancel interval when done with code.
let heartbeatInterval: NodeJS.Timer

// Receive an auth token
const token = getAccessToken() // I assume you have this logic

//Helper function to check if marketData Socket is connected
const isConnected = () => {
        return marketDataSocket && 
                marketDataSocket.readyState !== 0 && 
                marketDataSocket.readyState !== 2 && 
                marketDataSocket.readyState !== 3 && 
                marketDataSocket.readyState !== undefined
    }

//Heartbeat logic to be passed in to setInterval
const sendHeartbeat = () => {
    if (!isConnected()) {
        clearInterval(heartbeatInterval)
        return
    }
    marketDataSocket.send('[]')
}

// Helper function for parsing socket data
const prepareMessage = (raw: Data) => {
        const T = raw.slice(0, 1)
        let data = []
        if ((raw as string).length > 1) {
            data = JSON.parse((raw as string).slice(1))
        }
        return {T, data}
    }

// Once marketDataSocket is connected it will emit an 'o' open frame.
// On open frame connect with auth token and start heartbeat.
const onConnect = async (msg: MessageEvent) => {
    const {T} = prepareMessage(msg.data)
    if (T === 'o') {
        await marketDataSocket.send(`authorize\n${requestId}\n\n${token}`)   
        requestId++
        console.log('[MarketData]: connected.')
        
        marketDataSocket.removeEventListener('message', onConnect)
        heartbeatInterval = setInterval(sendHeartbeat, 2500)
    }
}

// Attach onConnect event listener to socket
marketDataSocket.addEventListener('message', onConnect)
// connect to market data web socket endpoint
const marketDataSocket = new WebSocket('wss://md.tradovateapi.com/v1/websocket')

// Params for tick stream on ESU2023
const tickChartParams = {
   symbol: 'ESU3',
   chartDescription: {
       underlyingType: 'Tick',// Available values: Tick, DailyBar, MinuteBar, Custom, DOM
       elementSize: 1,
       elementSizeUnit: 'UnderlyingUnits', // Available values: Volume, Range, UnderlyingUnits, Renko, MomentumRange, PointAndFigure, OFARange
       withHistogram: false,
    },
    timeRange: {
        asMuchAsElements: 2
     }
}

// Tick event handler
const onTickData = (msg: MessageEvent) => {
    const {T, data} = prepareMessage(msg.data)
    if (T === 'a' && data && data.length > 0) {
        data.forEach((item: any) => {
             // initial response from getChart Request 
             // type guard for chart data, normally you wouldn't hard code 1 as id
             if(item.s === 200 && item.i === 1){
                 cancelId = item.d.realtimeId
             }
             if(item.d && item.d.charts) {
                 item.d.charts.forEach((chart: TickPacket) => {
                     // manipulate data
                     console.log(chart)
                 })
             }
        })

    }
}

marketDataSocket.addEventListener('message', onTickData)
// request id updated to 1 
marketDataSocket.send(`md/getchart\n${requestId}\n\n${tickChartParams}`)
requestId++   

const cancelTickSubscription = () => { 
    const cancelBody = {subscriptionId: cancelId}
    marketDataSocket.send(`md/cancelchart\n${requestId}\n\n${cancelBody}`)
    clearInterval(heartbeatInterval)
}

// After 30 seconds cancel tick subscription and clear interval
setTimeout(()=>{
     cancelTickSubscription()
}, 30*1000)

```

The main issue with the above code is how the requestId counter is handled.
