[Python]ビットコインの自動売買プログラムのサンプルコードを公開

自動売買

下の記事で作り方を紹介した、ビットコイン自動売買プログラムのサンプルコードを公開します

この記事を読むことで、仮想通貨取引所bitbankを使った自動売買をすることができるようになります

また、

・仮想通貨自動売買とはなんなのか?

・メリットとデメリットはなんなのか?

を知りたい方は、この記事にまとめているのでご覧ください

ビットコインの自動売買プログラムのサンプルコードを公開

アルゴリズム(戦略)

単純移動平均のゴールデンクロス・デッドクロスをもとにアルゴリズムを考えます

移動平均線とは、値動きを平均的に均した線のことで、2本の移動平均線が交わったところで「買い」「売り」の判断をします

(図は、水色が25時間移動平均線、黄色が9時間移動平均線)

フローチャートに示すとこんな感じです

アルゴリズムについて気になる方は、この記事をご覧ください

プログラムを動かすために必要な下準備

bitbankの登録

暗号資産(仮想通貨)取引所のAPIというものを使って、プログラムから暗号資産(仮想通貨)を売買します

ビットコイン自動売買をするときに、選ぶ条件はこれらです

・APIが使える

・「取引所」がある(「販売所」ではない)

・取引手数料が安い

・スプレッドが小さい

この条件を満たすのは、仮想通貨取引所bitbank(ビットバンク)です

リンクを貼っておきます

bitbank

bitbankに登録をし、APIキーとAPIシークレットを取得しましょう

環境構築

プログラムで必要なライブラリをインストールします

コマンドプロンプトで、このように入力します

表計算をするライブラリ「pandas」

pip install pandas

定期実行するためのライブラリ「schedule」

pip install schedule

仮想通貨取引所bitbank(ビットバンク)のAPIを扱うライブラリ「python_bitbankcc」

pip install git+https://github.com/bitbankinc/python-bitbankcc.git

もしSSLエラーでpipが使えないと言われてしまったら、「OpenSSL」をインストールしてみてください

WindowsにOpenSSLをインストールして証明書を取り扱う(基本編)
電子証明書やSSL/TLSのための標準的なツールキット「OpenSSL」。だがWindows OSには標準でインストールされていない。Windows OSでOpenSSLを利用するのに必要なインストール手順と注意点を解説する。

ビットコインの自動売買プログラムのサンプルコード

※ビットコイン自動売買プログラムのサンプルを載せますが、以下の点をご注意ください

注意事項

・取引における損失について、責任は負いかねます

・API Keyの流出など、セキュリティ面での責任は負いかねます

・上記以外のいかなる障害・トラブルにおいても責任を負いかねます

#-------------------------------------------#
#関数

#分足でSMAを計算する関数 引数:終わりの日付データ、期間(分)、ペア 返り値:移動平均
def sma_cal_hourly(the_time, span, pair):

    #パブリックAPIのオブジェクトを取得
    pub = python_bitbankcc.public()
    
    #日付の補正
    if the_time.hour >= 9:
        correction = 0
    else:
        correction = 1
        
    #日付の演算
    start = the_time - datetime.timedelta(days = math.ceil(span/24/60)+correction)
    end = the_time - datetime.timedelta(days = correction)
    
    #日付の引き算
    data_span = end - start
#データフレームの定義
    col = ["Open","High","Low","Close","Volume","Unix Time"]
    df_sum = pandas.DataFrame(columns = col)
    
    #1日ごとに時間足データを取得し、結合していく
    for counter in range(data_span.days + 1):

        #日付の計算
        the_day = start + datetime.timedelta(days = counter)
        
        #データが欠損している部分は無視する
        try:
            #パブリックAPIのインスタンス化
            value = pub.get_candlestick("btc_jpy", "1min", the_day.strftime("%Y%m%d"))

            #データ部分の抽出
            ohlcv = value["candlestick"][0]['ohlcv']

            #データの長さを取得 本来は24時間なはずだけど、、
            length = len(value["candlestick"][0]['ohlcv'])

            #カラムの設定
            col = ["Open","High","Low","Close","Volume","Unix Time"]

            #データフレームに変換
            df = pandas.DataFrame(ohlcv, columns = col)

            #df_sumに結合
            df_sum = pandas.concat([df_sum, df])
