Using WebSocket to build a Real-time Cryptocurrency Tracker
Published: 2023-03-15 11:04:11

---
title: Using WebSocket to build a Real-time Cryptocurrency Tracker
published: true
date: 2023-03-15 10:25:03 UTC
tags: 
canonical_url: https://blog.michaeltech.xyz/using-websocket-to-build-a-real-time-cryptocurrency-tracker
---
![Cryptocurrency Tracker](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/okyw4c1ant74o0np57x0.jpeg)
In building web applications, the underlying communication architecture plays a vital role in determining the effectiveness of its functionalities. WebSocket is a TCP/IP communication protocol that allows for a consistent bidirectional(two-way )exchange between the client and the server.

This is in stark contrast to the traditional HTTP protocol that allows for a oneway call and response to the server, there are use cases for certain solutions where data on the server side changes rapidly, for these changes to be appropriately reflected, repeated calls to the server has to be made. This method clearly proves to be inefficient in cases that require fast-changing data such as live video streaming, stock, cryptocurrency trading, etc, WebSocket is the best technology to be implemented.

To demonstrate this, we'll implement the WebSocket API to build a real-time Cryptocurrency Tracker. For real-time data around the prices of certain cryptocurrencies, we would be using the [Binance](https://binance-docs.github.io/apidocs/websocket_api/en/#change-log) WebSocket API.

### Single Currency Example

After initiating the basic variables, we use the WebSocket address to create the connection, the _onmessage_ function listens for a message event which is then parsed to get our price property.

Here is the code sample to get the price stream for _ETH_ to _USD_

```
//Web socket ethusd stream
let ws= new WebSocket('wss://stream.binance.com:9443/ws/ethusdt@trade');

let ethUsdt= document.getElementById('eth');
let lastPrice = null;

let price= null;

//Recieves a message event and parses it as a JSON object
ws.onmessage= (event) =>{
    let eventData = JSON.parse(event.data);

        price=parseFloat(eventData.p).toFixed(2); //parses the price property and rounds it up to two decimal places

    ethUsdt.innerText=price;
}

```

Here it is implemented on Codepen



