Python×ビットコイン自動売買

#13 Python×ビットコイン自動売買 | 自動売買に必要なロジックを作成してみよう!

create-automatic-trading-system

こんにちは、はやたす(@hayatasuuu )です。

今回の講義では、自動売買に必要なロジックを作成していきたいと思います。

前回の記事はこちら

create-coincheck-class-object-top
#12 Python×ビットコイン自動売買 | クラスを作成してコードを読みやすくしよう!こんにちは、はやたす(@hayatasuuu )です。 今回の講義では、自動売買で使うためのクラスを作成していきたいと思います。 ...

そのためにも、まずはどのような自動売買ロジックを組んでいくのか紹介します。
そのあと、ビットコイン価格を取得し続けて、「買い」か「売り」を判定するところまで紹介します。

実際の売買については、次回の講義で紹介していくので、まずは取引する手前のコードまで作成していきましょう!

コードを作成するにあたり、前回のmain.pyを引き続き使っていきます。

コードを確認する

import configparser

from coincheck import Coincheck

conf = configparser.ConfigParser()
conf.read('config.ini')

ACCEES_KEY = conf['coincheck']['access_key']
SECRET_KEY = conf['coincheck']['secret_key']

coincheck = Coincheck(access_key=ACCEES_KEY, secret_key=SECRET_KEY)
# ticker = coincheck.ticker()
# print(ticker)

print(coincheck.last)

 

自動売買ロジックの確認

今回は以下の条件になったとき、「買い」と「売り」を入れるプログラムを作成していきたいと思います。

  • 買い : 観測地点のビットコイン価格が\(-2\sigma\)を下回ったとき
  • 売り : 観測地点のビットコイン価格が\(+2\sigma\)を上回ったとき

ここで登場する\(+2\sigma\)と\(-2\sigma\)を理解するには、ボリンジャーバンドについて知る必要があります。
とはいえ、ボリンジャーバンドの原理原則をしっかり理解しようとすると、大学で習う統計学の知識が必要です。

そこで、今回は目で見てわかるように、実際のチャートを確認していきましょう!

ボリンジャーバンドとは?

以下は1時間足のBTC/JPYチャートです。

ボリンジャーバンド

緑と赤でスティックになっているのが、ビットコインの価格推移です。
そして今回は価格推移だけでなく、BB:UpperとBB:Lowerも描かれています。

このBBというのがボリンジャーバンドのことです。
同じ色の線で上下セットになっていて、内側からそれぞれ\(1\sigma\)、\(2\sigma\)、\(3\sigma\)と呼びます。

より具体的にいうなら、最も内側に存在する青い線は\(1\sigma\)ということです。
さらに上側の線を\(+1\sigma\)、下側の線を\(-1\sigma\)と呼びます。

ボリンジャーバンドが意味するもの

ボリンジャーバンドを使うと、価格が各ライン内におさまる理論的な確率が分かります。

少し分かりにくいので、具体的に見ていきましょう。
\(1\sigma\)〜\(3\sigma\)ごとに、価格がライン内におさまる確率は以下のとおりです。

  • \(\pm1\sigma\)内におさまる確率 : 約68.3%
  • \(\pm2\sigma\)内におさまる確率 : 約95.4%
  • \(\pm3\sigma\)内におさまる確率 : 約99.7%

つまり以下のグラフで言えば、価格が最も内側の青いラインにおさまる確率は約68.3%ということです。

ボリンジャーバンド

このようにボリンジャーバンドを使うと、過去の価格推移を元に、値動きの上限と下限をある程度まで把握できるようになります。

今回のロジックの狙い

ここまでおさえた上で、今回プログラムで組んでいきたいロジックを振り返ってみます。

  • 買い : 観測地点のビットコイン価格が\(-2\sigma\)を下回ったとき
  • 売り : 観測地点のビットコイン価格が\(+2\sigma\)を上回ったとき

要するに、今回使っていきたいのは\(\pm2\sigma\)です。
図で表すと、以下の紫の線になります。

2σ

ここで描かれている紫の線の内側におさまる確率は約95.4%でした。
今回はそれを下回ったときに「買い」を入れて、上回ったときに「売り」を入れます。

これを図で確認すると、以下のようになります。

エントリーポイント

つまり、ほとんどの場合は約95.4%の確率で\(\pm2\sigma\)におさまるけど、もし例外が発生したら売買をおこなうということです。

これくらいシンプルなロジックだと、プログラムの作成もそこまで難しくありません。

自動売買に必要なロジックの作成

それでは自動売買で必要なロジックを作成していきましょう。
自動売買プログラムの作成にあたり、以下のステップが必要になります。

  • STEP① : Pandasをインストールする
  • STEP② : 最新価格を取得し続ける
  • STEP③ : ボリンジャーバンドを計算する
  • STEP④ : 「買い」または「売り」の条件を書く