except:
            print("data_error")

    #インデックスを0,1,2,3,,,とする
    df_sum = df_sum.reset_index()
    df = df_sum.drop(columns = "index")
    
    #UnixTimeから日付を計算
    date_and_time = []
    length = len(df)
    for counter in range(length):
        unix_time = df.at[counter,"Unix Time"]
        time_date = datetime.datetime.fromtimestamp(unix_time/1000)
        time = time_date.strftime("%Y-%m-%d-%H-%M")
        date_and_time.append(time)
        
    #日付の列を追加
    df["date"] = date_and_time

    #移動平均を求める
    df["SMA"] = df["Close"].rolling(window=span).mean()
    
    #その時間の移動平均を返す
    sma = df.at[len(df) - 1,"SMA"]       
    return(sma)

#板情報を取得する関数 引数:ペア 返り値:売値、買値
def board(pair):
    # public,private API classのオブジェクトを取得
 import python_bitbankcc
    pub = python_bitbankcc.public()

    # 板情報を取得
    value = pub.get_ticker(pair)
    #買い値
    buy_ratio = float(value["buy"])
    #売り値
    sell_ratio = float(value["sell"])

    return(buy_ratio, sell_ratio)
    


#-------------------------------------------#
#パラメータ

#短期移動平均・長期移動平均をそれぞれ何分平均にするかを定める 
short_span = 700
long_span = 1000

#投資する額[円]
jpy = 10000

#買う仮想通貨
crypto = "BTC"

#取引する仮想通貨ペア
pair = "btc_jpy"

#ビットコインを持ってない状態からスタート
signal = 0

#APIキー、シークレット(ビットバンク)
API_KEY = 'xxxxxxxxxxxxxxxxxx'
API_SECRET = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'


#-------------------------------------------#
#必要なライブラリ
import schedule
import time
import datetime
import python_bitbankcc
import math
import pandas


#-------------------------------------------#
#メインプログラム

def job():

    #グローバル変数の宣言
    global jpy
    global signal

    #現在の日付を取得
now = datetime.datetime.now()

    #時刻を表示
    print("--------------------------------")
    print(now.strftime("%Y-%m-%d-%H-%M"))

    #メインプログラム
    try:
        #移動平均の計算
        short_sma = sma_cal_hourly(now, short_span, "btc_jpy")
        long_sma = sma_cal_hourly(now, long_span, "btc_jpy")

        #売値と買値を取得
        res = board("btc_jpy")
        buy_ratio = res[0]
        sell_ratio = res[1]

        #注文量を設定
        #買うときはjpyで買えるだけ買う
        buy_amount_crypto = '{:.5f}'.format(jpy / buy_ratio)
        #売るときは買った分だけのビットコインを売る
        sell_amount_crypto = buy_amount_crypto

        #ゴールデンクロス
        if short_sma > long_sma:
            if signal == 0:

                #買う
                prv = python_bitbankcc.private(API_KEY, API_SECRET)
                value = prv.order(pair, 0, buy_amount_crypto, 'buy', 'market' )
 print("buy "+str(buy_amount_crypto)+" "+crypto)

                #買ったことにしておく
                signal = 1

            else:
                #トレードしない
                print("no_trade , have_btc")     
                
        #デッドクロス
        else:
            if signal == 1:

                #売る
                prv = python_bitbankcc.private(API_KEY, API_SECRET)
                value = prv.order(pair, 0, buy_amount_crypto, 'sell', 'market' )
                
                print("sell "+str(sell_amount_crypto)+" "+crypto)

                #売ったことにしておく
                signal = 0

                #どれだけ利益が出たか
                print("win: "+str(sell_amount_crypto * sell_ratio - jpy)+"yen")
#売買後の資産
                jpy = sell_amount_crypto * sell_ratio

            else:
                #トレードしない
                print("no_trade , don't_have_btc")
                

    except Exception as e:
        print(e)
        
#-------------------------------------------#
#定期実行する部分

