Golangでビットコインの値動きを知るCLIツールを作ってみた

Wataru SendoPosted by

この記事はGRIPHONE Advent Calendar 2021 20日目の記事です。

こんにちは。バックエンドエンジニアのsengokです。
今回の記事では、最近業務でPHPerからGolangエンジニアへと転生する機会があり、同時期に興味を持った仮想通貨と絡めて何か練習で作れないかな~というモチベーションで作ったアプリを紹介したいと思います。

非常にシンプルなCLIツールを作成したので、これからGolangに挑戦する方の何かきっかけにもなれば幸いです。

作ったもの

今回はtickerというビットコイン(BTC)の値動きを教えてくれるCLIツールを作りました。

tickerは20秒ごとに最新の値動きを価格と色で表示してくれます。
例えば、20秒前と比較して上がっていた場合は

下がっていた場合は

といった具合で教えてくれます。

なぜ作ったのか

tickerを作成する以前は、ブラウザでCoincheckさんのWebサービス上の取引板を表示しながら作業していたのですが、
なかなかに画面占有率が高くデスクトップ上で小さく表示したい、上下の値動きだけ軽ーく追いたいなというモチベーションから作りました。

どう作ったのか

ざっくり構成図

ざっくりとした構成図は以下になります。

CLI上でtickerと打つとspf13/cobraを経由してプログラムが動き始め、net/httpを使ってCoincheckさんのPublic APIを叩く、結果に対してfaith/colorで色付けをして表示するといった具合になります。

以降で使用したライブラリの特徴やAPIについて詳しく触れていきます。

spf13/cobra

cobra(https://github.com/spf13/cobra)はcobraが生成したひな形のうち特定の箇所を埋めていくだけで簡単にCLIツールを作成できるライブラリです。
コマンドの実処理に加えて、使い方を示すヘルプなどまで簡単に作ることができます。

今回は、生成されたひな形のShortやLongにtickerについての説明、Runのfunc内をtickerの実処理の記述で埋めました。

// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
	Use:   "ticker",
	Short: "Display btc-jpy price",
	Long: `Display the latest price through the Coincheck public API.
Updated to the latest price every 20 seconds.
`,
	Run: func(cmd *cobra.Command, args []string) {
		exPrice := 0.0
		for {
			ticker := getTicker()
			clearTerm()
			fmt.Printf("date  : %s\n", time.Unix(ticker.Timestamp, 0))
			switch {
			case ticker.Ask > exPrice:
				color.Green("price : ↑ %.3f\n", ticker.Ask)
			case ticker.Ask < exPrice:
				color.Red("price : ↓ %.3f\n", ticker.Ask)
			default:
				fmt.Printf("price : - %.3f\n", ticker.Ask)
			}
			exPrice = ticker.Ask
			time.Sleep(20 * time.Second) // API仕様で20秒くらいに1度しか更新しないようになってる(たぶん)
		}
	},
}

今回は使用しませんでしたがサブコマンドやオプションの追加も容易に行うことができて便利です。

Coincheck 取引所 Public API

ビットコインの値動きの取得にCoincheckさんが取引所のPublic APIとして用意している
GET /api/ticker(https://coincheck.com/ja/documents/exchange/api#ticker)を使用しました。

公開されているレスポンス定義に則りstructを用意し、JSONレスポンスから変換を行っています。

type Ticker struct {
	Last      float64 `json:"last"`      // 最後の取引の価格
	Bid       float64 `json:"bid"`       // 現在の買い注文の最高価格
	Ask       float64 `json:"ask"`       // 現在の売り注文の最安価格
	High      float64 `json:"high"`      // 24時間での最高取引価格
	Low       float64 `json:"log"`       // 24時間での最安取引価格
	Volume    float64 `json:"volume"`    // 24時間での取引量
	Timestamp int64   `json:"timestamp"` // 現在の時刻
}

func getTicker() Ticker {
	response, _ := http.Get("https://coincheck.com/api/ticker?pair=btc_jpy")
	defer response.Body.Close()

	body, err := ioutil.ReadAll(response.Body)
	if err != nil {
		panic(err)
	}

	bytes := []byte(body)
	var ticker Ticker
	err = json.Unmarshal(bytes, &ticker)
	if err != nil {
		panic(err)
	}

	return ticker
}

faith/color

faith/color(https://github.com/fatih/color)はCLIの出力に色を付けてくれるパッケージです。

出力したい色で文字列を囲むだけのシンプルな使い勝手で、フォーマット文字列を用いた文字列置換もできます。

color.Green("price : ↑ %.3f\n", ticker.Ask)

color.Red("price : ↓ %.3f\n", ticker.Ask)

今回は使用しませんでしたが、下線を引いたり太字にするなどの装飾もできます。

作ってみた感想

今回、Golangほぼ未経験の状態からA Tour of Go(https://go-tour-jp.appspot.com)や社内の勉強会での学習を経て作ったのがこのtickerだったのですが、構想から数時間で実装することができました。

Golangは自分で実装しないといけない部分が多い、記法に癖があるなどの前評判を聞いていたのですが、実際に触ってみると便利なパッケージも多く慣れると思想が伝わってくる部分も多かったように感じます。

今回は非常にシンプルなCLIツールを作ったので中規模、大規模な開発になるとまた感想は変わるかもしれませんが、今後も継続して使用したい言語だなと感じました。

また、Coincheck 取引所 APIでは実際に取引を行うなど、まだまだいろいろなことができるのでこのCLIツール自体のアップデートも行っていきたいと思っています。

さいごに

今回はGolangを使ってビットコインの値動きをするCLIツールを作成しました。

明日の記事もお楽しみに!