{% codepen https://codepen.io/MichaelEnigma/pen/BaOrPKV %}

What of scenarios were we are watching for multiple currencies? From the Binance API guide, the WebSocket address will take this form, 
``` wss://stream.binance.us:9443/stream?streams=<streamName1>/<streamName2>/<streamName3> ```
 where each stream represents a currency pair.

### Full Dashboard Integration

We will use a dashboard template to display the price stream for Bitcoin, Ethereum, Ripple, and Litecoin.

![Crypto Dashboard](https://cdn.hashnode.com/res/hashnode/image/upload/v1678866776191/a8109b5d-d133-40aa-ac12-e0066a84be80.png)

The WebSocket connection now streams in the message events for the various currency pairs, we'll create conditions to assign the proper currency events to their respective price variables.

```
//Binance multicurrency stream
let ws= new WebSocket('wss://stream.binance.com/stream?streams=ethusdt@trade/btcusdt@trade/xrpusdt@trade/ltcusdt@trade');
// we intialize the variables to hold our prices
let ethUsdt= document.getElementById('eth');
let lastPrice = null;
let btcUsdt= document.getElementById('btc');
let btclastPrice = null;
let xrpUsdt= document.getElementById('xrp');
let xrplastPrice = null;
let ltcUsdt= document.getElementById('ltc');
let ltclastPrice = null;
let price= null;
let btcprice= null;
let xrpprice= null;
let ltcprice= null;
let collection = document.getElementsByClassName("bi");

//Recieves a message event and parses it as a JSON object
ws.onmessage= (event) =>{
    let eventData = JSON.parse(event.data);
// these conditions assigns the various currency prices based on the currency pair
    if (eventData.stream=='ethusdt@trade'){
        price=parseFloat(eventData.data.p).toFixed(2);

    }
    else if(eventData.stream=='btcusdt@trade'){
        btcprice=parseFloat(eventData.data.p).toFixed(2);

    }
    else if(eventData.stream=='xrpusdt@trade'){
        xrpprice=parseFloat(eventData.data.p).toFixed(3);

    }
    else if(eventData.stream=='ltcusdt@trade'){
        ltcprice=parseFloat(eventData.data.p).toFixed(2);

    }

    ethUsdt.innerText=price;

```

For monitoring the changing prices on the dashboard, we'll use [Font Awesome](https://fontawesome.com/) caret up and down icons to give visual indicators about whether the value of the prices is going up or down, an _<i>_ element whose classes are dynamically changed will be used for this purpose.

```
<div class="row m-t-25">
                <div class="col-lg-3">
                    <div class="card currency-card-rounded">
                        <div class="card-body rounded bitcoin">
                            <div class="currency-card--icon pull-right">
                                <i class="cc BTC-alt" title="BTC"></i>
                            </div>
                            <h4>Bitcoin</h4>
                            <h2>
                                $<span id="btc">1.765</span> <i class="bi "></i>
                            </h2>

                        </div>
                    </div>
                </div>
                <div class="col-lg-3">
                    <div class="card currency-card-rounded">
                        <div class="card-body rounded ethereum">
                            <div class="currency-card--icon pull-right">
                                <i class="cc ETH-alt" title="ETH"></i>
                            </div>
                            <h4>Ethereum</h4>
                            <h2>
                                $<span id="eth">1.765</span> <i class="bi "></i>
                            </h2>

                        </div>
                    </div>
                </div>
                <div class="col-lg-3">
                    <div class="card currency-card-rounded">
                        <div class="card-body rounded ripple">
                            <div class="currency-card--icon pull-right">
                                <i class="cc XRP-alt" title="XRP"></i>
                            </div>
                            <h4>Ripple</h4>
                            <h2>
                                $<span id="xrp">1.765</span> <i class="bi "></i>
                            </h2>

                        </div>
                    </div>
                </div>
                <div class="col-lg-3">
                    <div class="card currency-card-rounded">
                        <div class="card-body rounded litecoin">
                            <div class="currency-card--icon pull-right">
                                <i class="cc LTC-alt" title="LTC"></i>
                            </div>
                            <h4>Litecoin</h4>
                            <h2>
                                $<span id="ltc">1.765</span> <i class="bi "></i>
                            </h2>

                        </div>
                    </div>
                </div>
            </div>

```

We'll then include the rest of the Javascript code that allows for this functionality.

```

// let ws= new WebSocket('wss://stream.binance.com:9443/ws/ethusdt@trade');
let ws= new WebSocket('wss://stream.binance.com/stream?streams=ethusdt@trade/btcusdt@trade/xrpusdt@trade/ltcusdt@trade');

let ethUsdt= document.getElementById('eth');
let lastPrice = null;
let btcUsdt= document.getElementById('btc');
let btclastPrice = null;
let xrpUsdt= document.getElementById('xrp');
let xrplastPrice = null;
let ltcUsdt= document.getElementById('ltc');
let ltclastPrice = null;
let price= null;
let btcprice= null;
let xrpprice= null;
let ltcprice= null;
let collection = document.getElementsByClassName("bi"); //holds the array of <i> elements

ws.onmessage= (event) =>{
    let eventData = JSON.parse(event.data);
    if (eventData.stream=='ethusdt@trade'){
        price=parseFloat(eventData.data.p).toFixed(2);

    }
    else if(eventData.stream=='btcusdt@trade'){
        btcprice=parseFloat(eventData.data.p).toFixed(2);

    }
    else if(eventData.stream=='xrpusdt@trade'){
        xrpprice=parseFloat(eventData.data.p).toFixed(3);

    }
    else if(eventData.stream=='ltcusdt@trade'){
        ltcprice=parseFloat(eventData.data.p).toFixed(2);

    }

    ethUsdt.innerText=price;

    // conditions to add the caret icons
   if (price>lastPrice){
    collection[0].classList.remove("bi-caret-down-fill");
    collection[0].classList.add( "bi-caret-up-fill" );
    collection[0].style.color='green';
   }
   else if (price<lastPrice){
    collection[0].classList.remove("bi-caret-up-fill");
    collection[0].classList.add( "bi-caret-down-fill" );
    collection[0].style.color='red';
   }

    lastPrice=price; // after the conditons are fulfilled the value of the lastprice is changed to the current price

    btcUsdt.innerText=btcprice;

    if (btcprice>btclastPrice){
        collection[1].classList.remove("bi-caret-down-fill");
        collection[1].classList.add( "bi-caret-up-fill" );
        collection[1].style.color='green';
       }
       else if (btcprice<btclastPrice){
        collection[1].classList.remove("bi-caret-up-fill");
        collection[1].classList.add( "bi-caret-down-fill" );
        collection[1].style.color='red';
       }    

    btclastPrice=btcprice;

    xrpUsdt.innerText=xrpprice;

    if (xrpprice>xrplastPrice){
        collection[2].classList.remove("bi-caret-down-fill");
        collection[2].classList.add( "bi-caret-up-fill" );
        collection[2].style.color='green';
       }
       else if (xrpprice<xrplastPrice){
        collection[2].classList.remove("bi-caret-up-fill");
        collection[2].classList.add( "bi-caret-down-fill" );
        collection[2].style.color='red';
       }

    xrplastPrice=xrpprice;

    ltcUsdt.innerText=ltcprice;

    if (ltcprice>ltclastPrice){
        collection[3].classList.remove("bi-caret-down-fill");
        collection[3].classList.add( "bi-caret-up-fill" );
        collection[3].style.color='green';
       }
       else if (ltcprice<ltclastPrice){
        collection[3].classList.remove("bi-caret-up-fill");
        collection[3].classList.add( "bi-caret-down-fill" );
        collection[3].style.color='red';
       }

    ltclastPrice=ltcprice;

}

```

And voila! we have our real-time dashboard, the link to the full code is in this [repo](https://github.com/MicahelE/CoinWatcher)

![CoinWatcher](https://cdn.hashnode.com/res/hashnode/image/upload/v1678875724346/92ca4aad-6f48-4094-a2af-93d9d8539e9e.gif)

Awesome! We have demonstrated the practical use of WebSockets in building a real-time cryptocurrency dashboard, what project ideas do you have that this technology will prove to be valuable? Let me know in the comments section.