PowerShellによる仮想通貨システムトレードの始め方(PowerShellの利点とAPIの種類)

窓使いのCoin Trading System -Vol.1

一時は200万円以上の値段を付けたビットコインに代表される仮想通貨ブーム。様々な事件、出来事が起きた中でも今なお市場は活況です。そんな仮想通貨の世界でも、ほんの少しプログラムが書ける人が楽をできる時代となっています。いわゆる、仮想通貨のシステムトレードです。

株式、FXなどでは当たり前のように行われているシステムトレードは、仮想通貨の世界においても有効な取引手段となっています。システムトレードといっても、必ずしもすべて自動的にトレードを重ねて利益を積み上げていくということだけではなく、トレードの判断となる情報をシステマチックに収集して分析を行い、トレードを優位に進めるための手助けになることもシステムトレードと考えています。

この連載では、自動取引、いわゆるbotを作ることだけでなく、テクニカル分析の元となる材料や様々な情報の集め方も紹介していく予定です。仮想通貨のシステムトレードでは、Pythonという言語が主流になりつつありますが、長年Windows使いとして生業を立ててきた身としては、あえてWindowsに標準搭載されているPowerShellで仮想通貨のシステムトレードを実現するべく、いざチャレンジします!

前提・条件

  • 開発実行環境は、24時間システムを稼働することも考慮し、「お名前.comデスクトップクラウド」の仮想マシンを使って作成~稼働まで行っています。
  • PowerShellの基本的な文法、使い方については解説を省略しています。
  • APIを公開している仮想通貨取引所の口座開設が完了しているものとします。口座開設方法については省略しています。
  • システムトレードを行うことによって必ずしも利益が出るという保証はありません。
  • .NET Framework で TLS1.1 および 1.2 を有効化する

PowerShellで使用される暗号化プロトコルは以下で確認することができます。

[Net.ServicePointManager]::SecurityProtocol
Ssl3, Tls

既定ではSSL3、TLS(1.0)が利用可能となっています。
しかし最近では暗号化プロトコルにTLS 1.2を必須とするサイトが増えてきており、仮想通貨取引所のAPIも同様となっています。既定の設定では.NET Frameworkを利用しているInvoke-WebRequestコマンドを実行するとエラーとなる場合があります。Invoke-WebRequestコマンドでTLS 1.2を利用するようにあらかじめ設定をしておきましょう。

1つ目の方法としてはInvoke-WebRequestコマンドを呼び出す前にTLS 1.2で通信することを明記します。こちらはスクリプト毎にその都度明記する必要があります。

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$res = Invoke-RestMethod $Url -Method POST -Headers $Header -Body $Body -ContentType "application/json"

もう1つの方法としては、以下のコマンドを実行して、レジストリでTLS 1.2で通信を既定値として設定しておきます。

Set-ItemProperty -Path HKLM:\\SOFTWARE\Microsoft\.NETFramework\v4.0.30319 -Name SchUseStrongCrypto -Value 1"

いずれかの対策を事前に行うことで、Invoke-WebRequestコマンドでAPIを利用する場合のエラーを回避することが可能です。

参考:.NET Framework で TLS1.1 および 1.2 を有効化する方法

PowerShellで開発を行うことの利点

PowerShellはWindowsに標準で搭載されているシェル&開発言語で、PowerShell ISEというエディタツールもあらかじめインストールされているので手軽に開発を始めることができます。特別に開発環境を整える必要はなく、今回は「お名前.comデスクトップクラウド」のPowerShell ISEを利用して開発を進めていきます。

基本的に各取引所はREST(REpresentational State Transfer)形式のWebサービスとしてAPIを公開しています。REST APIではJSON形式のテキストデータをやりとりすることで情報を送受信する仕様となっています。PowerShellでは、文字列としてのJSON形式のデータを自動的にPSCustomObjectとし読み込んで取り扱うことのできる便利な機能が用意されています。オブジェクトとして扱えることで、変数に格納したり、汎用的なPowerShellのコマンドをそのまま再利用することも可能となるので、開発効率が格段にアップします。

デスクトップクラウド上でPowerShell ISEを使って開発開始

