Nodejs Tick Stream Prototype

git repo

I’m a bit new to javascript so feel free to critique the source code. The project gets a key with an https request, authorizes a websocket connection from the key, makes an interface that waits for websocket responses and events, makes an interface that parses the chart events for ticks and presents them in order, and then prints the ticks. Most of this is done asynchronously, so that a request can be made and a response can be waited for or the next tick can be waited for and dealt with when it arrives. It would be nice to see what projects other people are writing to compare with.

The api seems workable so far. A few kinks that I ran into:

  • The example curl command for authentication on the api page has some typos. The appVersion field doesn’t have a comma after it and the \ symbol doesn’t concatenate lines when inside a single quote string.
  • The things I tried involving closestTimestamp and asFarAsTimestamp just gave me one event with an end of history flag. I ended up just using asMuchAsElements: 1.
  • There only seemed to be about an hour of historical tick data.

It would be nice to know if I’m messing something up with any of these or if it’s just a limitation of the api. What’s there so far seems like enough to do the sort of automatic trading that I’m interested in. For example, making a moving average from the history of ticks and trading long above the average and short below the average. Setting up orders, indicators, and setting maximum account losses is what I intend to work on next. Also is there a way to embed source code in a post or upload a text file? That would be more convenient than a git repo.

Hi @fennel, I’m happy to try and help you out.

This may have to do with the contract you’re looking at or the timestamp you’re using. The timestamp has to be within the contract’s expiration.

Yes, you can wrap the code with three backticks (```) on either side.

this is a code block

if you paste your code in between those backticks it should format it. It would be helpful to see your source code.

If you are intending to use JavaScript, you should look at the API tutorial that we have. You seem like you have a good idea of what you want to do - for the more advanced websocket tutorials check out this section.

Edit: I noticed you did post a bitbucket with your source code. From what I can see, you’re using the API correctly. I’ll need some time to look at it and try to reproduce your tick data for closestTimestamp and asFarAsTimestamp.

If you are going to try to reproduce, then here’s a smaller example. If you give a closestTimestamp and an asFarAsTimestamp then getChart only produces a single event with an eoh flag.
example output, id is a number:

{
  "s": 200,
  "i": 0
}
{
  "s": 200,
  "i": 1,
  "d": {
    "mode": "RealTime",
    "historicalId": id,
    "realtimeId": id
  }
}
{
  "e": "chart",
  "d": {
    "charts": [
      {
        "id": id,
        "eoh": true
      }
    ]
  }
}

example source code

import { readFile, writeFile } from 'fs/promises'
import { request } from 'https'
//npm install ws
import WebSocket from 'ws'

const mdWsUrl = 'wss://md.tradovateapi.com/v1/websocket'

export const key = JSON.parse(await readFile('key.json')).key

//every request gets a unique id
async function makeNextId() {
  let count = 0
  return async () => {
    let oldCount = count
    count += 1
    return oldCount
  }
}

const ws = new WebSocket(mdWsUrl)
const nextId = await makeNextId()
const authorizeId = await nextId()
let resolveOpen
const openPromise = new Promise((resolve, reject) => { resolveOpen = resolve })
let resolveAuthorize
const authorizePromise = new Promise((resolve, reject) => { resolveAuthorize = resolve })

ws.on('message', async (message) => {
  try {
    const type = message.slice(0, 1)
    message = message.slice(1, message.length)
    //open frame
    if (type === 'o') {
      resolveOpen()
    }
    //heartbeat frame
    else if (type === 'h') {
      ws.send('[]')
    }
    //array frame
    else if (type === 'a') {
      const messages = JSON.parse(message)
      messages.forEach((eventOrResponse) => {
        console.log(JSON.stringify(eventOrResponse, null, 2))
        if (eventOrResponse['i'] === authorizeId) {
          resolveAuthorize(authorizeId)
        }
      })
    }
    //close frame
    else if (type === 'c') {
    }
    else { throw ('unknown message type ' + type) }
  }
  catch (err) {
    ws.close()
    console.error(err)
    process.exitCode = 1
  }
})

let startDate = new Date()
let endDate = new Date(startDate)
startDate.setUTCMinutes(startDate.getUTCMinutes() - 300)
await openPromise
ws.send('authorize' + '\n' + authorizeId + '\n' + '' + '\n' + key)
await authorizePromise
ws.send('md/getChart' + '\n' + (await nextId()) + '\n' + '' + '\n' + JSON.stringify({
  symbol: 'NQM1',
  chartDescription: {
    underlyingType: 'Tick',
    elementSize: 1,
    elementSizeUnit: 'UnderlyingUnits',
    withHistogram: false
  },
  timeRange: { closestTimestamp: startDate, asFarAsTimestamp: endDate }}))

Hello again @fennel,

I think the issue is that asFarAsTimestamp should be startDate and closestTimestamp should be endDate.

Oh wow that was definitely it. Thanks for that. Although the data only seems to go back 4096 ticks. It would be nice to be able to pull historical tick data for the past few weeks or the past year for backtesting strategies.