Build

Live Streaming Global Currency Exchange Rates with Xignite

8 min read Michael Carroll on Jan 3, 2017

Xignite is a cloud-based platform that provides up-to-date financial information across a wide range of categories, on-demand. With Xignite, developers have access to the latest research, pricing, alerts and other information for bonds, equities, global currencies and more. It’s easy to integrate financial information into your real-time application, whether it’s part of an information dashboard, embedded in computations or in response to user-generated queries.

And with that, we’re pleased to announce our newest member of the PubNub BLOCKS Catalog, the Xignite block for global currency exchange rates, allowing you to stream hourly currency exchange rates for 150 currencies, including all majors.

Tutorial Overview

In this article, we’ll dive into a simple example of how to process real-time currency quote requests from an HTML5 AngularJS application with a modest 29-line PubNub JavaScript BLOCK and 85 lines of HTML and JavaScript. In the ever-connected world of global financial markets, business and consumer applications, things move fast. With PubNub and Xignite Global Currency API, applications can have the most up-to-date exchange rates at their fingertips.

Xignite UI in Action

 

As we prepare to explore our sample AngularJS web application with real-time currency quotes, let’s check out the underlying Xignite API.

Xignite API

logo-textThe world of financial market information is huge, and it’s often difficult to find all the necessary information and functionality in one place. Xignite provides market data via a very straightforward API that “just works.” Using one of the dozens of Xignite APIs, it’s possible to answer real-world financial queries in real time.

Obtaining PubNub Developer Keys

Before you can create a real-time application with PubNub, you’ll need your publish and subscribe keys. To get them, create an account and get your keys in the PubNub Admin Portal. The publish and subscribe keys look like UUIDs and start with “pub-c-” and “sub-c-” prefixes respectively. Keep those handy – you’ll need to plug them in when initializing the PubNub object in your HTML5 app below.

Please note that the user interfaces in this series of articles use the v3 API (since they need the AngularJS API, which still runs on v3). We expect the AngularJS API to be v4-compatible soon. In the meantime, please stay alert when jumping between different versions of JS code!

Getting Started with Xignite API

The next thing you’ll need to get started with financial data services is an Xignite account to take advantage of the Xignite APIs.

  • Step 1: go to the Xignite signup form to create an account, requesting access to the GlobalCurrencies API.
  • Step 2: go to the API Tokens section to view your API Token (make note of it for the future).
  • Step 3: that’s it – you’re ready to go.

Setting up the BLOCK

With PubNub BLOCKS, it’s really easy to create code to run in the network. Here’s how to make it happen:

Create Xignite BLOCK
  • Step 2: create a new block.
pubnub_xignite_block_list
  • Step 3: paste in the blockcode from the next section and update the credentials with the API token from the previous step above.
Paste in BLOCK code
  • Step 4: Start the block, and test it using the “publish message” button and payload on the left-hand side of the screen.

That’s all it takes to create your serverless code running in the cloud!

Diving into the Code – the BLOCK

You’ll want to grab the 29 lines of BLOCK JavaScript and save them to a file, say, pubnub_xignite_block.js. It’s available as a Gist on GitHub for your convenience.

First up, we declare our dependency on xhr and query (for HTTP requests) and create a function to handle incoming messages.

export default request => {
    let xhr = require('xhr');
    let query = require('codec/query_string');

Next, we set up variables for accessing the service (the API token and API URL from previous steps).

    let clientToken = 'YOUR_XIGNITE_TOKEN';
    let apiUrl = 'http://globalcurrencies.xignite.com/xGlobalCurrencies.json/GetRealTimeRate';

Next, we check the incoming message to make sure it has both an origin and destination currency specified (returning the unmodified message if that’s not the case).

    let currencyOrigin = request.message.currencyOrigin;
    let currencyDestination = request.message.currencyDestination;
    if (!currencyOrigin || !currencyDestination) {
        return request.ok();
    }

Next, we set up the HTTP options for the quote API request. We use a GET request to retrieve the data. We use a query params for the message values, and use the API token for authentication.

    let queryParams = {
        _token: clientToken,
        Symbol: currencyOrigin + currencyDestination
    };
    let url = apiUrl + '?' + query.stringify(queryParams);

Finally, we call the quote endpoint with the given data, decorate the message with a quote value containing the currency data, and catch any errors and log to the BLOCKS console. Pretty easy!

    return xhr.fetch(url).then((r) => {
        const body = JSON.parse(r.body) || r;
        request.message.quote = body;
        return request.ok();
    })
    .catch((err) => {
        console.log('error happened for XHR.fetch', err);
        return request;
    });
};

All in all, it doesn’t take a lot of code to add real-time market data to our application. We like that!

OK, let’s move on to the UI!

Diving into the Code – the User Interface

You’ll want to grab these 85 lines of HTML & JavaScript and save them to a file, say, pubnub_xignite_ui.html.

The first thing you should do after saving the code is to replace two values in the JavaScript:

  • YOUR_PUB_KEY: with the PubNub publish key mentioned above.
  • YOUR_SUB_KEY: with the PubNub subscribe key mentioned above.

If you don’t, the UI will not be able to communicate with anything and probably clutter your console log with entirely too many errors.

For your convenience, this code is also available as a Gist on GitHub, and a Codepen as well. Enjoy!

Dependencies

First up, we have the JavaScript code & CSS dependencies of our application.

