Updating a Stock Chart in Realtime with Laravel 5.8 and PushRadar

Download code (11.8MB, .zip)
PushRadar: Realtime Stock Chart

This tutorial shows you how to dynamically update a stock chart in realtime with Laravel 5.8 and PushRadar. We will be using PushRadar's PHP library on the server side and PushRadar's JavaScript client library to subscribe to a channel and receive data.

You can download the full source code of this solution as a zip file using the 'Download code' link at the top of this page.

Prerequisites

In order to follow along this guide or run the attached code, you will need the following:

  • PHP 7.2 or later
  • Composer - see getcomposer.org
  • A PushRadar account - you can sign up for free by clicking here

Live demo

If you would like to run a live demo of the finished product, download the attached code, and upload the files in the RealtimeStockChart folder to your server.

  • Replace your-secret-key inside app/Console/Kernel.php with your actual PushRadar secret.
  • Replace your-api-key inside resources/views/welcome.php with your actual PushRadar API key.
  • Start a cron job to call php artisan schedule:run every minute.
  • Navigate to the root of your site (/), and you should see the stock chart update after a minute.
You can obtain your PushRadar API credentials from the API page of your dashboard (www.pushradar.com/app/api).

Getting started

First of all, let's start a new Laravel project called RealtimeStockChart using Composer. Run the following command from your console inside your projects folder:

composer create-project --prefer-dist laravel/laravel RealtimeStockGraph

Change directory to the one you just created by running the following command from your console:

cd RealtimeStockGraph

We need to include PushRadar's PHP library to broadcast stock data. Run the following command to get the latest version of PushRadar's PHP server library:

composer require pushradar/pushradar-php

We are ready to start broadcasting data. Open app/Console/Kernel.php in a code editor and write the following code inside the schedule method:

  • PHP
$schedule->call(function() {
    $data = json_decode(file_get_contents('https://www.highcharts.com/samples/data/aapl-ohlcv.json'));
    $radar = new \PushRadar\PushRadar("your-secret-key");
    $radar->addDataItems($data)->broadcast("stock:data");
})->everyMinute();

The code above gets stock data from Highcharts and broadcasts on the stock:data channel using PushRadar. Remember to replace your-secret-key with your actual PushRadar secret.

Receiving & displaying data

We're now ready to receive and display the stock data using PushRadar's JavaScript client library. Open the resources/views/welcome.php file and replace its content with the following code:

  • HTML
<html>
<head>
    <title>Realtime Stock Graph</title>
    <link rel="stylesheet" type="text/css" href="https://code.highcharts.com/css/stocktools/gui.css">
    <link rel="stylesheet" type="text/css" href="https://code.highcharts.com/css/annotations/popup.css">
    <style>
        #container {
            max-height: 800px;
            height: 75vh;
        }

        .highcharts-bindings-wrapper * {
            box-sizing: content-box;
        }
    </style>
</head>
<body>
    <div id="container" class="chart"></div>

    <script src="https://www.pushradar.com/pushradar.js"></script>
    <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
    <script src="https://code.highcharts.com/stock/highstock.js"></script>
    <script src="https://code.highcharts.com/stock/indicators/indicators-all.js"></script>
    <script src="https://code.highcharts.com/stock/modules/drag-panes.js"></script>
    <script src="https://code.highcharts.com/modules/annotations-advanced.js"></script>
    <script src="https://code.highcharts.com/modules/price-indicator.js"></script>
    <script src="https://code.highcharts.com/modules/full-screen.js"></script>
    <script src="https://code.highcharts.com/modules/stock-tools.js"></script>

    <script>
        var radar = new PushRadar("your-api-key");
        radar.subscribe.to("stock:data", function(data) {
            var ohlc = [],
                volume = [],
                dataLength = data.length,
                i = 0;

            for (i; i < dataLength; i += 1) {
                ohlc.push([
                    data[i][0], // the date
                    data[i][1], // open
                    data[i][2], // high
                    data[i][3], // low
                    data[i][4] // close
                ]);

                volume.push([
                    data[i][0], // the date
                    data[i][5] // the volume
                ]);
            }

            Highcharts.stockChart('container', {
                yAxis: [{
                    labels: {
                        align: 'left'
                    },
                    height: '80%',
                    resize: {
                        enabled: true
                    }
                }, {
                    labels: {
                        align: 'left'
                    },
                    top: '80%',
                    height: '20%',
                    offset: 0
                }],
                tooltip: {
                    shape: 'square',
                    headerShape: 'callout',
                    borderWidth: 0,
                    shadow: false,
                    positioner: function (width, height, point) {
                        var chart = this.chart,
                            position;

                        if (point.isHeader) {
                            position = {
                                x: Math.max(
                                    // Left side limit
                                    chart.plotLeft,
                                    Math.min(
                                        point.plotX + chart.plotLeft - width / 2,
                                        // Right side limit
                                        chart.chartWidth - width - chart.marginRight
                                    )
                                ),
                                y: point.plotY
                            };
                        } else {
                            position = {
                                x: point.series.chart.plotLeft,
                                y: point.series.yAxis.top - chart.plotTop
                            };
                        }

                        return position;
                    }
                },
                series: [{
                    type: 'ohlc',
                    id: 'aapl-ohlc',
                    name: 'AAPL Stock Price',
                    data: ohlc
                }, {
                    type: 'column',
                    id: 'aapl-volume',
                    name: 'AAPL Volume',
                    data: volume,
                    yAxis: 1
                }],
                responsive: {
                    rules: [{
                        condition: {
                            maxWidth: 800
                        },
                        chartOptions: {
                            rangeSelector: {
                                inputEnabled: false
                            }
                        }
                    }]
                }
            });
        });
    </script>
</body>
</html>

Replace your-api-key with your actual PushRadar API key.

Running the application

Upload the code to your server and set up a cron job to call php artisan schedule:run every minute. Then navigate to the root of your website (/) and you should see the stock chart update after a minute.