62
64

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

JavaScriptでローソク足チャートの作成

Last updated at Posted at 2018-08-27

#概要
株価の推移を可視化するために用いられる、ローソク足チャートをJavaScriptを用いて描画してみます。完成物は、以下の画像のようなものになります。
Screen Shot 2018-08-27 at 21.42.20.png
ユーザが①銘柄コード②チャート描画期間を入力すると、チャートが描画されます。
チャート領域内には、①株価の動きを表すローソク足②三本の移動平均線グラフ③出来高を表す棒グラフ、の三種類の情報が表示されます。
#今回用いるツール
主に二つのツールを用います。
##IEX API
株価や出来高などの金融情報は、IEX APIから取得します。
このAPIからはアメリカの上場企業の株価が無料で取得できます。キーだとかアカウントだとかは必要ありません。国内株が取得できないところが難点ですが、使いやすいので我慢します。

リクエストはHTTPのGET通信で行います。リクエストのURLの例は、https://api.iextrading.com/1.0/stock/aapl/chart/5yのようなものとなります。
/aaplの部分に銘柄コードを、/5yの部分に取得したい期間を記述します。
上の例はアップルの5年分のヒストリカル情報を要求するものですが、これに対するレスポンスは、

[
  {
      "date":"2013-08-27",
      "open":65.1405,
      "high":65.7304,
      "low":63.6101,
      "close":63.9096,
      "volume":105930335,
      "unadjustedVolume":15132905,
      "change":-1.881,
      "changePercent":-2.859,
      "vwap":64.5862,
      "label":"Aug 27, 13",
      "changeOverTime":0
  },
 ...
]

のようなJSON形式のものになります。
##Google Charts
チャートを描画するためのツールです。後述するように、HTMLのscriptタグで読み込んで、JavaScriptで使うことができます。公式ドキュメントはこちら。様々な種類のチャートを作成することができますが、今回はローソク足、線グラフ、棒グラフの三つを用います。
#ページのデザイン(HTML)
まずは簡単にwebページのデザインをします。

chart.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <title>Chart</title>
<!--- デザインに関する規定はこれしかないので、cssファイルではなくstyleタグに記述 --->
<style>
input{
    width: 140px;
    margin: 10px;
}
select{
    margin: 10px;
}
</style>
</head>
<body>
<!--- 銘柄コードを受け付けるボックス --->
    <input type = "text" maxlength = "4" id='input'><button id='btn'>Get Info</button>
<!--- 描画期間を選ばせるプルダウンメニュー --->
    <select id="span">
        <option value="6m" selected>
            6m
        </option>
        <option value="1y">
            1y
        </option>
        <option value="2y">
            2y
        </option>
        <option value="5y">
            5y
        </option>
    </select>
<!--- ローソク足及び移動平均線グラフを配置 --->
    <div id='appendMain'></div>
<!--- 出来高の棒グラフを配置 --->
    <div id='appendVolume'></div>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<!--- ここでGoogle Chartの読み込み --->
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script src="chart.js"></script>
</body>
</html>

最後の方でGoogle Chartを読み込むことを忘れないでください。
#チャートの描画(JavaScript)
いよいよ具体的な処理を記述していきます。jsファイルを用意し、以下の記述を書き加えていきます。
###Google Chartの呼び出し

chart.js
google.charts.load('current', {'packages':['corechart']});

チャート描画の処理を書く前に、このように記述をしてGoogle Chartを呼び出します。'current'は最新バージョンであることを、'corechart'は、今回用いる機能が含まれているパッケージを表します。
###ユーザの入力

chart.js
$('#btn').click(function(){
    var code = $('#input').val()
    var span = $('#span').val()
    getInfo(code, span, mainChart);
})

ユーザがボタンをクリックした際に行われる処理です。変数codeに銘柄コードを、変数spanに描画期間を入れて、これらとコールバック関数「mainChart」を引数にして、getInfo関数を呼び出します。

###APIからの情報取得

chart.js
function getInfo(code, span, callback){
    $.ajax({
        url : 'https://api.iextrading.com/1.0/stock/' + code + '/chart/' + span,
        type : 'GET',       
        async : true,        
        cashe : false,     
        dataType : 'json',  
        contentType : 'application/json' 
    }).done(function(result){
        callback(result);
    }).fail(function(result){
        alert('Failed to load the information');
        console.log(result)
    });  
}

urlの中に、ユーザが入力した銘柄コードと描画期間を組み込み、通信を行います。正常に情報が取得できた場合は、引数として受け取ったmainChartをコールバック関数として実行します。

###ローソク足と移動平均線チャートの作成

