ビットコインの自動売買システムを作る|bitFlyer口座と連携

ビットコインを自動で売買するプログラムを作りました。

Udemyという動画学習サイトの動画を見ながら、それ通りに進めていきました。

プログラミング初心者でも大丈夫なように作ってあるのでとても分かりやすくて良い動画です。

毎日少しづつ進めて、完成した時は嬉しかったですよ〜!

儲かってはないですけどね…。

Udemyで詳しく見てみる>>Rubyで作る! ビットコイン自動売買システム

講座の対象者と必要なもの

講座の対象者は

・初歩的なPC操作の知識が必要

・bitFlyerのアカウントを持っている必要があります

・プログラミングに関してはやる気さえあれば初心者でも大丈夫です

となっていて、必要なものは

  • パソコンと
  • bitFlyerのアカウント

です。

プログラミングは初心者でも大丈夫とのことで、確かに動画を見ながら順番に作っていけば問題はないかと思います。

使用言語は『Ruby』で、Web系のシステムでよく使われてます。

ビットコインの自動売買システムを作る

動画は全部で3時間ほどあり、かなりのボリューム。

いつもYouTubeで10分15分ぐらいの動画しか観なれてない僕にはビビる長さでした。

毎日ちょっとずつ進めてトータルの作業時間は5時間ほどで完成できました。

解説動画を見ながら実際にプログラミングしていく感じで、一時停止と巻き戻し必須です。

パソコンのディスプレイが小さいとこういう時に不便ですね。

動画ではかなり初歩の初歩から説明されていて、分かりやすかったです。

必要なサービスのアカウント登録、足し算・掛け算などからなので、プログラミング未経験でもなんとかなりそうな印象でした。

ビットコイン自動売買システム
1秒に30回注文を出しているところ

1秒ごとに勝手に注文が出されるところを眺めるとシステムトレードやってる感がすごいです!

一部エラーが出て動かなかったりすることがあったので、動画を進めたり戻したりググったりと頑張りました。以下はつまずいた所です。

ちょっとつまづいた所

動画の通りに作っていけばOKですが、つまづいたところもありました。

売り買いの注文を出すとエラー

bitFlyerに注文を出すところで以下のエラーが出ました。