順を追って解説していきます!

STEP① : Pandasをインストールする

今回は追加でPandasというライブラリをインストールします。
Pandasを使う理由は、自動売買で必要になる移動平均や標準偏差をラクに計算できるからです。

というわけで、さっそくPandasをインストールしていきましょう。
以下のコマンドを実行します。

pip install pandas

 

インストールが完了したら、Pandasをインポートします。

import configparser

import pandas as pd

from coincheck import Coincheck

conf = configparser.ConfigParser()
conf.read('config.ini')

ACCEES_KEY = conf['coincheck']['access_key']
SECRET_KEY = conf['coincheck']['secret_key']

coincheck = Coincheck(access_key=ACCEES_KEY, secret_key=SECRET_KEY)

print(coincheck.last)

 

これでPandasの準備は完了です!

STEP② : 最新価格を取得し続ける

ライブラリのインポートなど準備が完了したら、さっそくコードを書いていきます。

まず今回必要になるのは、いまprint()内で書いているcoincheck.lastです。
これを使うことで、ビットコインの最新価格を取得できます。

そして、取得したビットコイン価格は、PandasのDataFrame(データフレーム)内に格納していきたいです。

このDataFrameを活用することで、簡単に\(\pm2\sigma\)の計算をおこなえます。
というわけで、まずはDataFrameにビットコインの最新価格を入れていきましょう。

そのためのコードが以下になります。

import configparser

import pandas as pd

from coincheck import Coincheck

conf = configparser.ConfigParser()
conf.read('config.ini')

ACCEES_KEY = conf['coincheck']['access_key']
SECRET_KEY = conf['coincheck']['secret_key']

coincheck = Coincheck(access_key=ACCEES_KEY, secret_key=SECRET_KEY)

df = pd.DataFrame()

df = df.append(
    {'price': coincheck.last}, ignore_index=True
)

print(df)

 

ここまで書いてmain.pyを実行してみると、以下のような出力になるはずです。

       price
0  6503280.0

 

これがpriceというカラムを持ったDataFrameです。
ただ、これだと1つしかデータが入っていなくて分かりづらいですね。

なのでforループでAPIに5回アクセスして、もう少しデータを取得してみます。
このとき繰り返しのアクセスになるので、各回ごとに1秒間の休止状態を入れましょう。

その理由は、コインチェックのサーバーに負荷がかかってしまうからです。
Pythonで1秒間の休止状態を入れるには、timeライブラリをインポートしてtime.sleep(1)を使ってあげます。

import configparser
import time

import pandas as pd

from coincheck import Coincheck

conf = configparser.ConfigParser()
conf.read('config.ini')

ACCEES_KEY = conf['coincheck']['access_key']
SECRET_KEY = conf['coincheck']['secret_key']

coincheck = Coincheck(access_key=ACCEES_KEY, secret_key=SECRET_KEY)

interval = 1

df = pd.DataFrame()

for _ in range(5):
    time.sleep(interval)
    df = df.append(
        {'price': coincheck.last}, ignore_index=True
    )

print(df)

 

ここではintervalという変数を準備してから、1秒間の休止を設定しました。

出力結果は、以下のようになるはずです。

       price
0  6500985.0
1  6500985.0
2  6500985.0
3  6503649.0
4  6503649.0

 

ただし、今回作成していくプログラムは「ビットコインの最新価格を取得し続ける」必要がありますので、While文を使って以下のようにコードを修正します。

import configparser
import time

import pandas as pd

from coincheck import Coincheck

conf = configparser.ConfigParser()
conf.read('config.ini')

ACCEES_KEY = conf['coincheck']['access_key']
SECRET_KEY = conf['coincheck']['secret_key']

coincheck = Coincheck(access_key=ACCEES_KEY, secret_key=SECRET_KEY)

interval = 1

df = pd.DataFrame()

while True:
    time.sleep(interval)
    df = df.append(
        {'price': coincheck.last}, ignore_index=True
    )

    print(df)

 

これで最新価格を取得し続けるコードは作成完了です!

STEP③ : ボリンジャーバンドを計算する

次に考えるべきは、取得した価格を使ったボリンジャーバンドの計算です。

ボリンジャーバンドを計算するには、「過去どれくらい遡って価格情報を使うのか」を指定する必要があります。
もし1日ごとに価格を取得しているのであれば、「どれくらいの日足を使って計算するのか」ということです。

今回は、過去20回の価格情報を使って、ボリンジャーバンドを計算していきたいと思います。

\(\pm2\sigma\)の値は、以下の計算式で求められます。

$$\begin{eqnarray} +2\sigma &=& SMA + 2\sigma \\ -2\sigma &=& SMA – 2\sigma \end{eqnarray}$$

