[良い子は真似をしてはいけません]Node.jsとccxtと取引所APIを利用した自家製仮想通貨自動積立システム(ABC2P)

シェアする

  • このエントリーをはてなブックマークに追加
  • Evernoteに保存Evernoteに保存
  • 0

今年は、日本の仮想通貨取引所の、coincheck、Zaifがともに大きなハッキング被害を受け、仮想通貨市場が大暴落しました。coincheckについては私自身あまり利用しておらず、それほど影響を受けなかったのですが、Zaifに関しては仮想通貨の自動積立サービスを利用していたことから、直接的に大きな影響を受けました。(もちろんどちらの件も間接的には価格大暴落というすさまじく大きな影響を受けたのはいうまでもありません(泣))

スポンサーリンク

Zaifハッキング被害の影響

自動積立サービスの停止は大きな誤算

ビットコイン(BTC)は未だ出金不可、モナコイン(MONA)は一部(8割?)強制的に円転された上に未だ出金不可、イーサリアム(ETH)・ネム(XEM)は出金可能という状況で、自動積立も停止されています。(2018/12/09現在)

現状の仮想通貨の市況において、積立を続けることは一般的な視点から見ると愚の骨頂と言えるでしょう。しかしながら、(救いようがないな自分…とは思うのですが、)ブロックチェーン自体に価値を感じている投資家として、「圧倒的なバーゲンセール!」という気持ちも残っています。とはいうものの、これほど極端な相場で自動的で機械的な積立以外で適切に買い増ししていくことができるとも思えません。(だからこそZaif自動積立してたのに…サービス停止されてしまうとは…誤算。)

今後どうするか考えてみた

自前で自動積立の仕組みを作って積立は続ける

2~3年間は何も考えずに買い増ししようという方針を決めていましたので、完全に価値がゼロになることも覚悟した上で、積立は継続したいです。(メインの資産形成として、別の手段を実践しており、仮想通貨では大きな失敗も受け入れられる前提条件だから。)

しかし、手作業で、Zaif自動積立のように、毎日定額で小額ずつ複数の通貨を購入し続けるのは、めんどくさすぎてやりたくありません。

以前から取引所APIを利用した取引には興味があったので、毎日、ほったらかしでも、自動で小額ずつ購入できる仕組みを自前で作って積立を続けることを決意しました。

具体的な仕組み

システム名:ABC2P(Automatic Buying Crypto Currency Program)

せっかく何かを自分で作るからには、気分を盛り上げていきたいところです。一応名前も考えてみました。最初はCCABPという名前にしようと思ったのですが、ABCと並んだほうが語呂が良い気がしたので、少し順番を入れ替えたイメージです。

概要

Node.jsで、ccxtというnpmパッケージ(Node.jsで使えるツールを良い感じに管理してくれる仕組み?)を利用し、Zaif取引所のAPIを介して自動的に注文を出すという仕組みです。

必要なJPYの入金は手動で行う必要があります。

免責事項について

以下で説明するプログラムは、バグ等の問題を含んでいる可能性を否定できません。ご使用にあたって、いかなる結果が生まれたとしても、当方はまったく責任を負うことはできません。皆様の自己責任の下、慎重にお試しください。

環境構築手順

以下はWindows前提で書いていますが、MacやLinuxの方も、ほぼ同じ手順で実行できると思います。(フォルダパスやフォルダ移動のコマンド等は勝手が違うとは思いますが、必要に応じてそこは自分で調べてトライして頂けますと幸いです。)

Node.jsのインストール

以下サイトから普通にダウンロードしてインストールしましょう。本格的な開発では、バージョンを明示的に管理する必要があるため、もっと本格的なインストール手順が必要ですが、ここでは不要です。

PC内の適当な場所にフォルダ作成

どこでも良いのですが、以下の説明を簡略化するため、Cドライブ直下に「abc2p」とフォルダを作成してください。もし違うフォルダを使いたい方は以下の説明で適宜置き換えてください。

C:\abc2p

コマンドプロンプトを起動し、作成したフォルダへ移動

コマンドプロンプトを起動し、「cd ..」コマンドを(場合によっては数回)実行し、Cドライブ直下まで移り、「cd abc2p」コマンドを実行することでC:\abc2pフォルダまで移動できると思います。

npm initコマンド実行

npm init

上記コマンドを実行すると、何か出てきますが、全部そのまま「エンター」を押して次に進みます。最後に(yes)と出てきたところに「エンター」を押すところまでは細かいことを気にせず、エンター連打しましょう。(もちろん、本格的な開発では違うと思います。)