/home/ec2-user/environment/method.rb:99:in `+': no implicit conversion of Float into String (TypeError)

原因は関数に引数で渡した価格と注文数量が数値だからみたいです。

body部のpriceとsizeに、数値を文字列に変換するメソッドの「.to_s」を追加して解決。

    body = '{
      "product_code": "BTC_JPY",
      "child_order_type": "LIMIT",
      "side": "' + side + '",
      "price": ' + price.to_s + ',
      "size": ' + size.to_s + ',
      "minute_to_expire": 10000,
      "time_in_force": "GTC"
    }'

ボリンジャーバンドで判定してみる

せっかくなのでボリンジャーバンドの判定をシステムに組み込んでみました。

動画の最後の方で紹介されていた指標です。

ボリンジャーバンドは、相場の振れ幅(ボラティリティ)を一定期間の価格データから測定し、統計学的な観点から価格の変動範囲を予測してチャート上に表示するテクニカル指標です。

ボリンジャーバンドには1σ、2σ、3σの3本の線が上下にあり、2σのボリンジャーバンド内に株価が推移する確率は95%にもなるそう。

ボリンジャーバンド

ボリンジャーバンドについてはこちらのサイト(株の売買サインを簡単に見極めるボリンジャーバンドの使い方)が分かりやすかったです。

2σの下のバンドに近づいたらビットコインを買い、上のバンドに近づいたら売るみたいなプログラムが出来たら良さそうな気がします。

計算式

プログラムに組み込むために詳しい計算式を探していると英語のサイトが見つかりました。

これかな。

  * Middle Band = 20-day simple moving average (SMA)
  * Upper Band = 20-day SMA + (20-day standard deviation of price x 2) 
  * Lower Band = 20-day SMA - (20-day standard deviation of price x 2)
  * Middle Band = 単純移動平均線
  * Upper Band = 単純移動平均線 + (標準偏差(σ) x 2) 
  * Lower Band = 単純移動平均線 - (標準偏差(σ) x 2)

MiddleBandが上の図でいう「移動平均線」、UpperBandが2σバンドの上、LowerBandが下なのかな。

そうすると、計算に必要なのは「単純移動平均線」と「標準偏差(σ)」になります。

単純移動平均線

移動平均線は価格の平均値です。

現在価格を取得して、配列に格納し、その平均値を求める方法で計算できそうです。

  # 現在価格を取得
  price = get_price
  
  # 配列に追加
  prices.push(price)
  
  if prices.length > 20
    # 配列から一番古いものを削除
    prices.shift
    
    # 単純移動平均線
    middle_band = prices.mean

標準偏差(σ)

method.rbに以下を追加します。

class Array
  # 合計
  def sum
    reduce(:+)
  end
 
  # 平均
  def mean
    sum.to_f / size
  end
 
  # 分散
  def variance
    m = mean
    reduce(0) { |a,b| a + (b - m) ** 2 } / (size - 1)
  end
 
  # 標準偏差
  def standard_deviation
    Math.sqrt(variance)
  end
end

method.rbに追加したらbitcoin.rbで以下のようにして標準偏差が計算できます。

    # 標準偏差(σ)
    standard_deviation = prices.standard_deviation

ボリンジャーバンドもどきを算出

最終的に出来たbitcoin.rbファイルがこれ

require 'date'
require './method'

#値段を入れる配列
prices = []

# 現在価格
price = 0

# 注文数量
order_size = 0.01

# もうお金ない判定
stop_price = 25000

# 無限ループ開始
while(true)

  # 保有資産(JPY)
  jpy_amount = get_my_money("JPY")["amount"]
  # 保有資産(BTC)
  btc_amount = get_my_money("BTC")["amount"]

  # 現在価格を取得
  price = get_price
  
  # 配列に追加
  prices.push(price)
  
  if prices.length > 20
    # 配列から一番古いものを削除
    prices.shift
    
    # 単純移動平均線
    middle_band = prices.mean
    
    # 標準偏差(σ)
    standard_deviation = prices.standard_deviation
    
    # ボリンジャーバンド(σ)
    upper_bollinger_band = middle_band + standard_deviation
    lower_bollinger_band = middle_band - standard_deviation
    
    # ボリンジャーバンド(2σ)
    upper_bollinger_band_2 = middle_band + (standard_deviation * 2)
    lower_bollinger_band_2 = middle_band - (standard_deviation * 2)
    
    puts "now price : "  + price.to_s
    
    # 現在価格がボリンジャーバンドを下回ったら買い
    if (price <= lower_bollinger_band_2) && (jpy_amount > stop_price)
      puts "買い注文を発注します。"
      order("BUY", price, order_size)
      
    # 現在価格がボリンジャーバンドを上回ったら売り
    elsif (price >= upper_bollinger_band_2) && (btc_amount > 0.001)
      puts "売り注文を発注します。"
      order("SELL", price, order_size)
      
    end
    
    else
      p prices
  end
  
  sleep(1 * 60)
  
end

そもそもちゃんとボリンジャーバンドが計算されてるかも分かんないんですが、それもりもダメなところに気づきました。

このプログラムは1分ごとにビットコインの価格を取得して動いてるんですけど、これだと「20日移動平均線」どころか「20分移動平均線」という短すぎるスパンのものになっています…

ビットフライヤーのAPIは過去の価格は取れないみたいなんで、他のサービスで過去の価格を取得するやり方が良さそうですね。

プログラミングの入り口に良いと思う

儲けようと思ったら自分で色々と工夫しないといけないですね…

とはいえ、ちょっとそれらしい自動売買システムができたのは嬉しいところ。

プログラミングの勉強は「やりたいことがある」とかなにかしら目的がないと続きにくいので、

  • 動画を見ながら進めるだけで
  • ビットコインを自動売買するシステムが完成する

というところはモチベーションが維持できて良かったです!

Udemyは頻繁にセールをやっているので、セール時を狙って動画教材を購入するとお得です。時に90%OFFなどもやってます。

Udemyで詳しく見てみる>>Rubyで作る! ビットコイン自動売買システム