<!doctype html>
<html>
<head>
  <script src="https://code.jquery.com/jquery-1.10.1.min.js"></script>
  <script src="https://cdn.pubnub.com/pubnub-3.15.1.min.js"></script>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
  <script src="https://cdn.pubnub.com/sdk/pubnub-angular/pubnub-angular-3.2.1.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
  <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.2/css/bootstrap.min.css" />
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css" />
</head>
<body>

For folks who have done front-end implementation with AngularJS before, these should be the usual suspects:

  • JQuery : gives us the ability to use easy JQuery selectors.
  • PubNub JavaScript client: to connect to our data stream integration channel.
  • AngularJS: were you expecting a niftier front-end framework? Impossible!
  • PubNub Angular JavaScript client: provides PubNub services in AngularJS quite nicely indeed.
  • Underscore.js: we could avoid using Underscore.JS, but then our code would be less awesome.

In addition, we bring in 2 CSS features:

  • Bootstrap: in this app, we use it just for vanilla UI presentation.
  • Font-Awesome: we love Font Awesome because it lets us use truetype font characters instead of image-based icons. Pretty sweet!

Overall, we were pretty pleased that we could build a nifty UI with so few dependencies. And with that… on to the UI!

The User Interface

Here’s what we intend the UI to look like:

Xignite UI

The UI is pretty straightforward – everything is inside a div tag that is managed by a single controller that we’ll set up in the AngularJS code.

<div class="container" ng-app="PubNubAngularApp" ng-controller="MyFinCtrl">
<pre>
NOTE: make sure to update the PubNub keys below with your keys,
and ensure that the financial data BLOCK is configured properly!
</pre>
  
<h3>MyCurrency Exchange Rates</h3>

We provide simple selects for the currency types to send to the PubNub channel as well as a button to perform the publish() action.

<div>
  Exchange Rates from / to
  <select ng-model="currencyOrigin">
    <option value="USD">USD</option>
    <option value="GBP">GBP</option>
    <option value="EUR">EUR</option>
  </select>
  
  <select ng-model="currencyDestination">
    <option value="USD">USD</option>
    <option value="GBP">GBP</option>
    <option value="EUR">EUR</option>
  </select>
  
  <input type="submit" ng-click="publish()" value="check!" />
</div>

Our UI consists of a simple list of data messages. We iterate over the messages in the controller scope using a trusty ng-repeat. Each message includes the currency quotes (there is additional information from the API inside the message.quote attribute; we just display the human-readable Text attribute).

<ul>
  <li ng-repeat="message in messages track by $index">
    Source: {{message.currencyOrigin}}
    <br />
    Destination: {{message.currencyDestination}}
    <br />
    Quote: {{message.quote.Text}}
  </li>
</ul>

And that’s it – a functioning real-time UI in just a handful of code (thanks, AngularJS)!

The AngularJS Code

Right on! Now we’re ready to dive into the AngularJS code. It’s not a ton of JavaScript, so this should hopefully be pretty straightforward.

The first lines we encounter set up our application (with a necessary dependency on the PubNub AngularJS service) and a single controller (which we dub MyFinCtrl). Both of these values correspond to the ng-app and ng-controller attributes from the preceding UI code.

<script>
angular.module('PubNubAngularApp', ["pubnub.angular.service"])
.controller('MyFinCtrl', function($rootScope, $scope, Pubnub) {

Next up, we initialize a bunch of values. First is an array of message objects which starts out empty. After that, we set up the channel as the channel name where we will send and receive real-time structured data messages.

NOTE: make sure this matches the channel specified by your block configuration!

  $scope.messages  = [];
  $scope.channel   = 'xignite-channel';

We initialize the Pubnub object with our PubNub publish and subscribe keys mentioned above, and set a scope variable to make sure the initialization only occurs once.

NOTE: this uses the v3 API syntax.

  if (!$rootScope.initialized) {
    Pubnub.init({
      publish_key: 'YOUR_PUB_KEY',
      subscribe_key: 'YOUR_SUB_KEY',
      ssl:true
    });
    $rootScope.initialized = true;
  }

The next thing we’ll need is a real-time message callback called msgCallback; it takes care of all the real-time messages we need to handle from PubNub. In our case, we have only one scenario – an incoming message containing the real-time market data. We unshift the message object onto the scope array; that unshift() operation should be in a $scope.$apply() call so that AngularJS gets the idea that a change came in asynchronously.

  var msgCallback = function(payload) {
    $scope.$apply(function() {
      $scope.messages.unshift(payload);
    });
  };

The publish() function takes the contents of the select inputs and publishes them as a structured data object to the PubNub channel that the BLOCK will understand.

  $scope.publish = function() {
    Pubnub.publish({
      channel: $scope.channel,
      message: {currencyOrigin:$scope.currencyOrigin, currencyDestination:$scope.currencyDestination}
    });
  };

In the main body of the controller, we subscribe() to the message channel (using the JavaScript v3 API syntax) and bind the events to the callback function we just created.

  Pubnub.subscribe({ channel: [$scope.channel], message: msgCallback });

We mustn’t forget close out the HTML tags accordingly.

});
</script>
</body>
</html>

Now, we have a direct integration between our real-time message channel and the external financial market data exchange. If you’re building an application on another platform, you would follow exactly the same PubNub message pattern, with the benefit that no data in the block would need to change!

Not too shabby for a little more than eighty lines of HTML & JavaScript!

Conclusion

Thank you so much for joining us in the Xignite Financial Market Data article of our web service integration series! Hopefully it’s been a useful experience learning about finance-aware technologies. In future articles, we’ll dive deeper into additional web service APIs and use cases for other real-time web applications.

Stay tuned, and please reach out anytime if you feel especially inspired or need any help!

0