Latest Ext JS 7.8 is now available. Learn more

Build a Real-Time Javascript Stock Charts Using Sencha Ext JS

April 27, 2021 399 Views
Show

In this global economic turmoil, it has become very important for investors to make the right financial decision based on accurate and up-to-date market data. With Sencha Ext JS and Marketstack API, you can build a stock market web application that provides real-time data and helps the investors uncover valuable insights. In this article, you will find all the details with what we believe is one of the best javascript libraries.

What is Marketstack API?

Marketstack is a REST API that provides real-time stock market data. It supports 25,000 stock tickers across the globe from 72 stock exchanges, including NYSE, Nasdaq, and ENX. Also, it offers accurate historical market data of more than 30 years. With an uptime of nearly 100%, it has become one of the most reliable stock market APIs that you can find online.

Why should you use Marketstack API?

  • Offers real-time, intraday, and historical stock market data in JSON format, which is very easy to integrate with web applications
  • Supports integration with multiple languages and frameworks, including JavaScript, Python, Node, and Go
  • Handles traffic spike efficiently
  • Offers bank-grade security using the industry-standard 256-bit HTTPS encryption
  • Provides easy-to-follow documentation

How to Build a Real-Time Stock Market Web Application with Sencha Ext JS and Marketstack API

Sencha Ext JS is a feature-rich JavaScript framework for building business-grade web applications. By integrating Marketstack API, you can create a real-time Javascript stock charts application easily. Take a look at it:

Real Time Stock Market Web Application Built With Sencha Ext JS And Marketstack API

To create the stock market application shown above, you have to follow these steps:

1. First, you have to create the model. Go to app > model folder, create HomeModel.js file and add these codes:

Ext.define('Demo.model.HomeModel', {

    extend: 'Ext.data.Model',

 

    alternateClassName: [

        'home'

    ],

    requires: [

        'Ext.data.field.Number',

        'Ext.data.proxy.Rest'

    ],

 

    fields: [

        {

            type: 'float',

            name: 'low'

        },

        {

            type: 'float',

            name: 'high'

        },

        {

            type: 'int',

            name: 'date'

        },

        {

            type: 'float',

            name: 'close'

        },

        {

            type: 'float',

            name: 'open'

        }

    ],

 

    proxy: {

        type: 'rest'

    }

});

Here, you are adding different fields, including open, close, data, high and low. Also, you are defining their types.

2. Then you have to create the view. Go inside view folder and create OHLCCharts.js file. Insert these codes:

