仮想通貨の自動売買をCoincheckで行うには?

暗号資産(仮想通貨)取引の最も大きな特徴は「24時間365日取引可能」である点です。とりわけシステムトレードを行う上で全自動の自動売買が可能であれば、これほど適した市場は他にはありません。ここではRuby・Pythonプログラムのサンプルとともに、Coincheckでの暗号資産(仮想通貨)の自動売買方法を見てみましょう。

仮想通貨の自動売買の魅力

仮想通貨取引の特徴のひとつが「24時間365日」取引可能であるという点です。株式市場や為替市場であれば基本的に取引可能なのが平日のみですから、全自動で自動売買ができるのであれば仮想通貨市場はとても魅力的です。

また、仮想通貨といえば大きなボラティリティが特徴です。価格の変動こそが自動売買の利益の源泉となりますからボラティリティは重要です。これだけ短期間に価格が大きく動く資産はそう多くありません。

自動売買の仕組み

自動売買とは

ここでいう自動売買とは、システムが自動で売買指値を決め、注文から決済まで全てシステムが行い、人間が行うことはシステムのON・OFFのみという完全な自動売買です。

自動売買に必要なものといえば、

  1. 情報取得、売買注文を機械的に行える仕組み
  2. 売買ロジックの検証(バックテスト)が行える仕組み

が、欲しいところです。

「1」については、仮想通貨を取り扱う各業者が提供するAPIを利用することで解決できます。例えばCoincheckであれば、こちらにAPIのソースが記載されています。

「2」については、株式やFXでは多く存在していますが、仮想通貨ではあまり充実していない状況です。株価や為替は情報ベンダー(例えば日経平均なら日経やQuick社など)が価格情報を公開していますが、仮想通貨はそもそも業者ごとに価格が異なるので仕方ありません。

自動売買の考え方

実は自動売買プログラムは市販のものが提供されています。例えば「QUOREA」「コインネオ」が有名で、マイナーなものだと「マネコ」「CoinTrader」「CRYPTOTRADER」「bittrade24」「COIN FX 365(提供は終了)」などがあります。

ツールコスト対応業者通貨ペア特徴評価
QUOREA無料Liquid・ZaifBTCリスクとリターンの予想値が可視化
でき、独自ボット作成が可能
コインネオ3万円/月bitFlyer・Liquid・
Coincheck・Zaif・
bitbank・BTCBOX
BTCAI活用型の裁定取引がメイン
マネコ無料LiquidBTC・
ETH
優秀なトレーダーをフォロー
する形で取引する(提供終了)
CoinTrader1,200円〜/月38ヶ所2,500以上対応取引所・対応通貨ペアが国内最大
CRYPTOTRADER0.0024BTC〜/月13ヶ所1,000以上海外の自動売買プラットフォーム
bittrade2426万円
※購入
bitFlyer・Liquid・
Coincheck
BTC仮想通貨の裁定取引ツール
COIN FX 365(提供終了)

しかし市販のプログラムは「使える仮想通貨の取引所・販売所がツールに対応しているところに限られる」「利用料が高額」「カスタムしにくい」などのデメリットが大きく、ここでは自前で作ることを考えていきましょう。

自動売買システムを作るにあたり、まずはどのようにイベントを起動するかを考えなければなりません。イベント起動とは、「どのようなトリガーでプログラムを動かすのか?」ということです。

ざっくりいうと、イベント起動の方法としては

  • タスクスケジューラやcronを用い、プログラムを定期的に実行
  • ループ処理をエンドレスに行い、処理を繰り返し実行

の2通りの実装方法があると思います。前者ではWindowsならタスクスケジューラを使えば簡単に実装できそうですが、自身の環境により利用可否が異なります。今回は後者のようにループ処理を延々と続ける方法で実装することを考えてみましょう。

自動売買ができる業者

上記を踏まえ、どの業者を使っていくか考えてみましょう。

まず国内業者でAPIを公開しているのは以下に挙げたものです。(BITPointは新規口座開設が停止)

業者使える言語日本語対応
bitbankJavascript, Java, Python, Ruby
bitFlyerJavascript, Java, Python, Ruby
BITPointJavascript×
BTCBOXJavascript×
CoincheckJavascript, Java, Python, Ruby
DeCurretJavascript, Python, Ruby×
GMOコインJavascript×
Huobi JapanJavascript×
Liquid by FTXJavascript, Python, Ruby×
Zaif ExchangeJavascript×

さて、自動売買を行う上で考えておきたいのが、取引コストです。自動売買では、少額の利益を取引回数によって積み上げていく戦略を取ることになります。必然的に取引回数が多くなりますから、より取引コストが低い方法を採用することになります。

