【PHP】暗号通貨のローソク足を取得する方法をはじめから

ここでは主にプログラミングに興味を持つ学生向けに記事を書いています。

文部科学省の学習指導要領改訂により,家庭科において金融教育が導入されます。そこで投資や資産形成をプログラミングの題材にしてみようというのが本稿の趣旨です。ここでは,ローソク足チャートを画面に表示してトレーダー気分を味わってみることを一つの目標にします。

今回は最初のステップとして,暗号通貨のローソク足のデータを取得してみます。暗号通貨を用いるのはなるべく新しいものにチャレンジしてみようという好奇心と,ローソク足のデータを簡単に取得できる API が存在しているためです。

PHPの実行

ローソク足のデータを取得する方法はいくつもありますが,ここではなるべく身近な言語として PHP を用いて話を進めます。PHP を実行するには,XAMPP をインストールし,Apache を起動する必要があります。Apache は自分の PC をサーバーとして動かすソフトウェアです。取得したデータは Chrome などのブラウザ上に表示しますが,データの取得自体はサーバーを通じて行います。

全体の流れを説明します。まず,ブラウザから自分の PC に設置したサーバー(ローカルサーバーと言います)に PHP のコードを送ります。コードには「ここからデータを取ってきて」という命令が書かれているので,ローカルサーバーがそれに基づいてデータを取得します。そして,ローカルサーバーは取得したデータをブラウザに渡し,ブラウザがそのデータを画面に表示します。

つまり,ブラウザは画面に情報を表示する仕事,サーバーはデータのやり取りをする仕事,というようにそれぞれの仕事を分担して行っているのです。

データを取得するコード

まずは,最初のコードを実行してみましょう。

<!DOCTYPE html>
<html lang="ja">
<head><meta charset="utf-8"></head>
<body>
<?php
$url = "https://api.cryptowat.ch/markets/binance/btcusdt/ohlc?periods=3600";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url); //URLを指定
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); //データを文字列で受け取る
$res = curl_exec($ch);
curl_close($ch);
var_dump($res);
?>
</body>
</html>

ファイル名は test.php としてます。ファイルは,C ドライブの xampp というフォルダを開き,その中にある htdocs というフォルダの中に保存しましょう。あとは,Apache を起動した状態でブラウザのアドレス欄に localhost/test.php と入力すると次のような文字が表示されるはずです。

string(76083) "{"result":{"3600":[[1628071200,37739.7,37875.99,37660,37825.35,
1429.801664,54013630.73715126],[1628074800,37825.35,38120,37731.78,38093.13,
1657.432227,62855376.46826354],[1628078400,38090.4,38260,38033.29,38160.06,
1869.066951,71318051.65114385],[1628082000,38160.06,38933.5,38154.32,38860.28,
4926.399379,189773911.72820274],[1628085600,38860.27,39237.73,38749.99,

・・・

これがローソク足のデータです。データは[ CloseTime(時間), OpenPrice(始値), HighPrice(高値), LowPrice(安値), ClosePrice(終値), Volume, QuoteVolume]という順番で並んでいます。ここでは初めの 5 つのデータが必要なものです。

コードの説明

コードを一つずつ見ていきましょう。全体としては HTML の中に PHP を記述する構造になっています。<?php?> で囲まれた部分が PHP のコードです。

$url = "https://api.cryptowat.ch/markets/binance/btcusdt/ohlc?periods=3600";

まず,curlでリクエストする URL を $url に格納します。curl は取得したいデータを URL の形で要求する仕組みです。実は,ここに書いた URL をブラウザのアドレス欄に打ち込むと,上で述べたものとまったく同じデータが画面上に表示されます。通常,アドレス欄に URL を入れると文字や写真などで構成されるホームページが表示されます。一方で,curl はブラウザ側にデータを送ります。

ここでは,中国にある Cryptowatch というサイトからデータを取得しています。取得しているデータは主要な暗号通貨取引所の一つである Binance における,ビットコインの価格(アメリカドル)のローソク足の情報です。URL の markets/binance/btcusdt/ohlc の部分がこれに該当します。この部分の文字列を変更することで,さまざまな取引所におけるその他の暗号通貨のデータを取り出すことができます。

また ?periods=3600 はパラメータと呼ばれるもので,3600 秒つまり 1 時間ごとのローソク足を取得することを意味しています。この値を変えることで,1 分足や 4 時間足など時間の区切りを変えたデータを取得することができます。

$ch = curl_init();

curl を初期化します。初期化が具体的に何を行っているのかは知らなくて大丈夫です。ここでは curl という機械の電源スイッチを押しているのだ,というくらいに解釈しておけば良いでしょう。無事に機械が起動すると $ch にはハンドルという情報が格納されます。ハンドルとは何か,についても深く知る必要はありません。機械を操作できる者に与えられる免許証のようなものだと思えば良いでしょう。

curl_setopt($ch, CURLOPT_URL, $url); //URLを指定

curl に URL の情報を設定します。

curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); //データを文字列で受け取る

データを文字列で受け取る,という設定を行います。この辺りもなぜそうするのかを考えるとキリが無いので,儀式として書いておきましょう。