Ext.define('Demo.view.OHLCCharts', {

extend: 'Ext.panel.Panel',

alias: 'widget.OHLCCharts',

 

alternateClassName: [

'OHLCCharts'

],

requires: [

'Demo.view.OHLCChartsViewModel',

'Demo.view.OHLCChartsViewController',

'Ext.toolbar.Toolbar',

'Ext.toolbar.Fill',

'Ext.form.field.Date',

'Ext.button.Button',

'Ext.chart.CartesianChart',

'Ext.chart.axis.Time',

'Ext.chart.series.CandleStick',

'Ext.chart.interactions.PanZoom',

'Ext.chart.interactions.Crosshair'

],

 

controller: 'ohlccharts',

viewModel: {

type: 'ohlccharts'

},

dock: 'top',

height: '100vh',

padding: 0,

style: {

background: '#ffffff'

},

width: '100wh',

layout: 'fit',

bodyPadding: 0,

frameHeader: false,

manageHeight: false,

 

dockedItems: [

{

xtype: 'toolbar',

alignTarget: '',

border: 2,

dock: 'top',

style: {

background: '#c6e4aa'

},

layout: {

type: 'hbox',

padding: '0 10 0 0'

},

items: [

{

xtype: 'tbfill'

},

{

xtype: 'textfield',

id: 'tickerInput',

width: 100,

fieldLabel: 'Ticker',

labelWidth: 40,

value: 'AAPL'

},

{

xtype: 'datefield',

id: 'fromDatePicker',

width: 250,

fieldLabel: 'From',

labelWidth: 50,

value: '01/01/2020'

},

{

xtype: 'datefield',

id: 'toDatePicker',

resizable: false,

width: 250,

fieldLabel: 'To',

labelWidth: 50,

value: '12/31/2020'

},

{

xtype: 'button',

id: 'refreshBtn',

text: 'Refresh',

listeners: {

click: 'onRefreshBtnClick'

}

}

]

},

{

xtype: 'cartesian',

dock: 'top',

height: '85vh',

id: 'mycandlestickchart',

itemId: 'mycandlestickchart',

margin: '0 0 0 0',

width: '100vw',

colors: [

'#115fa6',

'#94ae0a',

'#a61120',

'#ff8809',

'#ffd13e',

'#a61187',

'#24ad9a',

'#7c7474',

'#a66111'

],

store: 'BtcRateDataJsonPStore',

innerPadding: {

top: 0,

left: 10,

right: 10,

bottom: 0

},

axes: [

{

type: 'time',

fields: [

'date'

],

id: 'bottom',

position: 'bottom'

},

{

type: 'numeric',

fields: [

'low',

'high',

'close',

'open'

],

position: 'left'

}

],

series: [

{

type: 'candlestick',

style: {

ohlcType: 'ohlc',

barWidth: 10,

opacity: 0.9,

dropStyle: {

fill: 'rgb(237,123,43)',

stroke: 'rgb(237,123,43)'

},

raiseStyle: {

fill: 'rgb(55,153,19)',

stroke: 'rgb(55,153,19)'

}

},

xField: 'date',

closeField: 'close',

highField: 'high',

lowField: 'low',

openField: 'open'

}

],

interactions: [

{

type: 'panzoom',

enabled: false,

axes: {

left: {

allowPan: false,

allowZoom: false

},

bottom: {

allowPan: true,

allowZoom: true

}

},

zoomOnPan: true

},

{

type: 'crosshair',

axes: {

bottom: {

label: {

fillStyle: 'white'

},

rect: {

fillStyle: '#344459',

opacity: 0.7,

radius: 5

}

},

left: {

label: {

fillStyle: 'white'

},

rect: {

fillStyle: '#344459',

opacity: 0.7,

radius: 5

}

}

}

}

]

}

],

listeners: {

afterrender: 'onPanelAfterRender',

render: 'onPanelRender'

}

 

});

3. Next, you have to create the view controller of your app. Create OHLCChartsViewController.js file inside view folder and add these codes:

