シストレどうですか

  Algorithmic Trading for Dummies

仮想通貨 API 解説編 その1 ー CoinGeckoのAPIを使って価格を取得する

ついに新型コロナワクチンの2回目の接種(ファイザー社製)が終わりました。インフルエンザワクチンとは違い筋肉注射でしたので、2回とも接種後しばらく腕が痛く今までにない経験でした。
これで一安心だと良いのですが、いつまでも持つのか?変異種には効果があるのか?などなどわからない事だらけですので今後どうなる事やらです。(これを毎年やるのはちょっと辛いです・・・)

さて、OandaのAPIの使い方についていろいろ学んできましたが、今回はそれを応用して仮想通貨系のサーバーにアクセスしてみました。
APIを使って自動売買を行おうとすると当然その取引所に口座がないとできませんが、プライスなどのマーケットデータを得るだけであればAPIキーなどの取得なしにアクセスを許可している会社もあります。
それらのうち、CoinGeckoというサイトのAPIを使って仮想通貨の情報を取得してみました。


CoinGeckoとは

サイトの基本情報によれば、暗号通貨のデータ収集サイトとあります。
他にもないかと探したところ、 LinkedInのページ ではクアラルンプール(マレーシア)で設立された会社で”仮想通貨ランキングサイト”との事です。

CoinGeckoのホームページにはいろいろな仮想通貨の情報をいろいろな言語や通貨で表示できるようになっており、アカウント登録をすれば、自分のポートフォリオを登録できるような機能もあります。
また、”ビットコイン保有する上場企業”のページに行くと世界の上場企業でビットコインを大量保有している一覧なども見れます。 先日ニュースになっていたテスラ社が2位に入っていますね。

CoinGeckoのサイト自体にはあまり宣伝広告の類も貼り付けてありませんので、どのようにして収益を挙げているのかよくわかりませんが、APIも無料で提供されていますので、遠慮なく使わさせていただきました。


APIの使い方

マニュアルを解読

まずは説明書がないと何もできませんので、APIのマニュアルのページに行きます。(メニューから行くには[リソース]➡[API] )

www.coingecko.com

画面の少し下のほうへ移動すると、"Explore the API"以下のところに説明がでています。
まずはどんな情報が取得できるかから始まり、無料で使えるとか、できれば"Powered by CoinGecko API"って貼ってねとかですが、 重要なのは、タイムスタンプはUTCタイムゾーンなのと1分間に100リクエストの制限がある、くらいでしょうか。 (ついでにいえば、時間はUNIXタイムで戻ってきます。)

実際のエンドポイントの説明は その下 からになります。
f:id:jantzen:20210326044620p:plain:w420:h400
それぞれのエンドポイントの欄を拡張すると、それぞれの具体的な呼び出し方法が表示されますのでそこをクリックすれば簡単な解説と引数や戻り値の説明が出てきます。
さらに[Try it Out]ボタンを押して引数を入力した後に[Execute]ボタンを押せば実際にその場でAPIを走らせてくれます。
ですからコーディングする前に実行してみてどんなURLや引数を与えればよいか、どんな値が戻ってくるかなど確認できるので非常に便利です。
f:id:jantzen:20210326044911p:plain:w420:h400
というわけですので、早速どうなるか試してみました。

サンプルプログラム

情報を取得するだけなので、例外処理は気にせずに作成してみます。 また、"requests"モジュールをなんとなく理解していれば、マニュアルから得られる情報だけでプログラミングができると思いますので、細かい解説は省略します。

このへんの所がよくわからない方は以前のブログをぜひ参考にしてみてください。
jantzen.hatenablog.com

サーバーからの応答 (/ping)

まずは引数もなくてシンプルな"ping"を使ってサーバーが動いているかどうか確認してみます。

import requests
  
URL = "https://api.coingecko.com/api/v3"
  
#/ping (サーバーからの応答)
endpoint = "/ping"
url = URL + endpoint
response = requests.request("GET", url)
r = response.json()
print(r)

戻り値

{'gecko_says': '(V3) To the Moon!'}