SMAというのは、単純に過去20回分の価格平均です。

また、\(\sigma\)は標準偏差のことで、要するに価格のバラツキを表します。
\(\sigma\)が大きければ、バラツキも大きいということですね。

\(\sigma\)は数学が分からないと少し難しいですが、Pandasを使えば簡単に計算できます。

それではコードで書いてみましょう。

"""
中略
"""

interval = 1
duration = 20

df = pd.DataFrame()
while True:
    time.sleep(interval)
    df = df.append(
        {'price': coincheck.last}, ignore_index=True
    )

    if len(df) < duration:
        continue

    df['SMA'] = df['price'].rolling(window=duration).mean()
    df['std'] = df['price'].rolling(window=duration).std()

    df['-2σ'] = df['SMA'] - 2*df['std']
    df['+2σ'] = df['SMA'] + 2*df['std']

    print(df)

 

これでビットコイン価格を取得し続けて、\(\pm2\sigma\)の計算までおこなえます。

ポイントはSMAstdの計算です。
Pandasを使うことで、それぞれ1行のコードで簡単に記述できます。

引数のwindow=durationでは、あらかじめ先に決めておいた変数duration=20が入ります。
durationに20を選択している理由は、過去20回分の価格を元に、平均と標準偏差を計算したいからです。

言い方を換えると、過去20回分の価格データが必要なので、それまでは価格取得に注力しています。

その結果をdf['SMA']df['std']と書くことで、新しいカラムに格納しています。

それではコードを実行して、出力を確認してみましょう。

        price         SMA          std           -2σ           +2σ
0   6559000.0         NaN          NaN           NaN           NaN
1   6562420.0         NaN          NaN           NaN           NaN
2   6562420.0         NaN          NaN           NaN           NaN
"""
中略
"""
17  6560002.0         NaN          NaN           NaN           NaN
18  6560002.0         NaN          NaN           NaN           NaN
19  6560002.0  6561444.75  1771.380814  6.557902e+06  6.564988e+06

 

このように、20行目では過去の価格データを使った\(\pm2\sigma\)の計算ができていますね。

これでボリンジャーバンドを計算するコードも作成できました!

STEP④ : 「買い」または「売り」の条件を書く

あとは計算したボリンジャーバンドを元に、「買い」と「売り」の条件を書くだけです。
「買い」と「売り」の条件を書くには、直近で取得した価格と\(\pm2\sigma\)の値を比較する必要があります。

DataFrameで最後の値を参照するにはdf['カラム名']iloc[-1]を使います。

このことを応用すれば、作成したいコードは以下のようになります。

"""
中略
"""

df = pd.DataFrame()
while True:
    time.sleep(interval)
    df = df.append(
        {'price': coincheck.last}, ignore_index=True
    )

    if len(df) < duration:
        continue

    df['SMA'] = df['price'].rolling(window=duration).mean()
    df['std'] = df['price'].rolling(window=duration).std()

    df['-2σ'] = df['SMA'] - 2*df['std']
    df['+2σ'] = df['SMA'] + 2*df['std']

    # もし-2σを割ったら買いを入れる
    if df['price'].iloc[-1] < df['-2σ'].iloc[-1]:
        print('buy!!!')

    # もし+2σを超えたら売りを入れる
    if df['+2σ'].iloc[-1] < df['price'].iloc[-1]:
        print('sell!!!')

 

このように書くことで、直近の価格と\(\pm2\sigma\)を比較したロジックを作成できます。

また、条件判定の中身はprint()で補っていますが、これは次のレクチャーで作成します。

今回は、最新価格の取得とボリンジャーバンドの計算、またそれらを比較する部分まで作っておけば大丈夫です!

まとめ : 自動売買に必要なロジックを作成してみよう!

というわけで、自動売買に必要なロジックを作成していきました。
おそらく、想像していたよりも簡単にコードを書けたのではないでしょうか。

次回の講義では、売買の部分もコードを書いていき、自動売買ロジックを完成させていきたいと思います。

もう完成に近づいているので、最後まで頑張っていきましょう!

第14回目の記事はこちら

buy-and-sell-bitcoin-automatically
#14 Python×ビットコイン自動売買 | 条件分岐を追加して売買ロジックを完成させよう!こんにちは、はやたす(@hayatasuuu )です。 今回の講義では、途中まで作成していた自動売買ロジックを、完成させていきたい...

トップページはこちら

python-bitcoin-auto-trade
Python×ビットコイン自動売買 | 初心者でも理解できる入門講義『Pythonを使ったビットコインの自動売買って、どうやって実装するんだろう...。分かりやすく書かれている入門記事はないかな〜。』このような悩みを解決する記事になっています。Pythonを使ったビットコインの自動売買を学んでみたい人は必見です。...