TradingView Charting Library JS API Setup for Crypto: Realtime Chart Updates

Jon Church
6 min readJun 21, 2018

--

In part 2 of this TradingView JS API Example Guide, we will be implementing Realtime price updates on the chart. Make sure to read the Introduction, and Part 1 first

Photo by toine Garnier on Unsplash

To get realtime updates to the chart, we are continuing from Part 1 where we setup a basic charting widget for static data.

This example will use CryptoCompare’s trade level websocket connection to get price updates as they happen.

You can see the demo deployed here on Glitch, and see the code for part 2 here

Part 1 focused on setting up the TradingView Charting Library widget, and getting the JS API to get historic bars from our data source.

The JS API methods that allow us to update the chart in realtime are:

  • subscribeBars — subscribe to updates for a symbol
  • unsubscribeBars — unsubscribe to updates for a symbol

Essentially what we need to do is update the most recent candle on our chart, whether that is a 1 minute bar, or a 1 day bar, the process is pretty much the same.

We have to keep a record of the last bar on the chart, update it with new price data (did the open, high, low, close, or volume for that period change?), and provide a new bar if we have entered a new period.

Note: If you are providing TV with 1min bars, and letting it build 5min, 15min, etc, bars from that, you will actually be updating 1min bars. Don’t worry though, TV will specify the resolution it needs when it calls subscribeBars !

First, let’s take a look at these new JS API methods we will be working with.

subscribeBars

This method will be called by the charting library after resolveSymbol is called, assuming we were able to successfully resolve the symbol. If you’re not familiar with resolveSymbol check out part 1 of this guide.

subscribeBars: (symbolInfo, resolution, onRealtimeCallback, subscribeUID, onResetCacheNeededCallback) => {

},

The Library will pass these arguments to subscribeBars:

  • symbolInfoObject sybolInfo object resolveBars , bar
  • resolutionString resolution of the bars to provide to TV
  • onRealtimeCallbackFunction pass our updated bar into this callback to update the chart
  • subscribeUIDString unique id for this symbol pair and resolution representing the subscription, based on ticker value + resolution
  • onResetCacheNeededCallbackFunction callback to tell the chart to request the historic static chart data again

In terms of implementation, subscribeBars is called by the library when the chart symbol or resolution is changed, or whenever the chart needs to subscribe to a new symbol.

When subscribe bars is called, we need to create a record of the subscription, including the onRealtimeCallback function, so you can call the onRealtimeCallback function with new data received from your realtime data source.

The JS API is a JS object you pass to the library, which must contain the functions defined by TradingView. These functions are called by the library as needed, you cannot call them yourself, only their callbacks.

What you’re supposed to do is keep a reference to the subscription, and the callbacks passed into the subscribeBars function. To to update the chart, we pass our updated bar into realtimeUpdateCallback .

So let’s see this in action!

Assume we have two files, api/index.js where the JS API lives, and api/stream.js with our realtime update code:

// api/index.jsimport stream from './stream'...subscribeBars: (symbolInfo, resolution, onRealtimeCallback, subscribeUID, onResetCacheNeededCallback) => {  stream.subscribeBars(symbolInfo, resolution, onRealtimeCallback, subscribeUID, onResetCacheNeededCallback)
},
...

Keep in mind that a lot of the above deals with specifics of the data source I’m working with, CryptoCompare’s Socket.io websocket channels.

We need to know a few things which are not provided by the library, we need to know the lastBar we have on the chart, and its values. We need to have a reference to the onRealtimeUpdateCB for the specific chart.

The parts which are specific to TradingView are the following:

  • Create a record of subscriptions, so we can store a reference to the updateCB and pass data to the right chart
  • Updating lastBar or creating a new bar based on updates from our datasource
  • Passing the updated/new bar into the updateCB provided to us when TradingView calls subscribeBars

From the TradingView library’s perspective, it’s as simple as that. But implementing this flow with your own datasource can be as simple or complicated as your system makes it.