ここでは取引コストが事実上存在しない、Coincheckのビットコイン現物の取引所取引を考えていきましょう。レバレッジ取引では建玉手数料が1日のポジション保有でも無視できず、取引のたびに取引手数料がかからない(Maker/Taker手数料が0)である、ある程度の流動性が存在するという点を考慮した結果です。

現物取引なら建玉手数料はかかりません。Coincheckであれば取引手数料がかからない(Maker/Taker手数料が0)ですし、ビットコインならば現物で取引所取引が存在しある程度の取引量が存在するというメリットがあるからです。

Coincheckの口座をまだ開設していない方はこちらから申請することができます。

Coincheck 公式サイト

Coincheckが選ばれる理由や評判、メリット・デメリットとは?
Coincheckは暗号通貨取り扱い会社の中でもっとも有名な業者のひとつです。一度は不正アクセスによる流出を経験しましたがセキュリティは大幅に改善し、今ではCoincheckは国内業界大手の会社です。筆者がCoincheckを実際に利用し...

Coincheck自動売買の実装

APIキーの取得

まずはAPIキーを取得していきますが、その前にここまであまり説明していなかった点について説明しましょう。そもそもAPIにはPublic APIとPrivate APIの2種類があります。

Public APIとはアカウントに紐づかない、他の人も参照している情報を見るために利用するものです。例えば取引所の注文状況や公開されている取引の履歴、板情報などが該当します。

一方、Private APIとはアカウントなどに紐づく、自分しか見ることのできない情報を操作するために利用するものです。例えば取引所での新規注文や注文キャンセル、自分の残高などを確認することなどが該当します。

つまり自動売買のためには、Private APIを利用することが必要です。そのためには個人のアカウント画面からAPIキーを取得することが必要です。

CoincheckのAPIキー取得方法

APIキーは「アクセスキー」と「シークレットキー」の2つに分けられ、どちらも新たに取得する必要があります。

CoincheckでAPIキーの取得をしたことがない方はここから紹介するイメージを参考にしてみてください。以下のイメージは英語ですが、登録時に日本語登録していればちゃんと日本語で表示されますから安心してくださいね。

まず、ページ上部の「設定」をクリックします。一番右のSetteing(日本語では「設定」)です。

「設定」ページから、「APIキー」をクリックしましょう。

「新たにAPIキーを追加する」をクリックします。一番下の「Add another API key」のところです。

下記のようにAPIキーの権限にチェックをつけて選択します。日本語だと「新規注文」「未決済の注文一覧」「注文のキャンセル」「取引履歴」「残高」です。

必要な権限にチェックを入れたら、パスワードを入力して「OK」をクリックします。すると、以下の用に新しいAPIキーが表示されます。デフォルトではシークレットキーは表示が隠されています。

繰り返しますが、上記に表示されるAPIキーは「アクセスキー」ですので、「シークレットキー」はクリックして表示させてくださいね。

Ruby

まずは指値注文するためのスクリプトを書いてみましょう。

USER_KEYに取得した「アクセスキー」、USER_SECRET_KEYに取得した「シークレットキー」をセットしてください。

require 'ruby_coincheck_client'
USER_KEY = "アクセスキー"
USER_SECRET_KEY = "シークレットキー"
BASE_URL = "https://coincheck.jp/"
SSL_FLAG = true
cc = CoincheckClient.new(USER_KEY,
                         USER_SECRET_KEY,
                         {base_url: BASE_URL,
                          ssl: SSL_FLAG})
loop do
  response = cc.read_positions(status: "open")
  positions = JSON.parse(response.body)["data"]
  # step1 btc_jpy 595,000円で0.01BTCロング発注
  if positions.empty?
    # ポジションがない場合
    response = cc.create_orders(order_type: "leverage_buy",
                                rate: 595000,
                                amount: 0.01,
                                market_buy_amount: nil,
                                position_id: nil,
                                pair: "btc_jpy")
  else
    # ポジションがある場合
    # step2 step1のポジションを持っていたら600,000円で決済注文
    response = cc.create_orders(order_type: "close_long",
                                rate: 600000,
                                amount: positions.first["amount"],
                                market_buy_amount: nil,
                                position_id: positions.first["id"],
                                pair: "btc_jpy")
    # 1秒待機
    sleep 1
  end
end

これを次のようにコンソールで実行することで、ビットコインに対し595,000円でロングを持ち、600,000円で決済(売却)することを繰り替えす自動売買ができます。

$ ruby first_trade.rb

停止させたくなったら「Ctrl-C」「Ctrl-B」「Ctrl-Break」「Ctrl-Alt-Del」「Esc」「Ctrl-Esc」などで抜け出します。または、Windowsであればタスクマネージャーを起動し「ruby.exe」のプロセスを終了すると良いでしょう。