#job()を毎分00秒に実行する
schedule.every().minute.at(":00").do(job)
schedule.run_pending()
while True:
    schedule.run_pending()
    time.sleep(1)

プログラムの解説

関数について

#-------------------------------------------#
#関数

#分足でSMAを計算する関数 引数:終わりの日付データ、期間(分)、ペア 返り値:移動平均
def sma_cal_hourly(the_time, span, pair):

    #パブリックAPIのオブジェクトを取得
    pub = python_bitbankcc.public()
    
    #日付の補正
    if the_time.hour >= 9:
        correction = 0
    else:
        correction = 1
        
    #日付の演算
    start = the_time - datetime.timedelta(days = math.ceil(span/24/60)+correction)
    end = the_time - datetime.timedelta(days = correction)
    
    #日付の引き算
    data_span = end - start
#データフレームの定義
    col = ["Open","High","Low","Close","Volume","Unix Time"]
    df_sum = pandas.DataFrame(columns = col)
    
    #1日ごとに時間足データを取得し、結合していく
    for counter in range(data_span.days + 1):

        #日付の計算
        the_day = start + datetime.timedelta(days = counter)
        
        #データが欠損している部分は無視する
        try:
            #パブリックAPIのインスタンス化
            value = pub.get_candlestick("btc_jpy", "1min", the_day.strftime("%Y%m%d"))

            #データ部分の抽出
            ohlcv = value["candlestick"][0]['ohlcv']

            #データの長さを取得 本来は24時間なはずだけど、、
            length = len(value["candlestick"][0]['ohlcv'])

            #カラムの設定
            col = ["Open","High","Low","Close","Volume","Unix Time"]

            #データフレームに変換
            df = pandas.DataFrame(ohlcv, columns = col)

            #df_sumに結合
            df_sum = pandas.concat([df_sum, df])
except:
            print("data_error")

    #インデックスを0,1,2,3,,,とする
    df_sum = df_sum.reset_index()
    df = df_sum.drop(columns = "index")
    
    #UnixTimeから日付を計算
    date_and_time = []
    length = len(df)
    for counter in range(length):
        unix_time = df.at[counter,"Unix Time"]
        time_date = datetime.datetime.fromtimestamp(unix_time/1000)
        time = time_date.strftime("%Y-%m-%d-%H-%M")
        date_and_time.append(time)
        
    #日付の列を追加
    df["date"] = date_and_time

    #移動平均を求める
    df["SMA"] = df["Close"].rolling(window=span).mean()
    
    #その時間の移動平均を返す
    sma = df.at[len(df) - 1,"SMA"]       
    return(sma)

#板情報を取得する関数 引数:ペア 返り値:売値、買値
def board(pair):
    # public,private API classのオブジェクトを取得
 import python_bitbankcc
    pub = python_bitbankcc.public()

    # 板情報を取得
    value = pub.get_ticker(pair)
    #買い値
    buy_ratio = float(value["buy"])
    #売り値
    sell_ratio = float(value["sell"])

    return(buy_ratio, sell_ratio)

ここで、以下の2つの関数を定義しています

・分足でSMA(単純移動平均)を計算する関数

・板情報を取得する関数

bitbankのAPIを使ってデータを取得する方法

日付を演算する方法

単純移動平均を計算する方法

パラメータについて

パラメータの部分を自由に買えることができます

#-------------------------------------------#
#パラメータ

#短期移動平均・長期移動平均をそれぞれ何分平均にするかを定める 
short_span = 700
long_span = 1000

#投資する額[円]
jpy = 10000

#買う仮想通貨
crypto = "BTC"

#取引する仮想通貨ペア
pair = "btc_jpy"

#ビットコインを持ってない状態からスタート
signal = 0

#APIキー、シークレット(ビットバンク)
API_KEY = 'xxxxxxxxxxxxxxxxxx'
API_SECRET = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'

パラメータとして、

・長期平均期間:1000時間

・短期平均期間:700時間

・投資金額:10,000円

に設定してあります

メインプログラムについて

#-------------------------------------------#
#メインプログラム