"response.text"でも戻り値を取得できますが、Oanadaの APIでも使えた"response.json()" を使ってみたところ同様にJSON型式のデータを直接取ることが出来ました。
戻り値ですが、サーバーのステータスを表すのになぜ"To the Moon!"なのか気になったので、 Gecko(ヤモリ)と月を結びつけるような意味がないか調べてみましたが、特にこれといったものは出てきませんでした。 ヤモリが夜行性だからでしょうか?それともCoinを月に見立てているのでしょうか?
まさかですが"Gecko"(ゲッコー)と"月光"を掛けているでしょうか?(なんちゃってでスミマセン…)

引数に指定できる値の取得

マニュアルのページの上から順番通りに"simple"エンドポイントで価格を取得と思いましたが、引数に与える値自体がわからなかったので、それらの値を取得できるエンドポイントからこの辺りの情報を収集してみました。

/coins/list (コインの種類)

特定の仮想通貨の情報を検索する場合には"id"引数に値を指定しなければなりませんが、その"id"に指定できる値を見つけるために必要なエンドポイントです。
単純に呼び出すと6,000個以上の値が戻ってきてしまい訳が分からなくなったので、いくつかの仮想通貨だけを調べてみました。
-ビットコイン(BTC)、イーサリアム(ETH)、ザグラフ(GRT)、ライトコイン(LTC)、モナコイン(MONA)

仮想通貨の"symbol"はCoinGeckoのホームページにも表示されていますが、それをすべて小文字に置き換えればよいので、"symbol"から"id"を検索してみました。

import requests
  
URL = "https://api.coingecko.com/api/v3"
#/coins/list (コインの種類を取得)
endpoint = "/coins/list"
url = URL + endpoint

response = requests.request("GET", url)
r = response.json()
symbol = ['btc','eth','grt', 'xrp','ltc','mona']
for i in r:
  if i['symbol'] in symbol:  
    print('%s ⇒ %s' %(i['symbol'], i['id']))

戻り値

btcbitcoin
ethethereum
grtgolden-ratio-token
ltclitecoin
monamonacoin
monamonavale
xrpripple
grtthe-graph

the-graphのようにハイフン"-"でつながっていたり、grtやmonaのように複数でてくるものもありましたが、原則コイン名をすべて小文字にすればよさそうです。

/simple/supported_vs_currencies (通貨の種類)

仮想通貨を換算するための相対通貨名の取得

import requests
  
URL = "https://api.coingecko.com/api/v3"
#/simple/supported_vs_currencies (通貨の種類)
endpoint = "/simple/supported_vs_currencies"
url = URL + endpoint

response = requests.request("GET", url)
r = response.json()
print(r)

戻り値

['btc', 'eth', 'ltc', 'bch', 'bnb', 'eos', 'xrp', 'xlm', 'link', 'dot', 'yfi', 'usd', 'aed', 'ars', 'aud', 'bdt', 'bhd', 'bmd', 'brl', 'cad', 'chf', 'clp', 'cny', 'czk', 'dkk', 'eur', 'gbp', 'hkd', 'huf', 'idr', 'ils', 'inr', 'jpy', 
'krw', 'kwd', 'lkr', 'mmk', 'mxn', 'myr', 'ngn', 'nok', 'nzd', 'php', 'pkr', 'pln', 'rub', 'sar', 'sek', 'sgd', 'thb', 'try', 'twd', 'uah', 'vef', 'vnd', 'zar', 'xdr', 'xag', 'xau', 'bits', 'sats']

コインの種類と同様にすべて小文字になっているようです。

価格の取得 (/simple/price)

価格を取得するために指定する値もわかったところで、価格を取得してみました。
複数指定する場合はカンマ","で仕切れとの事ですので、ビットコインイーサリアムの日本円とUSドルの価格を取得してみました。

import requests
import json
  
URL = "https://api.coingecko.com/api/v3"
#/simple/price (価格を取得)
endpoint = "/simple/price"
url = URL + endpoint
params = {"ids":"bitcoin,ethereum","vs_currencies":"jpy,usd"}
response = requests.request("GET", url, params=params)
r = response.json()
print(json.dumps(r, indent=2))