いよいよボリンジャーバンドを使ったシステムを組んでみましょう。Coincheckのgemにはテクニカル分析を行うような機能はありません。別のライブラリ(例えばこちら)を探すまたは、自分で作ることになります。

以下はあくまでサンプルです。ボリンジャーバンドの正しい使い方をしておらず、この方法で取引をすることはおすすめしません。

require 'ruby_coincheck_client'
require 'bigdecimal'
require './technical_analysis_services/bollinger_band_service'
USER_KEY = "your user key"
USER_SECRET_KEY = "your secret_key"
INTERVAL_TIME = 1
BASE_URL = "https://coincheck.jp/"
SSL = true
cc = CoincheckClient.new(USER_KEY,
                         USER_SECRET_KEY,
                         {base_url: BASE_URL,
                          ssl: SSL})
bollinger_band_service = BollingerBandService.new()
loop do
  # 現在のレートを確認
  puts "count:#{count}"
  rate_res = cc.read_ticker
  btc_jpy_bid_rate =  BigDecimal(JSON.parse(rate_res.body)['bid']) # 現在の買注文(bid)
  btc_jpy_ask_rate =  BigDecimal(JSON.parse(rate_res.body)['ask']) # 現在の売注文(ask)
  btc_jpy_rate = (btc_jpy_bid_rate + btc_jpy_ask_rate)/2
  bollinger_band_service.set_rate(rate: btc_jpy_rate)
  # ポジションの確認
  response = cc.read_positions(status: "open")
  positions = JSON.parse(response.body)["data"]
  # 証拠金の確認
  response = cc.read_leverage_balance
  margin_available = JSON.parse(response.body)['margin_available']['jpy']
  if positions.empty?
    # ポジションがない場合
    result = bollinger_band_service.check_signal_exec(btc_jpy_rate)
    # ボリンジャーから注文内容を決定
    if [BollingerBandService::PLUS_SIGNAL_LV_3, BollingerBandService::MINUS_SIGNAL_LV_3].include?(result)
      if result == BollingerBandService::PLUS_SIGNAL_LV_3
        # +2σを超えた場合、逆張りでショート
        order_rate = btc_jpy_bid_rate.to_i
        order_type = "leverage_sell"
      else
        # -2σを超えた場合、逆張りでロング
        order_rate =  btc_jpy_ask_rate.to_i
        order_type = "leverage_buy"
      end
      order_amount = (margin_available / order_rate * 5).to_f.round(2)
      cc.create_orders(order_type: order_type,
                       rate: order_rate,
                       amount: order_amount,
                       market_buy_amount: nil,
                       position_id: nil,
                       pair: "btc_jpy")
    end
  else
    open_rate = positions[0]["open_rate"]
    # 1.5%以上の含み益で利確
    # -5.0%以下の含み損発生で損切り
    if positions[0]["side"] == "buy"
      gain_rate = (open_rate * 1.015).to_i
      loss_cut_rate = (open_rate * 0.95).to_i
      if gain_rate <= btc_jpy_ask_rate || loss_cut_rate>= btc_jpy_ask_rate
        # 現在の売り注文が利確金額以上なら利確
        # 現在の売り注文が損切り金額以下なら損切り
        cc.create_orders(order_type: "close_long",
                         rate: btc_jpy_ask_rate.to_i,
                         amount: positions.first["amount"],
                         market_buy_amount: nil,
                         position_id: positions.first["id"],
                         pair: "btc_jpy")
      end
    elsif positions[0]["side"] == "sell"
      gain_rate = (open_rate * 0.95).to_i
      loss_cut_rate = (open_rate * 1.015).to_i
      if gain_rate >= btc_jpy_bid_rate || loss_cut_rate <= btc_jpy_bid_rate
        # 現在の買い注文が利確金額以下なら利確
        # 現在の買い注文が損切り金額以上なら損切り
        cc.create_orders(order_type: "close_short",
                         rate: btc_jpy_bid_rate.to_i,
                         amount: positions.first["amount"],
                         market_buy_amount: nil,
                         position_id: positions.first["id"],
                         pair: "btc_jpy")
      end
    end
  end
  # INTERVAL_TIME秒だけ待機
  sleep INTERVAL_TIME
end

BollingerBandServiceについては以下を参照してください。