def job():

    #グローバル変数の宣言
    global jpy
    global signal

    #現在の日付を取得
now = datetime.datetime.now()

    #時刻を表示
    print("--------------------------------")
    print(now.strftime("%Y-%m-%d-%H-%M"))

    #メインプログラム
    try:
        #移動平均の計算
        short_sma = sma_cal_hourly(now, short_span, "btc_jpy")
        long_sma = sma_cal_hourly(now, long_span, "btc_jpy")

        #売値と買値を取得
        res = board("btc_jpy")
        buy_ratio = res[0]
        sell_ratio = res[1]

        #注文量を設定
        #買うときはjpyで買えるだけ買う
        buy_amount_crypto = '{:.5f}'.format(jpy / buy_ratio)
        #売るときは買った分だけのビットコインを売る
        sell_amount_crypto = buy_amount_crypto

        #ゴールデンクロス
        if short_sma > long_sma:
            if signal == 0:

                #買う
                prv = python_bitbankcc.private(API_KEY, API_SECRET)
                value = prv.order(pair, 0, buy_amount_crypto, 'buy', 'market' )
 print("buy "+str(buy_amount_crypto)+" "+crypto)

                #買ったことにしておく
                signal = 1

            else:
                #トレードしない
                print("no_trade , have_btc")     
                
        #デッドクロス
        else:
            if signal == 1:

                #売る
                prv = python_bitbankcc.private(API_KEY, API_SECRET)
                value = prv.order(pair, 0, buy_amount_crypto, 'sell', 'market' )
                
                print("sell "+str(sell_amount_crypto)+" "+crypto)

                #売ったことにしておく
                signal = 0

                #どれだけ利益が出たか
                print("win: "+str(sell_amount_crypto * sell_ratio - jpy)+"yen")
#売買後の資産
                jpy = sell_amount_crypto * sell_ratio

            else:
                #トレードしない
                print("no_trade , don't_have_btc")
                

    except Exception as e:
        print(e)

このフローチャートを満たすようなプログラムです

bitbankのAPIを使ってビットコインを購入する方法

パラメータの最適化

ビットコイン自動売買プログラムのアルゴリズムは、長期移動平均と短期移動平均のゴールデンクロスで全力買い、デッドクロスで全力売りとしました

ここで、長期移動平均は何分平均なのか、短期移動平均は何分平均なのかを決めておかなければないません

長期平均期間と短期平均期間がそれぞれ何分なのかによって、利益も変わってきます

もちろん利益が大きい方がいいので、利益が大きくなるような長期平均期間と短期平均期間を見つける作業をします

言い換えると、パラメータの最適化をしなければいけないということです

この記事で、過去データでシミュレーションをすることで、パラメータの最適化を試みています

この記事でシミュレーションをした結果より、上のプログラムでは、長期移動平均期間を1000分、短期移動平均期間を700分にしました

バックテスト

このプログラムが、本当に動かしていいプログラムなのかどうか、バックテストもする必要があります

バックテストの結果は、この記事にまとめました

バックテストより、このビットコイン自動売買プログラムは、動かしても大丈夫そうと言うことが分かりました

実行環境

このプログラムは、24時間ずっと動かしておく必要があります

24時間ネットに繋げてプログラムを動かし続けなければいけないので、ノートパソコンだと厳しいと思います

そこで、windowsのレンタルサーバーを借りるのをおすすめします

レンタルサーバーを借りると、24時間動かしておくパソコンをもう1台借りられるというイメージです

おすすめなレンタルサーバーはConoHaです

ConoHa for Windows Server

まとめ

Pythonで暗号資産ビットコイン自動売買プログラムを作り、実際に自動売買をするやり方を紹介しました

ビットコイン価格が上昇傾向の時は、紹介したサンプルプログラムでも利益が出るかもしれませんが、まだまだ欠点もあります

サンプルプログラムを改良したり、パラメータを最適化したりして、爆益に挑戦してみてください!

リンク

プログラムで使っている暗号資産取引所bitbank(ビットバンク)

bitbank

おすすめのレンタルサーバー

ConoHa for Windows Server

コメント

タイトルとURLをコピーしました