$res = curl_exec($ch);

curl を実行します。$res にデータが文字列として格納されます。

curl_close($ch);

curl は仕事を終えたので,セッションを閉じます。機械の電源をオフにすることと同じです。

var_dump($res);

$res に格納されたデータを画面に表示します。

データを配列に格納する

第一段階としてデータを取得しました。取得された文字列は JSON 形式で記述されています。しかしながら,このままではデータをうまく扱うことができません。

取得されたデータは,いわば紙の上に数字をただ書き並べただけの状態であり,「○月○日の高値のデータがほしい」と思っても,数字の羅列の中から必要なデータを見つけることはほとんど不可能です。

そこで,JSON 形式の文字列を配列に格納してみます。配列は,小さな箱がいくつも並んでいる姿を想像すると良いでしょう。紙の上にただ並べて書いただけのデータを一つ一つ分けて箱の中に入れていきます。

コードを書き直します。

<!DOCTYPE html>
<html lang="ja">
<head><meta charset="utf-8"></head>
<body>
<?php
$url = "https://api.cryptowat.ch/markets/binance/btcusdt/ohlc?periods=3600";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url); //URLを指定
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); //データを文字列で受け取る
$res = curl_exec($ch);
curl_close($ch);
$array = json_decode($res, true);
?>
<p>ローソク足(1時間足)</p>
<?php
for($i=0;$i<=10;$i++){
    $unixtime = $array["result"][3600][$i][0];
    echo date('Y/m/d H 時 ', $unixtime);
    echo "始値", $array["result"][3600][$i][1];
    echo " 高値", $array["result"][3600][$i][2];
    echo " 安値", $array["result"][3600][$i][3];
    echo " 終値", $array["result"][3600][$i][4];
    echo "<BR>";
}
?>
</body>
</html>

結果は以下のようになります。

ローソク足(1時間足)

2021/08/04 23 時 始値39752.17 高値39874 安値39620 終値39755.75
2021/08/05 00 時 始値39755.74 高値39969.66 安値39722.88 終値39838.38
2021/08/05 01 時 始値39837.47 高値39959 安値39517.19 終値39716.29
2021/08/05 02 時 始値39716.28 高値39913.07 安値39550.02 終値39723.18
2021/08/05 03 時 始値39723.17 高値39849.61 安値39533.55 終値39554.63
2021/08/05 04 時 始値39554.64 高値39600 安値39167 終値39491.58
2021/08/05 05 時 始値39491.59 高値39501.87 安値39207.25 終値39376.78
2021/08/05 06 時 始値39376.06 高値39562.79 安値39200 終値39435.09
2021/08/05 07 時 始値39438.06 高値39530.6 安値39290.25 終値39363.64
2021/08/05 08 時 始値39363.65 高値39519.99 安値39300 終値39382.64
2021/08/05 09 時 始値39382.64 高値39382.64 安値39000 終値39088.18

変更された部分を見ていきましょう。

$array = json_decode($res, true);

JSON文字列をデコードして配列に格納します。このように,PHP には JSON 形式の文字列をコンピュータが解釈して配列にデータを格納してくれる便利な機能があります。

for($i=0;$i<=10;$i++){

for 文は繰り返しの作業を行います。ここでは $i が 0 から 9 まで変化しながら,以下の作業を 10 回繰り返し実行します。

    $unixtime = $array["result"][3600][$i][0];

デコードされた配列がどのような形になっているかはすぐに想像できないかもしれません。JSON 文字列を見てみると

{"result":{"3600":[[1628071200,37739.7,37875.99,37660,37825.35,1429.801664,54013630.73715126]

となっていました。

これは,result という箱の中に 3600 という箱があり,その中に 7 つの数値が入った箱が入っていることを表します。この 7 つの数値は 1 時間足のデータであり,この箱がいくつもあります。

こうして ["result"][3600][0][0]1628071200 というデータを指すことになります。もし, ["result"][3600][0][1] とすれば,それは 37739.7 を指すことになります。

箱に入っている 7 つのデータの 1 番目は UNIX 時間を表します。UNIX時間とは「1970年1月1日午前0時から何秒経過したか」を表すもので,プログラミングではよく利用される時間の表現方法です。

ここでは,この UNIX 時間を $unixtime に格納します。

    echo date('Y/m/d H 時 ', $unixtime);

UNIX 時間は,それを見ても私たちにはそれが何時何分を表すかは分かりません。そこで,date() を使って,私達が理解できる時間の表記に変換します。

    echo "始値", $array["result"][3600][$i][1];
    echo " 高値", $array["result"][3600][$i][2];
    echo " 安値", $array["result"][3600][$i][3];
    echo " 終値", $array["result"][3600][$i][4];

7 つのデータのうち,2 番目から 5 番目までの 4 つのデータを表示します。それぞれのデータは,始値,高値,安値,終値を表しています。

まとめ

ここでは,Cryptwatch の API を利用して,ビットコインのローソク足のデータを取得し,ブラウザの画面上に表示する方法を学びました。JSON 形式で取得したデータを配列に格納し,それぞれのデータを出力できるようになりました。このデータを利用して,ローソク足をグラフの形で表示することもできます。