ccxtパッケージのインストール

npm install ccxt --save

上記コマンドを実行します。少し時間がかかった後に何か出てくると思います。警告らしきものが出てきますが、ここではあまり気にする必要はないでしょう。コマンドプロンプトの作業はいったんここまでですが、また後でコマンドプロンプトをこの状態で使用するので、閉じずにそのままにしておきましょう。

自動積立プログラムを記述するファイルの作成(abc2p.js)

C:\abc2pフォルダ内に新規テキストファイルを作成し名前を「abc2p.js」と変更してください。拡張子も.txtから.jsに変更することに注意してください。拡張子が非表示の方は拡張子を表示する設定に変更する必要があるかもしれません。

自動積立プログラムの記述その1

上記で作成したabc2p.jsを右クリックして編集で開き、以下のソースコードをコピペしてください。

'use strict';

//定義
//npmパッケージのccxtを読み込み
const ccxt = require ('ccxt');

//ここの''内のapikey、secretは自分で設定したものに変更する必要あり。この情報は決して第三者に渡してはならない。
const zaif = new ccxt.zaif ({
        apiKey: '',
        secret: '',
    })

//ここの金額を変えれば積立金額を変えられる
const money_per_year = 480000 //年間積立額をここに入力→例として1月4万円の積立なら480000
const money_per_day = money_per_year / 365 //年間365日毎日積立

//ここの割合を変えれば、各通貨の積立割合を変えられる
const btc_ratio = 1 / 3 * 100 //%
const eth_ratio = 1 / 3 * 100 //%
const xem_ratio = 1 / 3 * 100 //%
const mona_ratio = 1 / 4 * 100 * 0 //% MONA購入は現在Zaifでは不可能なため0%に設定しておく

//各通貨の1日当りの購入金額の計算と端数の処理
const money_per_day_btc = money_per_day * btc_ratio / 100
const money_per_day_eth = money_per_day * eth_ratio / 100
const money_per_day_xem = money_per_day * xem_ratio / 100
const money_per_day_mona = money_per_day * mona_ratio / 100

//積立間隔をミリ秒で設定する 例えば1日なら 24 * 60 * 60 * 1000
const interval = 24 * 60 * 60 * 1000

//次回積立タイミングまで待機する関数の定義
const sleep = (timer) => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve()
        }, timer)
    })
}

//ここからプログラム本体(同期、非同期を考慮した記述)
(async function () {
    //常に繰り返し→明示的にキルしない限り実行され続ける
    while (true) {
        //板情報取得
        const ticker_btc = await zaif.fetchTicker ('BTC/JPY')
        const ticker_eth = await zaif.fetchTicker ('ETH/JPY')
        const ticker_xem = await zaif.fetchTicker ('XEM/JPY')
        const ticker_mona = await zaif.fetchTicker ('MONA/JPY')
        
        //makerのほうが手数料有利のため、ベストaskより最小刻み幅分安い価格を指定
        //価格刻み最小幅はZaifではBTCは5JPY、XEMは0.0001JPY、ETHは5JPY、MONAは0.1JPY
        const ask_btc_maker = ticker_btc.ask - 5
        const ask_eth_maker = ticker_eth.ask - 5
        const ask_xem_maker = ticker_xem.ask - 1 / 10000
        const ask_mona_maker = ticker_mona.ask - 1 / 10

        //積立金額にあわせて各通貨購入数量の計算及び端数の処理
        const amount_btc = Math.round(money_per_day_btc / ask_btc_maker * 10000) / 10000
        const amount_eth = Math.round(money_per_day_eth / ask_eth_maker * 10000) / 10000
        const amount_xem = Math.round(money_per_day_xem / ask_xem_maker * 10) / 10
        const amount_mona = Math.round(money_per_day_mona / ask_mona_maker * 10) / 10
        
        //年月日&日時の取得
        const today = new Date()
        
        //確認のための出力
        console.log(today)
        console.log(ticker_btc.ask, ticker_eth.ask, ticker_xem.ask, ticker_mona.ask)
        console.log(ask_btc_maker, ask_eth_maker, ask_xem_maker, ask_mona_maker)
        console.log(money_per_day_btc, money_per_day_eth, money_per_day_xem, money_per_day_mona)
        console.log(amount_btc, amount_eth, amount_xem, amount_mona)
        
        //指値注文実行と確認のための出力(MONAは購入は現在Zaifでは不可のためコメントアウト)
        console.log (zaif.id, await zaif.createLimitBuyOrder ('BTC/JPY', amount_btc, ask_btc_maker))
        console.log (zaif.id, await zaif.createLimitBuyOrder ('ETH/JPY', amount_eth, ask_eth_maker))
        console.log (zaif.id, await zaif.createLimitBuyOrder ('XEM/JPY', amount_xem, ask_xem_maker))
        //console.log (zaif.id, await zaif.createLimitBuyOrder ('MONA/JPY', amount_mona, ask_mona_maker))
        
        //次回積立タイミングまで待機
        await sleep(interval)
    }
}) ();