Ext.define('Demo.view.OHLCChartsViewController', {

extend: 'Ext.app.ViewController',

alias: 'controller.ohlccharts',

 

updateUI: function(startDate, endDate, tickerType) {

console.log(startDate, endDate, tickerType);

if(!startDate || !endDate){

startDate = '2020-01-01';

endDate = '2020-12-31';

}

if(this.isVaildPeriod(startDate, endDate)) {

var mycandlestickchart = Ext.ComponentQuery.query('#mycandlestickchart')[0];

var store = mycandlestickchart.getStore();

var marketstackStore = Ext.getStore("marketstackStore");

 

marketstackStore.proxy.extraParams.date_from = startDate;

marketstackStore.proxy.extraParams.date_to = endDate;

marketstackStore.proxy.extraParams.symbols = tickerType;

 

marketstackStore.load({

scope:this,

callback: function(records, operation, success) {

console.log("records", records);

store.setData(records);

console.log("getData", store.getData());

}

});

}

},

 

isVaildPeriod: function(startDate, endDate) {

startDate = new Date(startDate);

endDate = new Date(endDate);

 

if(startDate.getTime() > endDate.getTime()) {

var temp = endDate;

endDate = startDate;

startDate = temp;

}

 

// console.log("endDate - startDate", endDate - startDate);

 

var days = Math.round((endDate - startDate) / (24 * 3600 * 1000));

// console.log("days", days);

if(days > 1000 || days === 0) {

Ext.Msg.alert('Alert', 'You can see only for a year(365days)', Ext.emptyFn);

return false;

} else {

return true;

}

},

 

initMarketStackStore: function() {

Ext.create('Ext.data.Store', {

id         : 'marketstackStore',

model      : 'Demo.model.HomeModel',

autoLoad   : true,

autoDestroy: true,

proxy: {

type: 'rest',

url : 'https://api.marketstack.com/v1/eod',

useDefaultXhrHeader: false, // <= HERE

extraParams: {

access_key: 'c611bbc77b83810b23b0871dca45fb7e',

symbols: 'AAPL',

date_from: '2021-03-31',

date_to: '2021-04-10',

limit: 1000

},

reader: {

type           : 'json',

headers: {'Accept': 'application/json'},

totalProperty  : 'total',

successProperty: 'success',

messageProperty: 'message',

transform: function(response){

// console.log("data", data);

var data = response.data.slice();

data = data.map((dataForDay) => {

//                     console.log("before", dataForDay);

dataForDay.date = new Date(dataForDay.date).getTime();

//                     console.log("after", dataForDay);

return dataForDay;

});

return data;

}

}

}, // <= and notice this change

fields: [

{

type: 'float',

name: 'high'

},

{

type: 'float',

name: 'low'

},

{

type: 'int',

name: 'date'

},

{

type: 'float',

name: 'close'

},

{

type: 'float',

name: 'open'

}

]

});

},

 

onRefreshBtnClick: function(button, e, eOpts) {

var mycandlestickchart = Ext.ComponentQuery.query('#mycandlestickchart')[0];

var fromDatePicker = Ext.ComponentQuery.query('#fromDatePicker')[0];

var fromDate = fromDatePicker.value;

 

var toDatePicker = Ext.ComponentQuery.query('#toDatePicker')[0];

var toDate = toDatePicker.value;

 

var tickerType = Ext.ComponentQuery.query('#tickerInput')[0].value;

 

// console.log(":tickerType", tickerType);

// console.log("Ext.ComponentQuery.query('#tickerInput')[0]", Ext.ComponentQuery.query('#tickerInput')[0]);

 

if(fromDate && toDate) {

fromDate = new Date(fromDate);

toDate = new Date(toDate);

 

if(fromDate > toDate) {

var temp = toDate;

toDate = fromDate;

fromDate = temp;

}

 

fromDate = Ext.Date.format(fromDate, 'Y-m-d');

toDate = Ext.Date.format(toDate, 'Y-m-d');

 

this.updateUI(fromDate, toDate, tickerType);

}

},

 

onPanelAfterRender: function(component, eOpts) {

this.updateUI("2020-01-01", "2020-12-31", "AAPL");

},

 

onPanelRender: function(component, eOpts) {

console.log("onPanelRender");

this.chart = Ext.ComponentQuery.query('#mycandlestickchart')[0];

this.initMarketStackStore();

}

 

});

Here, you are creating different functionalities of the Stock Market app, like updating UI based on start date, end date, and ticker type.

4. Then you have to create the view model of your web application. Create the OHLCChartsViewModel.js inside the view folder and insert these codes:

Ext.define('Demo.view.OHLCChartsViewModel', {

extend: 'Ext.app.ViewModel',

alias: 'viewmodel.ohlccharts',

 

alternateClassName: [

'homepanel'

]

 

});

5. Now, it’s time for creating the controller. Go to app > controller folder. Create MyController.js file and add these codes:

Ext.define('Demo.controller.MyController', {

extend: 'Ext.app.Controller',

 

alternateClassName: [

'home'

]

});

6. Next, you will need the Marketstack API access key. You can get it for free by signing up here.

