ReactとChart.jsで株価チャートを描写
Reactを使って株価チャートを描いてみたいという人がもしかしたらいる?かもしれないのでそんな人のためにReact+Chart.js+投資情報サービスを利用して株価のチャートの描写する方法を説明したいと思います。株に興味がない人も外部のサービスの情報を利用してチャートを表示する方法がどういうものか理解することができます。
APIを利用して株価情報を取得することができるサービスが国内にないか探したのですが手軽に始められそうなものを見つけることができませんでした。そのためアメリカのmarketstackというサービスを利用して行いたいと思います。アメリカには無数のサービスがありどれを選ぶか悩むところですが日本はあまりないようです、この違いは一体何なんでしょう??
目次
利用するサービス
marketstackというグローバルで72の証券取引所をサポートしているアメリカの投資情報サービスを使います。東京証券取引所の株価も情報が取得できると記載されていたのですが残念ながら銘柄検索で東京証券取引所の銘柄がひっかかりませんでした。札幌、名古屋の情報は銘柄検索で表示され銘柄情報はAPI経由で取得することはできても株価は取得できませんでした。
1ヶ月4,000リクエストなら無料だということで動作確認程度であれば十分ということでmarketstackというサービスを利用して株価情報を取得したいと思います。本書での動作確認であればリクエストが100件を超えることもないでしょう。
1日の株価の動きやリアルタイムでの株価の情報取得は有料のプランを契約する必要がありそうです。
marketstackのアカウントの作成
marketstackのサイトにアクセスしてアカウントの作成を行います。アカウント作成時にクレジット情報の登録などは必要ありませんが、請求先の住所のみ入力を求められます。
marketstackにアクセスすると画面左側に”GET API KEY”ボタンが表示されているので、そのボタンをクリックします。右上にある”SIGN UP FREE”ボタンでもアカウントを作成できますが、”SIGN UP FREE”の場合はプランを選択する画面が表示されます。
Free Planでアカウントを作成することが可能なので必要な情報を入力してください。
サインアップが完了するとアクセスに必要なAPIのアクセスキーが表示されます。
情報取得の方法
ドキュメンテーションを見るとAPIのアクセストークンの利用方法を確認することができます。 “Run API Request”ボタンをクリックするとリクエストのJSONデータが表示されます。access_keyには取得したAPIアクセスキーが利用されるので実行すると1回のリクエストとしてカウントされます。
リクエストの実行結果が表示されます。
JavaScript(Node.js)を利用した場合のコードの記述例についても公開されているのでコードの記述に迷うこともありません。
利用するサービスの準備ができたのでReactのプロジェクトを作成します。
Reactプロジェクトの作成
任意のプロジェクト名をつけてReactプロジェクトを作成してください。ここではstockという名前にしています。
% npx create-react-app stock
プロジェクト作成後、プロジェクトのstockフォルダに移動してnpm startコマンドを実行してください。
% cd robinhood_clone
% npm start
srcフォルダに移動して、App.jsファイルを開いてロゴなど必要のないコードを削除します。削除後は下記のようになります。
import './App.css';
function App() {
return (
<div className="App">
</div>
);
}
export default App;
srcフォルダにあるApp.test.js, log.svg, setupTests.jsなど利用しないファイルも削除します。これは必須の作業ではありません。
App.cssファイルを開いて記述されているCSSを削除して下記を設定します。背景をブラック、文字を白に設定しています。
* {
margin: 0;
padding: 0;
}
body {
background-color: #191919;
color: white;
}
株価チャートの作成
銘柄と株価の表示
銘柄と株価をブラウザ上に表示します。Teslaの株価を表示させるため、銘柄名と株価をまずは手動で設定し表示させます。後ほどmarketstackから取得したデータで表示を行います。
import './App.css';
function App() {
return (
<div className="App">
<h1>TSLA</h1>
<h2>$633.25</h2>
</div>
);
}
export default App;
App.cssファイルでAppクラスにCSSを適用します。
.App {
width: 1024px;
margin-top: 100px;
margin-right: auto;
margin-left: auto;
}
ブラウザで確認すると下記のように表示されます。
axiosを利用してmarketstackから会社名と本日の株価の情報を取得します。axiosはpromiseベースのHTTPクライアントで、axiosを利用すると外部サービスからデータの取得を効率的に行うことができます。
axiosのインストール
npmコマンドでaxiosのライブラリをインストールします。
% npm install axios
marketstackからのデータ取得
marketstackにアカウント作成するとアクセスキーを取得することができました。銘柄の情報を取得するために取得したアクセスキーを利用してmarketstackにアクセスしますがどの銘柄の情報を取得するかsymbolを設定する必要があります。
http://api.marketstack.com/v1/tickers/{symbol}?access_key={api_access_key}
marketstackのStock SearchのメニューからSymbolを確認することができます。株になれていない人だとsymbolがすぐにわからないと思いますが各銘柄に4桁のアルファベットが割り振られているようです。AppleならAAPL、AmazonならAMZNといった感じです。
TeslaのSymbolはTSLAなのでTSLAを利用してTeslaの情報を取得します。
URLとACCESS_KEYを定義し、アクセスするURLとAPI ACCESS KEYを設定します。API ACCESS KEYは各自が取得したキーを設定します。marketstackにログインすればダッシュボードページから確認できます。
function App() {
const URL = "http://api.marketstack.com/v1/tickers";
const ACCESS_KEY = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
//略
コンポーネントがmountする時にmarketstackにアクセスして株価情報を取得するためuseEffectフックを利用します。getStockDataメソッドを追加し、引数にsymbolを設定し、useEffectフックの中でgetStockDataを実行します。
import {useEffect} from 'react'
import './App.css';
import axios from 'axios'
function App() {
const URL = "http://api.marketstack.com/v1/tickers";
const ACCESS_KEY = "XXXXXXXXXXXXXXXXXX";
useEffect(() => {
const getStockData = (symbol) => {
axios.get(`${URL}/${symbol}?access_key=${ACCESS_KEY}`)
.then(response => {
console.log(response.data);
});
}
getStockData('TSLA');
},[]);
return (
<div className="App">
<h1>TSLA</h1>
<h2>$633.25</h2>
</div>
);
}
export default App;
デベロッパーツールのコンソールで取得した情報を確認することができます。nameが”TESLA INC”、取引所がNASDAQ Stock Exchange”であることがこの情報からわかります。
取得したデータを保存し、ブラウザ上に表示させるためにuseStateフックを利用します。
const [stockData, setStockData] = useState({})
取得したデータはsetStockDataでstockDataに保存します。
useEffect(() => {
const getStockData = (symbol) => {
axios.get(`${URL}/${symbol}?access_key=${ACCESS_KEY}`)
.then(response => {
// console.log(response.data);
setStockData(response.data)
});
}
getStockData('TSLA');
},[]);
取得したデータをブラウザ上に表示させるためにstockDataを利用します。
<div className="App">
<h1>{ stockData.name }</h1>
<h2>$633.25</h2>
</div>
ブラウザで確認するとmarketstackで取得したデータから会社名を表示させることができます。
会社名の下にある現在の株価を表示させたいのですが、先ほど取得したデータには株価が含まれていませんでした。株価の含まれている情報を取得するため再度axiosを利用して下記のURLにアクセスして株価を取得します。
http://api.marketstack.com/v1/tickers/{symbol}/eod/latest?access_key={api_access_key}
新たに株価を保存するstockPriceをuseStateで定義し、getStockDataメソッドの中にaxiosのgetメソッドを追加します。
const [stockData, setStockData] = useState({})
const [stockPrice, setStockPrice] = useState({});
useEffect(() => {
const getStockData = (symbol) => {
axios.get(`${URL}/${symbol}?access_key=${ACCESS_KEY}`)
.then(response => {
setStockData(response.data)
});
axios.get(`${URL}/${symbol}/eod/latest?access_key=${ACCESS_KEY}`)
.then(response => {
console.log(response.data)
setStockPrice(response.data);
})
}
getStockData('TSLA');
},[]);
デベロッパーツールのコンソールに表示される内容を確認します。symbolがTSLAと表示されているので2020-12-15のTeslaの株価であることがわかります。closeがその日の終値なのでブラウザにcloseを表示させます。他のサービスを利用しても12/15のteslaの株価は633.25であることが確認できました。
ブラウザ上で取得した株価が表示されるように変更を行います。
<div className="App">
<h1>{ stockData.name }</h1>
<h2>${ stockPrice.close }</h2>
</div>
marketstackから取得した株価を表示することができました。
Chartコンポーネント作成
株価チャート用のコンポーネントChartを追加します。srcフォルダにChart.jsファイルとChart.cssを作成します。
import React from 'react'
import './Chart.css'
function Chart() {
return (
<div className="chart">
株価チャート表示
</div>
)
}
export default Chart
App.jsファイルでChartコンポーネントを追加し、株価の下に表示します。
import Chart from './Chart'
<div className="App">
<h1>{ stockData.name }</h1>
<h2>${ stockPrice.close }</h2>
<Chart />
</div>
ブラウザで確認すると下記のように表示されます。
Charコンポーネントの中に株価チャートを表示するためのコードを記述していきます。
chart.jsとreact-chartjs-2インストール
ReactでChart.jsを利用するためchart.jsとreact-chartjs-2のライブラリをインストールします。
% npm install react-chartjs-2 chart.js
Chart.jsによるチャートの表示
Chart.jsではLine, Bar, Pieなどさまざまなチャートを利用することができますが、株価チャートを描写するためLineチャートを利用します。
Lineチャートを利用するためにインストールしたreact-chartjs-2ライブラリからLineコンポーネントをimportします。
import React from 'react'
import './Chart.css'
import {Line} from "react-chartjs-2"
function Chart() {
return (
<div className="chart">
<Line />
</div>
)
}
export default Chart
何もデータを与えていないので線は何も表示されませんが、y軸だけメモリラベルが表示されます。
線を表示させるためにはpropsのdataを使ってLineコンポーネントに情報を与える必要があります。
動作確認のためにdataを設定します。
function Chart() {
const data = {
labels: ['1月','2月','3月','4月'],
datasets:[
{
borderColor: 'rgba(35,200,153,1)',
data: [100,120,50,110],
lineTension: 0,
}
]
}
return (
<div className="chart">
<Line data={data} />
</div>
)
}
export default Chart
これだけの設定を行うだけでブラウザ上に線グラフを表示することができます。図ではわかりににくいですがX軸のラベルにはlabelsの1月,2月..が表示され、Y軸のラベルには50から120までが表示されます。labelsの配列が横軸、dataの配列が縦軸に対応していることがわかります。borderColorは名前の通り、線の色を設定することができます。lineTentionを0に設定すると折れ線グラフのように表示されます。
参考にLineTensionを設定しない場合は直線ではなく曲線でなめらかになります。
data以外にLineコンポーネントのoptions propsを利用してグラフの設定を変更することができます。まず、optionsを利用してlegend(凡例:上部に表示されているグラフの説明,設定を行っていないのでundefinedと表示されています)
const options = {
legend:{
display:false,
},
}
Lineコンポーネントでpropsのoptionsを設定します。
<div className="chart">
<Line data={data} options={options} />
</div>
optionsを設定することでグラフからlegendが決めました。
X軸とY軸のラベルの表示・非表示もoptionsで行うことができます。
const options = {
legend:{
display:false,
},
scales: {
xAxes: [{
display: false
}],
yAxes: [{
display: false
}],
},
}
xAxes, yAxesのdisplayをfalseにすることでX軸とY軸のラベルが非表示になります。
ここまでの動作確認でLineコンポーネントを利用したグラフの表示方法が理解できたので次はmarketstackから取得したデータを利用してグラフを描写します。
marketstackからヒストリーデータ
marketstackでは期間を指定することでその間の株価を取得することができます。
http://api.marketstack.com/v1/eod?access_key={API_KEY}&symbols={symbol}&date_from={start_date}&date_to={end_date}
先ほどApp.jsでuseEffectでgetStockDataを実行した方法を利用して、Chartコンポーネントからmartketstackにアクセスして1ヶ月のヒストリーデータを取得します。
import React,{ useEffect } from 'react'
import './Chart.css'
import {Line} from "react-chartjs-2"
import axios from 'axios'
//略
const URL = "http://api.marketstack.com/v1/eod";
const API_KEY = "yuour_key";
useEffect(() => {
const getStockData = (symbol) => {
axios.get(`${URL}?access_key=${API_KEY}&symbols=${symbol}&date_from=2020-11-17&date_to=2020-12-16&sort=ASC`)
.then(response => console.log(response.data));
}
getStockData('TSLA');
},[]);
土日などの休業日の情報はないので、20日分のデータとなります(2020-11-17から2020-12-16)。グラフに利用するのは横軸のlabelsに設定するdateと縦軸のdataに設定するcloseになります。
取得したデータを保存するためにuseStateでstockDataを定義します。
import React,{ useState, useEffect } from 'react'
//略
const [stockData, setStockData] = useState({});
取得したデータを展開してforで展開してdataとlabelsの配列に設定します。またaxiosでデータ取得してからsetStockDataが実行できるようにasync, await関数を利用しています。
useEffect(() => {
const getStockData = async (symbol) => {
let data = [];
let labels = [];
await axios.get(`${URL}?access_key=${API_KEY}&symbols=${symbol}&date_from=2020-11-17&date_to=2020-12-16&sort=ASC`)
.then(response => {
for ( let stock of response.data.data){
data.push(stock.close)
labels.push(stock.date)
}
});
setStockData({
labels: labels,
datasets:[
{
borderColor: 'rgba(35,200,153,1)',
data: data,
lineTension: 0,
}
]
})
}
getStockData('TSLA');
},[]);
stockDataそのものをLineコンポーネントのpropsのdataに設定します。
<div className="chart">
<Line data={stockData} options={options} />
</div>
ブラウザで確認すると1ヶ月のTeslaの株価の遷移を確認することができます。
GoogleのTeslaの情報と比較すると正しくグラフが表示されていることが確認できます。
縦軸の株価がわかるようにoptionsのyAxesのdisplayを削除してグラフの点にマウスを合わせるとマウスを合わせた日の株価も確認することができます。
銘柄変更や期間変更の機能を追加するだけでオリジナルの投資情報サイトを構築することも可能です。本文書の範囲ではアメリカの銘柄しか表示されませんが。。。