TV REQS

Realtime updates are implemented by updating the most recent bar (the currently “open” bar) on the chart. You need to supply the library with the updated version of that bar, as realtime price data comes in.

The JS API provides two functions to manage this. susbcribeBars and unsubscribeBars.

When the chart loads a symbol, or the resolution for the current chart is changed, TV will ask to subscribe to realtime updates for that bar by calling subscribeBars with the symbol and resolution it wants to subscribe to.

subscribeBars: (symbolInfo, resolution, onRealtimeCallback, subscribeUID, onResetCacheNeededCallback) => {
console.log('=====subscribeBars runnning')
}
unsubscribeBars

TV will call the subscribeBars function to initiate the realtime subscription for whatever symbol the chart is displaying. In order to pass update data to the chart, you will call the onRealtimeCallback passed to you insubscribeBars .

Note, that TV calls subscribeBars once, and you will need to keep a reference to the onRealtimeCallback function to call whenever you need to update the chart for that subscription.

So you are responsible for:

  • Connecting to the realtime data source
  • Managing subscriptions TV informs you about through the subscribeBars and unsubscribeBars methods of the JS API.
  • Keeping track of the most recent bar on the chart
  • Massaging your data to TV format

The TV bar format is an object that looks like this:

{
time: 1528322340000, //bar time must be in milliseconds
open: 7678.85,
high: 7702.55,
low: 7656.98,
close: 7658.25, //close for open bars is the most recent price
volume: 0.9834
}

It’s important to understand the difference between TV’s requirements, and your own data implementation. You can get the data however you please, so long as you supply it to the TV library in the proper format.

Below is my own example of implementing CryptoCompare’s socket.io trade data websocket.

This is just part of a full JS API implementation, we are exporting two methods from this file, which will be called from our JS API object we pass to TV. See Part 1 of this tutorial for more about the JS API

Again, your specific data source implementation will likely look different than mine, unless you’re using CryptoCompare as well!

The general steps are:

  • Provide a subscribe/unsubscribeBars function to TV through the JS API
  • Make a record of the subscription, hold onto the realtimeUpdateCallback , uid, and resolution passed to you by TV. You also need the lastBar on the chart. My historyProvider is responsible for keeping track of that initially.
  • Subscribe to appropriate channel with your data source
  • On data from the data source, update the lastBar reference you have (or create a new bar, if the lastBar has closed since last data received) with the new trade data
  • Pass that updated bar into the realtimeCallback for the appropriate subscription.
  • Handle unsubscribing

Let’s breakdown some of what I’m doing to implement CryptoCompare’s specific realtime data to work with this. This is specific to TV only in that I’m massaging the data I have available to the format they specify.

  • Subscribing to channel for trade level updates for the Pair/Exchange specified. Cryptocompare handles many many exchanges, and all the pairs listed there, which is why I built these components into the Symbol Name, e.g, Coinbase:BTC/USD gives me the information I need to subscribe to the correct channel with CryptoCompare
  • On subscription to a channel, listen to the “snapshot” that is sent from CryptoCompare, this is the last few minutes worth of trades from the channel, which allows me to update with price changes that happened between retrieving the historical data, and the moment we connect to the websocket. These updates are sent just like all future updates will be, so I didn’t have to do anything beyond ignore the outdated updates which were older than the lastBar on the chart.
  • I’m pruning each update’s timestamp to the buckets we are using as the trade resolution, this is necessary in order to update the last bar, and determine when we need to open a new bar.
  • Update the lastBar in our subscription record. Record the new high, low, open volume, and close price. Close price will always be the last price update you got. For open bars, “close” is the current price.
  • Send the updated bar to updateCB for the proper subscription.

That’s all for now!

You can see the demo deployed here on Glitch, and see the code for part 2 here

Hopefully this has helped answer some questions for you about realtime updates for Trading View Charting Library!

This has been the most requested part of my series on the charting library, and I intend to update this over time as I simplify the process.

--

--