前置きはこのくらいとして、まずはAPIを利用したサンプルを紹介しましょう。各取引所のビットコインの板情報を取得して最新の売買値情報を表示しています。

Function Get-Prices(){
    $Sites = @()

    $objPs = New-Object PSCustomObject
    $objPs | Add-Member -NotePropertyMembers @{Name = "BTCBOX"}
    $objPs | Add-Member -NotePropertyMembers @{TickerUrl = "https://www.btcbox.co.jp/api/v1/depth/"}
    $Sites += $objPs

    $objPs = New-Object PSCustomObject
    $objPs | Add-Member -NotePropertyMembers @{Name = "bitbank"}
    $objPs | Add-Member -NotePropertyMembers @{TickerUrl = "https://public.bitbank.cc/btc_jpy/depth"}
    $Sites += $objPs

    $objPs = New-Object PSCustomObject
    $objPs | Add-Member -NotePropertyMembers @{Name = "bitFlyer"}
    $objPs | Add-Member -NotePropertyMembers @{TickerUrl = "https://api.bitflyer.jp/v1/ticker"}
    $Sites += $objPs

    $objPs = New-Object PSCustomObject
    $objPs | Add-Member -NotePropertyMembers @{Name = "FISCO"}
    $objPs | Add-Member -NotePropertyMembers @{TickerUrl = "https://api.fcce.jp/api/1/depth/btc_jpy"}
    $Sites += $objPs

    $objPs = New-Object PSCustomObject
    $objPs | Add-Member -NotePropertyMembers @{Name = "QUOINE"}
    $objPs | Add-Member -NotePropertyMembers @{TickerUrl = "https://api.quoine.com/products/5/price_levels"}
    $Sites += $objPs

    $objPs = New-Object PSCustomObject
    $objPs | Add-Member -NotePropertyMembers @{Name = "Zaif"}
    $objPs | Add-Member -NotePropertyMembers @{TickerUrl = "https://api.zaif.jp/api/1/depth/btc_jpy"}
    $Sites += $objPs


    $Prices = @()

    ForEach($Site In $Sites){

        $SiteName = $Site.Name

        $res = Invoke-RestMethod $Site.TickerUrl -Method GET

        [int]$AskPrice = 0
        [int]$BidPrice = 0
        [double]$AskSize = 0
        [double]$BidSize = 0

        Switch ($SiteName)
        {
            "BTCBOX" {
                $AskPrice = $res.asks[$res.asks.Count-1][0]
                $BidPrice = $res.bids[0][0]
                $AskSize = $res.asks[$res.asks.Count-1][1]
                $BidSize = $res.bids[0][1]
            }
            "bitbank" {
                $AskPrice = $res.data.asks[0][0]
                $BidPrice = $res.data.bids[0][0]
                $AskSize = $res.data.asks[0][1]
                $BidSize = $res.data.bids[0][1]
            }
            "bitFlyer" {
                $AskPrice = $res.best_ask
                $BidPrice = $res.best_bid
                $AskSize = $res.best_ask_size
                $BidSize = $res.best_bid_size
            }
            "FISCO" {
                $AskPrice = $res.asks[0][0]
                $BidPrice = $res.bids[0][0]
                $AskSize = $res.asks[0][1]
                $BidSize = $res.bids[0][1]
            }
            "QUOINE" {
                $AskPrice = $res.sell_price_levels[0][0]
                $BidPrice = $res.buy_price_levels[0][0]
                $AskSize = $res.sell_price_levels[0][1]
                $BidSize = $res.buy_price_levels[0][1]
            }
            "Zaif" {                
                $AskPrice = $res.asks[0][0]
                $BidPrice = $res.bids[0][0]
                $AskSize = $res.asks[0][1]
                $BidSize = $res.bids[0][1]
            }
        }

        $objPs = New-Object PSCustomObject
        $objPs | Add-Member -NotePropertyMembers @{Name = $Site.Name}
        $objPs | Add-Member -NotePropertyMembers @{AskPrice =  $AskPrice}
        $objPs | Add-Member -NotePropertyMembers @{AskSize = $AskSize.ToString("0.00000")}
        $objPs | Add-Member -NotePropertyMembers @{BidPrice = $BidPrice}
        $objPs | Add-Member -NotePropertyMembers @{BidSize = $BidSize.ToString("0.00000")}
        $Prices += $objPs
    } 

    $Prices | FT   
}