7. Create a new folder, called store, inside the app folder. Then create BtcRateDataJsonPStore.js file. Now, add these codes:

Ext.define('Demo.store.BtcRateDataJsonPStore', {

extend: 'Ext.data.Store',

alias: 'store.BtcRateDataStore',

 

alternateClassName: [

'btcratedatastore'

],

requires: [

'Demo.model.HomeModel',

'Ext.data.proxy.JsonP',

'Ext.data.reader.Json',

'Ext.data.field.Number',

'Ext.data.field.String'

],

 

constructor: function(cfg) {

var me = this;

cfg = cfg || {};

me.callParent([Ext.apply({

storeId: 'BtcRateDataJsonPStore',

model: 'Demo.model.HomeModel',

proxy: {

type: 'jsonp',

cacheString: '\'\'',

directionParam: '\'\'',

extraParams: {

access_key: 'c611bbc77b83810b23b0871dca45fb7e',

symbols: 'AAPL',

date_from: '2021-03-31',

date_to: '2021-04-10',

limit: 1000

},

limitParam: '\'\'',

pageParam: '\'\'',

sortParam: '\'\'',

startParam: '\'\'',

url: 'https://api.marketstack.com/v1/eod',

autoAppendParams: false,

reader: {

type: 'json',

transform: function(data) {

 

console.log("data", data);

return data;

},

rootProperty: 'data',

successProperty: '\'\'',

totalProperty: '\'\''

}

},

fields: [

{

type: 'float',

name: 'high'

},

{

type: 'float',

name: 'low'

},

{

type: 'string',

name: 'date'

},

{

type: 'float',

name: 'close'

},

{

type: 'float',

name: 'open'

}

]

}, cfg)]);

}

});

Integrating the Marketstack API with the ExtJS App

Keep in mind that you are inserting the access key of Marketstack API, which you obtained at Step 6, by using these codes:

extraParams: {

access_key: 'c611bbc77b83810b23b0871dca45fb7e',

Also, take a look at this line:

url: 'https://api.marketstack.com/v1/eod',

That’s it! You have built a real-time stock market web application with Sencha Ext JS and Marketstack API, which looks like this:

Marketstack6

Source Code:

You can find the project files on GitHub.

How to launch the project on your PC?

To run the project, you will need Sencha Architect. You can download it for free from here.

Once you are done with the installation, open the project on Sencha Architect. Then preview and build it. The stock market app will show up on your favorite web browser.

Wrapping Up

That’s how you build a real-time stock market web application utilizing Marketstack API. You can use the same codes to display real-time stock market data in your cross-platform application using Sencha Ext JS.

Sencha Ext JS is a feature-rich JavaScript library for building data-intensive web applications. Try it now for free.

Recommended Articles

8 Must-Know Tips for Choosing the Right Web Application Framework for Your Project

Starting web application development on a project can feel like a very difficult task. The abundance of frameworks adds to the confusion. It leaves developers…

Web Application Development | Top 10 Frameworks in 2024

If you are a developer, you must know the role of frameworks in creating amazing applications. Web application development frameworks come with pre-built tools to…

Understanding the Difference: When to Use Ext JS Classic vs. Modern Toolkit

Ext JS is a JavaScript framework for building powerful web and mobile applications. The framework features over 140+ high-performance, fully tested, and customizable UI widgets/components.…

Ext JS 7.8 Has Arrived!

The Sencha team is pleased to announce the latest Ext JS version 7.8 release. Following the 7.7 release, which included numerous quality enhancements in Ext…

How to Work with Ext JS Models and Stores: Tutorial on Managing Data and State

Ext JS is a popular JavaScript framework for creating robust enterprise-grade web and mobile applications. The framework offers a rich set of high-performance and fully-tested…

Discover the Top 07 Architecture Patterns used in Modern Enterprise Software Development

Developing software without an architecture pattern may have been an option back then. However, that’s not the case anymore. Modern software development requires apps to…

View More