Start creating a technical analysis trading web or mobile application in minutes!
By: Michael Whittle
Tags: Nodejs, Technical Indicator, Trading, React, Cryptocurrency

This tutorial will get you started creating the frame of a web or mobile trading application/bot in minutes. I will be using free trading data from the Coinbase Pro API but you can use any exchange data be it for cryptocurrencies, forex or any traditional stocks.

Libraries we will need?

create-react-app (quick start React.js front-end application)

(quick start React.js front-end application) express-generator (quick start Node.js back-end API)

(quick start Node.js back-end API) coinbase-pro (library for interfacing with Coinbase Pro API)

(library for interfacing with Coinbase Pro API) technicalindicators (library for trading technical indicators)

(library for trading technical indicators) axios (library to retrieving data from the API)

(library to retrieving data from the API) react-bootstrap-table-next (library for rendering the results)

So let’s start with creating our backend API in Node.js.

% npx express-generator api

% cd api

% yarn <-- OR npm install

% yarn start <-- OR npm start

This will fire up your backend API on http://127.0.0.1:3000 which you can open up in your browser. We will change this later on to port 9000 not to conflict with React which will also want to run on port 3000.

% yarn start

yarn run v1.22.5

$ node ./bin/www

GET / 200 251.272 ms - 170

GET /stylesheets/style.css 200 2.337 ms - 111

GET /favicon.ico 404 9.496 ms - 1222

You then need to add the “cors”, “coinbase-pro” and “technicalindicators” libraries to your project. I use “yarn” but you can use “npm” as well, which ever you prefer.

% yarn add cors coinbase-pro technicalindicators

The reason why we add “cors” is because our requests from our React application on “http://127.0.0.1:3000” will be blocked making requests to our API on “http://127.0.0.1:9000" by default.

If you are not familiar with CORS this is the definition from Mozilla:

Cross-Origin Resource Sharing ( CORS ) is a mechanism that uses additional HTTP headers to tell browsers to give a web application running at one origin , access to selected resources from a different origin. A web application executes a cross-origin HTTP request when it requests a resource that has a different origin (domain, protocol, or port) from its own.

In your “express-generator” project edit the ./bin/www.js and make the following change to the listening port from TCP 3000 to 9000.

< var port = normalizePort(process.env.PORT || '3000');

> var port = normalizePort(process.env.PORT || '9000');

Then edit the ./app.js and make the following changes…

! under var express = require('express');

> var cors = require('cors'); ! under var app = express();

> app.use(cors()); < var usersRouter = require('./routes/users');

> var marketdataRouter = require('./routes/marketdata'); < app.use('/users', usersRouter);

> app.use('/marketdata', marketdataRouter);

Rename ./routes/users.js to ./routes/marketdata.js and replace the contents with the following…

var express = require('express');

var router = express.Router(); const CoinbasePro = require('coinbase-pro');

const publicClient = new CoinbasePro.PublicClient(); const EMA = require('technicalindicators').EMA; /* GET market data */

router.get('/:product', function(req, res, next) {

const product = req.params.product; const granularity = 60 * 60; // 1 hour

const numSamples = 200; // last 200 hours const coeff = 1000 * 60 * 60;

const startDate = new Date();

const startTemp = new Date(startDate.setHours(startDate.getHours() - numSamples));

const startTime = new Date(Math.round(startTemp.getTime() / coeff) * coeff).toISOString();

const endDate = new Date();

const endTime = new Date(Math.round(endDate.getTime() / coeff) * coeff).toISOString();

const options = { start: startTime, end: endTime, granularity }; publicClient.getProductHistoricRates(product, options)

.then(response => {

const data = [];

const closes = []; response.reverse().map(function(value, key) {

closes.push(value[4]); const ema12Data = EMA.calculate({period : 12, values : closes});

const ema12 = Number.parseFloat(ema12Data[ema12Data.length - 1]).toString(10); const ema26Data = EMA.calculate({period : 26, values : closes});

const ema26 = Number.parseFloat(ema26Data[ema26Data.length - 1]).toString(10); const object = {

date: new Date(value[0] * 1000).toISOString(),

low: value[1].toString(10),

high: value[2].toString(10),

open: value[3].toString(10),

close: value[4].toString(10),

volume: value[5].toString(10),

ema12: ema12 !== 'NaN' ? ema12 : '0',

ema26: ema26 !== 'NaN' ? ema26 : '0'

} data.push(object);

}); res.send(data);

})

.catch(error => {

res.send(error);

});

}); module.exports = router;

That should be enough to get your basic API working. I’ve included the EMA12 and EMA26 technical indicators as an example but there are many others included in the technicalindicators library. Just as an aside I could not get this library working with React and React Native. I used @d3fc/d3fc-technical-indicator instead which worked very well. It’s not as comprehensive as the node technicalindicators library but still very good.

I recommend reading my other article “Technical analysis and trading crypto currencies for profit” which will give you a nice introduction into the various technical indicators and how to use them.

So now that our backend API is working we need to create our React.js application.

% npx create-react-app mediumtutorial *** INSTALLATION PROCESS ***

I will be using “axios” to retrieve the data from the API and “react-bootstrap-table-next” (React Bootstrap Table 2) to display a table with the data. So let’s install them now…

% cd mediumtutorial

% yarn add axios react-bootstrap-table-next bootstrap

Start your React.js application…

% yarn start

If you open “http://127.0.0.1:3000” in your browser (if it doesn’t load automatically), it should look like this by default.

Replace your ./App.js with this.

import React, { Component } from 'react';

import BootstrapTable from 'react-bootstrap-table-next';

import axios from 'axios'; import 'bootstrap/dist/css/bootstrap.min.css';

import 'react-bootstrap-table-next/dist/react-bootstrap-table2.min.css'; class App extends Component {

state = {

tableData: []

} componentDidMount() {

axios.get('http://127.0.0.1:9000/marketdata/BTC-USD')

.then((response) => {

this.setState({ tableData: response.data });

});

} render() {

const columns = [

{ dataField: 'date', text: 'Date'},

{ dataField: 'high', text: 'High'},

{ dataField: 'low', text: 'Low' },

{ dataField: 'open', text: 'Open' },

{ dataField: 'close', text: 'Close' },

{ dataField: 'ema12', text: 'EMA12' },

{ dataField: 'ema26', text: 'EMA26'}

];



return (

<BootstrapTable keyField='date' data={ this.state.tableData } columns={ columns } striped bordered hover />

);

}

} export default App;

When you open “http://localhost:3000” in your browser an API call will be made to the backend to retrieve market data for the “BTC-USD” market including the EMA12 and EMA26 technical indicators. It will then be rendered using React Bootstrap Table 2.