結果

PS > Sample_01.ps1

Name AskPrice AskSize BidPrice BidSize
---- -------- ------- -------- -------
BTCBOX 812522 4.72090 811820 0.05000
bitbank 816179 0.00710 816023 0.03530
bitFlyer 814320 0.37000 813521 0.10000
FISCO 814660 0.00490 814620 0.22000
QUOINE 815300 0.04000 814594 0.01196
Zaif 814660 0.00490 814620 0.22000

取引所ごとの細かい仕様は後述することとして、ここではポイントとなる部分を解説しておきます。

41: $res = Invoke-RestMethod $Site.TickerUrl -Method GET

各取引所のREST APIからInvoke-RestMethodコマンドの「GET」メソッドで情報を取得しています。この行の直後にブレークポイントを設定して、変数$resに格納されているデータをGetTypeコマンドで確認してみましょう。APIから取得した情報がPSCustomObjectとして格納されているのが確認できます。

PS > Sample_01.ps1
ヒット 'Sample_01.ps1:43' の行のブレークポイント
[DBG]: PS >> $res.GetType()

IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True False PSCustomObject System.Object

さらに変数$resの中身を確認してみると、asksとbidsの要素に分かれて値が確認できます。

[DBG]: PS >> $res

asks bids
---- ----
{19999999 2.982, 14700000 0.05, 9580530 0.004, 8374208 0.005...} {798380 0.0...

要素名として$res.asksを指定することで、配列として格納されたビットコインの価格と注文量が確認できます。

[DBG]: PS >> $res.asks

19999999
2.982
14700000
0.05
9580530
0.004
8374208
0.005
5000000
0.1
4600000
2
4200000
1.5

取引所ごとに要素名は異なる部分もありますが、ほぼ同様の仕様で最新の板情報を取得することができるようになっています。PSCustomObjectとして取り扱えるので、要素名としてask値(売値)、bid値(買値)、注文量をテーブル形式で表示することも簡単に行うことができます。

仮想通貨取引の基本としては、安く買って高く売ることで利益を出すことが目的となります。同じ数量のビットコインを購入するにしても、どの取引所を選択するかによってタイミング次第では数万円の価格差が発生している場合もあります。このサンプルで取得した各取引所のビットコインの板情報は、裁定取引と呼ばれる価格差を利用して利益を出すことのできるトレード手法の重要な情報となります。売買を自動化するだけなく、このような価格情報や取引情報などをAPIを利用して情報収集し、データとして蓄積することもシステムトレードを構成する一つの重要な要素となります。PowerShellを利用することでこれらのデータをデータベースに蓄積し、普段使い慣れたExcelに読み込んで分析するといったことも簡単にできるようになります。Windowsに標準で搭載されている言語ということで、Microsoft Office製品や他のシステム製品と連携がしやすいといった点もPowerShellを利用することの利点となります。

APIを公開している国内仮想通貨取引所

システマチックに仮想通貨の取引を行うには、仮想通貨取引所が公開しているAPI(Application Programming Interface)を利用することになります。取引量の多い海外の取引所もAPIを公開しているところが数多くありますので、システムトレードを進めていく過程ではいずれ選択肢の一つになるものと考えられますが、使い方やサポートを考慮し、まずは日本国内の仮想通貨取引所を選択してシステムトレードを始めてみましょう。

システムトレードを行う上で注意しなければいけないのが、仮想通貨の売買にともなう手数料です。取引所や売買する仮想通貨、現物取引かFXなのかなどによって手数料は異なります。一度の取引で大きな利益を得られる場合はそれほど気になることもありませんが、取引を繰り返して小さな利益を積み上げていくような場合は、取引手数料を十分考慮しておく必要があります。

国内においてAPIを公開している金融庁登録事業者の取引所は以下となります。APIのリファレンスと取引手数料のページも併せて記載してあります。取引所ごとにアップデートが時々ありますのでチェックしておきましょう。
BITPointはAPI経由の取引はサポート対象外となるため除外しています。

APIを公開している日本国内の金融庁登録事業者

BTCBOXWebサイトAPIリファレンス手数料
bitbankWebサイトAPIリファレンス手数料
bitFlyerWebサイトAPIリファレンス手数料
FISCOWebサイトAPIリファレンス
QUOINEXWebサイトAPIリファレンス手数料
ZaifWebサイトAPIリファレンス手数料

APIの種類

取引所ごとに名称は異なりますが、APIの種類は大きく分けて2つあります。1つはアカウントの認証を必要とせず一般的に公開されている「Public API」、もう1つは取引所のアカウントに関連付けられた「Private API」です。「Public API」は主に、仮想通貨ごとの相場情報や価格情報などを取引所のアカウントの有無に関わらず取得することが可能です。「Private API」はユーザーの資産状況、注文状況を取得することが可能です。また、売買の注文も「Private API」を利用することになります。

APIの種類用途
Public API仮想通貨の相場情報や価格取得。誰でも利用可能。
Private API資産状況や注文状況を取得。売買の注文を行う。アカウント保有者のみ利用可能。

APIを利用することで、短時間に取引を何度も繰り返したり、独自のルールに基づいて売買を24時間自動的に行うなど、人の手では通常行えないような取引が可能となります。ただし、各取引所によってAPIのパフォーマンスにばらつきがあり、ある取引所では1分間に100回以上の注文を出せる一方で、ある取引所では市場が過熱状態となるとAPIからの注文がなかなか成立しないといった事も多々あります。システムによる取引とはいっても、取引所ごとのAPIのクセや特色がかなり影響してくるのもシステムトレードを行う上では考慮しておく必要があります。自身のトレードスタイルに最適な取引所を選択し、そこにマッチしたシステムを作成してトレードを進めていくことが重要となります。

次回以降、各取引所の主要なAPI機能を、サンプルを使いながら解説していきます。APIの使い方がある程度分かってきたところで、様々なシステムトレードのスタイルやロジックなどを紹介し、それをどのようにPowerShellのコードに落とし込んでいくか、というところまで解説する予定です。

仮想通貨のシステムトレードでなかなかPowerShellのサンプルコードが少ない中、少しでも同じ志の方々のお役に立てれば幸いです。

著書の紹介欄

Hyper-Vで本格的なサーバー仮想環境を構築。仮想環境を設定・操作できる!

できるPRO Windows Server 2016 Hyper-V

◇Hyper-Vのさまざまな機能がわかる ◇インストールからの操作手順を解説 ◇チェックポイントやレプリカも活用できる Windows Server 2016 Hyper-Vは、仮想化ソフトウェア基盤を提供する機能であり、クラウドの実現に不可欠のものです。 本書では、仮想化の基礎知識から、Hyper-Vでの仮想マシンや仮想スイッチの設定・操作、プライベートクラウドの構築、Azureとの連携などを解説します。

初めてのWindows Azure Pack本が発売

Windows Azure Pack プライベートクラウド構築ガイド

本書は、Windows Azure PackとHyper-Vを利用し、企業内IaaS(仮想マシン提供サービス)を構成するための、IT管理者に向けた手引書です。試用したサーバーは、最小限度の物理サーバーと仮想マシンで構成しています。Windows Azure Packに必要なコンポーネントのダウンロード、実際にプライベートクラウド構築する過程を、手順を追って解説しています。これからプライベートクラウドの構築を検討するうえで、作業負担の軽減に役立つ一冊です。

ブログの著者欄

樋口 勝一

GMOインターネットグループ株式会社

1999年6月GMOインターネットグループ株式会社に入社。Windows Serverをプラットフォームとしたサービス開発から運用・保守まで幅広く担当。講演登壇や出版、ネット記事連載などでマイクロソフト社と強い信頼関係を構築。「マイクロソフトMVPアワード」を15度受賞し、インターネットソリューションのスペシャリストとして活躍。

採用情報

関連記事

KEYWORD

採用情報

SNS FOLLOW

GMOインターネットグループのSNSをフォローして最新情報をチェック