戻り値

{
  "bitcoin": {
    "jpy": 6041990,
    "usd": 55578
  },
  "ethereum": {
    "jpy": 182146,
    "usd": 1675.5
  }
}

マニュアルでは、引数をURL内の"?"で指定していましたが、"params"で渡してあげても値が返ってきました。
戻ってきた値をCoinGekkoのホームページに表示される値と比べてみると一致しないようです。何か計算式があるようですが、 今回はそこまで調べる時間がなかったので触れないでおきます。

価格の取得 (/coins/markets)

価格に加えマーケットのボリュームや変化率を取得できるエンドポイントです。
"price_change_percentage"引数を使えば、その区間の価格の変化率も取得できます。(1h, 24h, 7d, 14d, 30d, 200d, 1yのみ指定可)

import requests
import json
  
URL = "https://api.coingecko.com/api/v3"
#/coins/markets (価格を取得)
endpoint = "/coins/markets"
url = URL + endpoint
params = {
          "ids" : "bitcoin",
          "vs_currency" : "usd",
          "price_change_percentage" : "1h,24h,7d"
        }
response = requests.request("GET", url, params=params)
r = response.json()
print(json.dumps(r, indent=2))

戻り値

[
  {
    "id": "bitcoin",
    "symbol": "btc",
    "name": "Bitcoin",
    "image": "https://assets.coingecko.com/coins/images/1/large/bitcoin.png?1547033579",
    "current_price": 55431,
    "market_cap": 1035699245106,
    "market_cap_rank": 1,
    "fully_diluted_valuation": 1165371084576,
    "total_volume": 60785812092,
    "high_24h": 57239,
    "low_24h": 53611,
    "price_change_24h": -34.3739996,
    "price_change_percentage_24h": -0.06197,
    "market_cap_change_24h": -680698621.5435791,
    "market_cap_change_percentage_24h": -0.06568,
    "circulating_supply": 18663312.0,
    "total_supply": 21000000.0,
    "max_supply": 21000000.0,
    "ath": 61712,
    "ath_change_percentage": -10.21926,
    "ath_date": "2021-03-13T20:49:26.606Z",
    "atl": 67.81,
    "atl_change_percentage": 81608.00041,
    "atl_date": "2013-07-06T00:00:00.000Z",
    "roi": null,
    "last_updated": "2021-03-24T19:14:45.548Z",
    "price_change_percentage_1h_in_currency": -1.2127389343570512,
    "price_change_percentage_24h_in_currency": -0.061974305525570275,
    "price_change_percentage_7d_in_currency": -2.4629598739452643
  }
]

ちなみに"ath","atl"はそれぞれ"all time high"(過去最高値),"all time low"(過去最安値)ですので、今からみれば昔はなんと割安だったことかというのがよくわかります。

まだ他にもたくさんエンドポイントがありますが、仮想通貨についてはあまり詳しくないこともあり、戻り値の内容も理解できないところがいっぱいありますので、この辺にしておきます。


まとめ

今回はFXを離れて仮想通貨の情報サイトからマーケット情報を取得する方法について試してみました。
ラッパーを利用せずにRest APIを使ったプログラミング方法を覚えておけば、今回のようなGETを使ったAPIであれば自力でコーディングできてしまうよい例ではないでしょうか。

CoinGecko以外にもAPIが使える情報サイトは、 Messari などいろいろありますので、使いやすいサイトを見つけて試してみてください。

応用としては自分の保有している仮想通貨の情報を集めて表をつくるとか、一定の価格を超えたらとか、変動率がいくつ以上になったら等の変動を検知して、それを自分の携帯に通知するような使い方もできますね。

ーラインやDiscordに通知するやり方 jantzen.hatenablog.com

仮想通貨のほうがFX系と違いAPIを提供している会社が多いので、Python等のプログラミング言語で一からボットを作成したい人はFXではなく仮想通貨の取引をしたほうがいろいろ選択肢があっていいかもしれません。