次に、apiKey: ”, secret:”のシングルクオーテーションの中に、Zaif取引所にて設定したAPIの情報を記述してください。今回のAPIには、info、trade、idあたりの権限が必要だと思いますので、それら権限は、Zaif取引所でのAPIの設定であらかじめ付与しておきましょう。

APIの情報の反映が終わったら、次は積立金額や、各通貨毎の積立比率を設定しましょう。例として一月4万円で、BTC、ETH、XEMそれぞれ1/3ずつの割合で積立る設定がソースコード中には記載されています。これを適宜、自分の積立たい金額や割合に設定しましょう。注意点としては、金額が少なすぎると、最低発注単位を下回る可能性があることです。(特にBTCは注意。)ここは、自分で色々計算して考えてみてください。

上記のようにAPI情報の記述と、積立金額等の設定が終わったら、ファイルを保存しましょう。その際、Windowsのメモ帳等をお使いの方は、単純な上書き保存ではなく、「名前をつけて保存」から、ファイルの種類が「すべてのファイル」、文字コード「UTF-8」となっていることを確認して保存するよう注意してください。(プログラミング経験のある方は、普段お使いのエディタでUTF-8で保存して頂ければよいと思います。)

プログラムの実行

いよいよ自動積立プログラムの起動です。コマンドプロンプトに戻ると、おそらく既にabc2p.jsファイルが配置されているフォルダに移動済みだと思いますので、コマンドプロンプト上でそのまま「node abc2p.js」コマンドを実行します。実行して次のような結果になると成功です。このまま放置すると、24時間毎に自動的に設定した買付注文が出されます。

2018-12-09T02:26:30.785Z
384940 10275 8.02 null
384935 10270 8.0199 -0.1
438.3561643835616 438.3561643835616 438.3561643835616 0
0.0011 0.0427 54.7 -0
zaif { info:
   { success: 1,
     return:
      { received: 0,
        remains: 0.0011,
        order_id: 393265976,
        funds: [Object] } },
  id: '393265976' }
zaif { info:
   { success: 1,
     return:
      { received: 0,
        remains: 0.0427,
        order_id: 30301469,
        funds: [Object] } },
  id: '30301469' }
zaif { info:
   { success: 1,
     return:
      { received: 0,
        remains: 54.7,
        order_id: 393265979,
        funds: [Object] } },
  id: '393265979' }

少し解説します。

1行目に年月日&日時が表示されています。後でこれを見れば、いつどのような買付がされたかコマンドプロンプトの表示からわかります。ただし、この日時は、GMT0の時刻が表示されており、日本時間に合わせるには、9時間足さなければなりません。少しわかりにくいですがご容赦ください。

2行目に各通貨のベストASKが表示されています。

3行目は実際に買い注文を入れる価格が表示されています。ベストASKそのものの価格で買い注文を入れないのは、Zaif取引所ではmaker手数料がtaker手数料に比べ優遇されているからです。

4行目は各通貨毎に日本円で何円分の買い注文を入れるかの金額が表示されています。

5行目は4行目の日本円と3行目の各通貨の買付け価格から計算した各通貨の買付け数量が表示されています。

6行目以降は、APIを通じて出した買付け注文のリクエストに対する応答が表示されています。successの値が1であれば、無事APIを通じて買付け注文を出せているということです。ただし、約定するかどうかはZaif取引所での板状況次第であり、本来であれば、各オーダーを監視し、何分以上約定しない場合は、既存のオーダーを取り消して、異なる価格での買付け注文をリクエストする等の手順が必要かもしれません。(今回のプログラムではそこまでの作りこみはされていませんので、ご注意ください。)

ちなみに、このままだと、いつまでもこれが実行され続けます。辞めるときにはコマンドプロンプトの画面をアクティブにして「Ctrl」キーと「C」キーを同時に押すとプログラムを停止させることができます。

はまりやすいところ

APIに適切な権限が必要

infoだけでなく、tradeが必要です。もしかするとidも必要かもしれません。idの必要性の有無は未検証です。