chart.js
function mainChart(result){
    //チャートに描画するための最終的なデータを入れる
    var chartData = new google.visualization.DataTable();
        //日付ようにString型のカラムを一つ、チャート描画用に数値型のカラムを7つ作成
        chartData.addColumn('string');
        for(var x = 0;x < 7; x++){
            chartData.addColumn('number');
        }
        //いちいち書くのが面倒なので、取得した情報の長さを配列に入れる
        var length = result.length;
        //描画用のデータを一時的に入れる
        var insertingData = new Array(length);
        //平均を出すための割り算の分母
        var divide = 0;
        //二次元配列aveに、平均線の日数と平均値を入れる
        var ave = new Array();
        //5日平均線用
        ave[0] = new Array();
        //25日平均線用
        ave[1] = new Array();
        //50日平均線用
        ave[2] = new Array();
        //平均線の計算に用いる
        var temp = 0;
        //5日移動平均線の算出
        //基準日より5日前までのデータを足し合わせ、平均値を出す
        for(var m = 0; m < length - 4; m++){
            for(var n = 0; n < 5; n++){
                if(result[m+n].close != ''){
                    temp = temp + parseFloat(result[m+n].close);
                    divide++;
                }
            }
            ave[0][m] = temp / divide;
            temp = 0;
            divide = 0;
        }
        //25日移動平均線の算出
        //上と同様の処理
        for(var m = 0; m < length - 24; m++){
            for(var n = 0; n < 25; n++){
                if(result[m+n].close != ''){
                    temp = temp + parseFloat(result[m+n].close);
                    divide++
                }
            }
            ave[1][m] = temp / divide;
            temp = 0;
            divide = 0;
        }
        //50日移動平均線の算出
        //上と同様の処理
        for(var m = 0; m < length - 49; m++){
            for(var n = 0; n < 49; n++){
                if(result[m+n].close != ''){
                    temp = temp + parseFloat(result[m+n].close);
                    divide++
                }
            }
            ave[2][m] = temp / divide;
            temp = 0;
            divide = 0;
        }
        //for文をまとめるため、出来高棒グラフの処理もここで行う
        //出来高を保持する配列
        var volume = new Array();
        //チャートの日付を保持する配列
        var dates = new Array();
        for(var s = 0; s < length; s++){
            if(result[s].volume != ''){
                volume[s] = result[s].volume;
                dates[s] = String(result[s].date);
            }
        }
        //配列insertingDataの中に、[安値、始値、高値、終値、5日移動平均線、25日移動平均線、50日移動平均線]の形で値を入れ込む
        for(var a = 0; a < length; a++){
            insertingData[a] = [dates[a],parseFloat(result[a].low),parseFloat(result[a].open),parseFloat(result[a].close),parseFloat(result[a].high),ave[0][a],ave[1][a],ave[2][a]]
        }
        //チャート描画用の配列の中に、insertingDataの値を入れ込む
        //最古の50日分のデータまでは移動平均線のデータが揃っていないので、取り除く
        for (var i = insertingData.length - 50; i > 0; i--){
            chartData.addRow(insertingData[i]);
        }
        //チャートの見た目に関する記述、詳細は公式ドキュメントをご覧になってください
        var options = {
            chartArea:{left:80,top:10,right:80,bottom:10},
            colors: ['#003A76'],
            legend: {
                position: 'none',
            },
            vAxis:{
                viewWindowMode:'maximized'
            },
            hAxis: {
                format: 'yy/MM/dd',
                direction: -1,
            },
            bar: { 
                groupWidth: '100%' 
            },
            width: 1200,
            height: 400,
            lineWidth: 2,
            curveType: 'function',
            //チャートのタイプとして、ローソク足を指定
            seriesType: "candlesticks",  
            //ローソク足だでなく、線グラフも三種類表示することを記述
            series: {
                1:{
                    type: "line",
                    color: 'green',
                },
                2:{
                    type: "line",
                    color: 'red',                
                },
                3:{
                    type: "line",
                    color: 'orange',                
                },
            } 
        };
        //描画の処理
        var chart = new google.visualization.ComboChart(document.getElementById('appendMain'));
        chart.draw(chartData, options);
        //出来高棒グラフを作成する関数を呼び出し
        volumeChart(volume, dates, length);
}

###出来高棒グラフの作成

chart.js
function volumeChart(volume, dates, length){
    var chartData = new google.visualization.DataTable();
    //出来高の値と日付のためのカラムを作成
    chartData.addColumn('string');
    chartData.addColumn('number');
    var insertingData = new Array();
    //配列insertingDataの中に、[日付、出来高]の形式でデータを入れ込む
    for(var a = 0; a < length; a++){
        insertingData[a] = [dates[a],parseInt(volume[a])]
    }
    //insertingDataの値をチャート描画用の変数に入れ込む
    for (var i = insertingData.length - 50; i > 0; i--){
        chartData.addRow(insertingData[i]);
    }
    //ローソク足の時と同じように、見た目の設定をする
    var options = {
        chartArea:{left:80,top:10,right:80,bottom:80},
        colors: ['#003A76'],
        legend: {
            position: 'none',
        },
        bar: { 
            groupWidth: '100%' 
        },
        hAxis: {direction: -1},
        width: 1200,
        vAxis:{
            viewWindowMode:'maximized'
        },
    }
    var chart = new google.visualization.ColumnChart(document.getElementById('appendVolume'));
    chart.draw(chartData, options);
}

#完成物
上のコードを書き終わると、成果物が完成します。
以下の画像のように、それっぽいローソク足チャートができています。
Screen Shot 2018-08-27 at 21.42.20.png

62
64
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
62
64

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?