class BollingerBandService   # データ不足   LACK_DATA = 0   PLUS_SIGNAL_LV_3 = 1   PLUS_SIGNAL_LV_2 = 2   PLUS_SIGNAL_LV_1 = 3   MINUS_SIGNAL_LV_1 = 4   MINUS_SIGNAL_LV_2 = 5   MINUS_SIGNAL_LV_3 = 6   def initialize     @rates = []     @average_rates = []     @range = 0     # 平均     @avg = 0     @plus_one_std_dev = 0     @minus_one_std_dev = 0     @plus_two_std_dev = 0     @minus_two_std_dev = 0   end   def set_rate(rate:)     @rates.push(rate)     rates_ary_size = @rates.size     if rates_ary_size> 60
      @rates = @rates[(rates_ary_size - 60)...rates_ary_size]
      @average_rates = @rates.each_slice(6).to_a.map { |ary| ary.inject(:+)/6 }
      # 平均
      @avg = @rates.inject(:+)/@rates.size
      # 分散
      var = @rates.reduce(0) { |a,b| a + (b - @avg) ** 2 } / (@rates.size - 1)
      # 標準偏差
      sd = Math.sqrt(var)
      @plus_one_std_dev = @avg + sd
      @minus_one_std_dev = @avg - sd
      @plus_two_std_dev = @avg + (2 * sd)
      @minus_two_std_dev = @avg - (2 * sd)
    end
  end
  # 単純に現在のレートが
  def check_signal_exec(rate)
    # データ不足
    return LACK_DATA if @rates.size < 60
    if @plus_two_std_dev <= rate
      # +2σ以上
      PLUS_SIGNAL_LV_3
    elsif @plus_one_std_dev <= rate && @plus_two_std_dev> rate
      # +1σ以上、+2σ未満
      PLUS_SIGNAL_LV_2
    elsif @avg <= rate && @plus_one_std_dev> rate
      # 平均以上、+1σ未満
      PLUS_SIGNAL_LV_1
    elsif @minus_one_std_dev <= rate && @avg> rate
      # -1σ以上、平均未満
      MINUS_SIGNAL_LV_1
    elsif @minus_two_std_dev <= rate && @minus_one_std_dev> rate
      # -2σ以上、-1σ未満
      MINUS_SIGNAL_LV_2
    else
      # -2σ以下
      MINUS_SIGNAL_LV_3
    end
  end
end

ここまでできれば売買ロジックを色々なケースに対応できるよう拡張していくだけです。

Python

Pythonで記述することも可能です。USER_KEYに取得した「アクセスキー」、USER_SECRET_KEYに取得した「シークレットキー」をセットしてください。

筆者はPythonでの取引をほぼしていないので、指値取引のみ記載します。

privateAPI.py
import json
import requests
import time
import hmac
import hashlib
class Coincheck:
    def __init__(self, access_key, secret_key, url='https://coincheck.com'):
        self.access_key = access_key
        self.secret_key = secret_key
        self.url = url
     def get(self, path, params=None):
        if params != None:
            params = json.dumps(params)
        else:
            params = ''
        nonce = str(int(time.time()))
        message = nonce + self.url + path + params
        signature = self.getSignature(message)
        return requests.get(
            self.url+path,
            headers=self.getHeader(self.access_key, nonce, signature)
        ).json()
    def post(self, path, params):
        params = json.dumps(params)
        nonce = str(int(time.time()))
        message = nonce + self.url + path + params
        signature = self.getSignature(message)
        return requests.post(
            self.url+path,
            data=params,
            headers=self.getHeader(self.access_key, nonce, signature)
        ).json()
    def delete(self, path):
        nonce = str(int(time.time()))
        message = nonce + self.url + path
        signature = self.getSignature(message)
        return requests.delete(
            self.url+path,
            headers=self.getHeader(self.access_key, nonce, signature)
        ).json()
    def getSignature(self, message):
        signature = hmac.new(
            bytes(self.secret_key.encode('ascii')),
            bytes(message.encode('ascii')),
            hashlib.sha256
        ).hexdigest()
        return signature
    def getHeader(self, access_key, nonce, signature):
        headers = {
            'ACCESS-KEY': access_key,
            'ACCESS-NONCE': nonce,
            'ACCESS-SIGNATURE': signature,
            'Content-Type': 'application/json' # 必須
        }
        return headers
access_key = 'アクセスキー'
secret_key = 'シークレットキー'
# インスタンス作成
coincheck = Coincheck(access_key, secret_key)
# 595,000円の指値で0,01ビットコインを現物取引買い注文
path_orders = '/api/exchange/orders'
params = {
    "pair": "btc_jpy",
    "order_type": "buy",
    "rate": 595000,
    "amount": 0.01,
}
result = coincheck.post(path_orders, params)
print(result)

Pythonではanacondaなど数値解析のためのライブラリが用意されており、活用することでより高度な自動化を設定できるかもしれませんね。

Coincheckの口座を活用し、ぜひ仮想通貨の自動売買に役立ててみてください。Coincheckの口座は以下から開設可能です。

Coincheck 公式サイト

>> 暗号資産(仮想通貨)でアービトラージを行う方法についてはこちらの記事から

error:Content is protected !!