ZaifでのBTCの最低購入数量の制約

ZaifでのBTC最低購入数量は、0.001以上でした。これは、現在のBTC価格にして、約400円くらいであり、12,000円/月以上の積立でないと、BTCの毎日積立はできないことになります。これは結構大きな金額で、微妙な仕様だな…と正直思ってしまいました。

Zaif取引所の価格推移次第では約定されない可能性もある

指値注文なので、この問題は避けて通れません。成行注文だとこの問題はないのですが、成行注文は必然的にtaker取引となり手数料が不利な上、そもそもZaif取引所で直接注文を入れても、成行注文は規制されていることが良くあるので、できるだけ成行注文は避けたほうが良いです。本来ならば、約定状況を各オーダー毎に監視して、約定しない時間が**分以上でオーダー出しなおすなどの対応が理想ですが、今回作成したプログラムではそこまでの機能は入っていません。ご容赦ください。

所感

システム的な話

ccxtの優秀さ

実際にやってみて、ccxtというnpmパッケージの優秀さに驚愕しました。取引所APIを介して買付け注文を出すのは、ゼロからプログラミングするとかなり大変なプログラミングになってしまうのですが、ccxtだと非常にシンプルに書けて感動しました。

対応している取引所も数多く、日本のAPIが使えるメジャーな取引所はほぼ網羅されている印象です。自分自身、自動積立以外にも、取引所間の価格差を利用した自動裁定取引ツールを作って運用してみたいと思っており、ccxtを使って開発を進めてみたいと思いました。

同期、非同期の概念は難しい

今回、Node.jsのプログラムにおいて、上記概念が必要な箇所にぶつかったのですが、とりあえず動くプログラムにはなったものの、ここに対する理解は未だ曖昧なままだな…というのが正直なところです。ここはさらに勉強して理解を深めていきたいと思いました。

金融サービスの未来

取引所APIの開放、証券のトークン化、そしてDAppsを通じた証券取引

今回、取引所の中でユーザーの手の届かないところで実行されていた自動積立サービスを、拙いながらも自作して、類似のサービスを利用することができる状況になりました。

自身がメインの資産形成と考えている株式ETFや投資信託の購入や積立でも、取引所APIの開放があれば、取引の自由度が良い意味で上がり、より自由度の高い金融サービスをエンドユーザーが利用できる可能性を感じました。

既に、大手企業同士の間では、APIを通じた情報の取得などは始まっていると思いますが、エンドユーザー自身が利用できるAPIの開放や、証券のトークン化、究極的にはDAppsを通じた証券取引などにより、個人投資家が今以上に良い金融取引の選択肢を持ちながら資産形成に向き合える未来がくることに期待しつつ、今後も色々な取り組みを続けていこうと思います。

長文、お付き合いありがとうございました。

こんな記事も書いています。

年初の仮想通貨暴落後、一時期価格が持ち直していたころに書いた記事です。その後Zaifハッキング事件もあり、当時の束の間の楽観的ムードはもはや消し飛んでしまいました。個人的には、まだ、仮想通貨には期待しているのですが、資産形成手段としては初心者向けではなく、万人にお勧めできるものではないのは間違いないところです。

仮想通貨が価格上昇中?でも投資の第一歩はインデックス投資をオススメします。
仮想通貨の価格上昇が最近1週間くらい継続しています。個人的にはそこまでインパクトのあるニュース等があったわけではないと思うのですが、短期的な...

自分自身の資産形成の中核は、仮想通貨ではなく、株式市場に幅広く分散投資するインデックス投資です。インデックス投資は一見ささやかなリターンしかもたらさない、退屈なもののように感じられるかもしれません。しかし、長期で見ると確かな力を持っていると思います。

インデックス投資の退屈さがもたらす人生におけるメリット
インデックス投資は退屈です。自動積立を設定していると、日々やるべきことはほとんどありません。そんなので本当にいいの?と思う方もいらっしゃるか...

2018年も終わりに近づいてきましたが、全てが右肩上がりでイージーな2017年の相場と違い、上下動の激しい波の中に終わりの始まりが感じられる相場だったな…と感じます。金融危機がいつくるかは誰にもわかりませんが、金融危機で各種資産を狼狽売りせずすむよう、資金面も、精神面も防衛力を高めておきたいですね。

金融危機前夜の雰囲気が強まっているように感じるが結局のところどうなのだろう?
経済状況は日々刻々と目まぐるしく変わります。昨年(2017年)は、力強く継続的に右肩上がりする市場だったのですが、今年(2018年)は、それ...