Help us understand the problem. What is going on with this article?

初心者が一攫千金を目指してBitcoin自動取引botを作るよ! その3【ローカルBot】

More than 3 years have passed since last update.

初心者が一攫千金を目指してBitcoin自動取引botを作るよ! その1
初心者が一攫千金を目指してBitcoin自動取引botを作るよ! その2の続きになります。

今回はついに、自分で情報を取得し売買を行うbitcoin自動取引Botもどきを作成します!

仕様

組み合わせて動くかの実験として、
安くなったら買う、そして、高くなったら売る!みたいな愚直なBotを作ってみました。

①前回の取引額を渡す(この金額が判断の基準となる)
②Bitcoinを持っていてかつ値上がりした場合、売る!(そして、前回取引額を更新する)
③日本円を持っていてかつ値下がりした場合、買う!(そして、前回取引額を更新する)
④取引が処理されない場合、1分待って、待っても処理されない場合、キャンセルする(そして、前回取引額を元に戻す)

【参考】
・取引後のResponseの「order_id」が0でない(order_idが発行されている)場合、取引が保留となっている。

実装

今回より、keyとsecretをjsonにして別ファイルで保管するように変えました。
[]・・・フォルダ
[zaif]
 |- main.py
 |- [config] - zaif_keys.json
 |- ...<略>

main.py
# -*- coding: utf-8 -*-

import json
import time
from zaifapi import ZaifPublicApi  # Zaifが公開している認証情報が要らないAPIを実行するクラス
from zaifapi import ZaifPrivateApi  # Zaifが公開している認証情報が必要なAPIを実行するクラス
from pprint import pprint  # 表示用(jsonをきれいに表示してくれる)

zaif_keys_json = open('config/zaif_keys.json', 'r')
zaif_keys = json.load(zaif_keys_json)

KEY = zaif_keys["key"]
SECRET = zaif_keys["secret"]

if __name__ == '__main__':
    zaif_public = ZaifPublicApi()
    zaif_private = ZaifPrivateApi(KEY, SECRET)

    # 前回の取引額
    Last_transaction_amount = 122210

    # 情報取得
    last_price = int(zaif_public.last_price('btc_jpy')["last_price"])
    trade_info = zaif_private.get_info2()
    funds_btc = trade_info["funds"]["btc"]
    funds_jpy = trade_info["funds"]["jpy"]
    print('■ 現在の情報です。')
    print('last_price: ' + str(last_price))
    print('funds_btc: ' + str(funds_btc))
    print('funds_jpy: ' + str(funds_jpy))
    cancel_flag = False
    order_id = 0
    last_price_old = 0

    # btcを持っていて値上がりしたとき
    if funds_btc != 0 and last_price > Last_transaction_amount:
        # Bitcoinを売る
        trade_result = zaif_private.trade(currency_pair="btc_jpy", action="ask", price=last_price, amount=funds_btc)
        print('■ Bitcoinの売却申請を行いました。')
        pprint(trade_result)
        last_price_old = Last_transaction_amount
        Last_transaction_amount = last_price
        if trade_result["order_id"] != 0:
            cancel_flag = True
            order_id = trade_result["order_id"]
        else:
            print('■ 取引が完了しました。')

    # jpyを持っていて値下がりしたとき
    # (最小単位(0.0001btc分)の日本円以上を持っていたとき)
    elif funds_jpy > Last_transaction_amount / 10000 and last_price < Last_transaction_amount:
        # APIが小数点以下4桁までの対応なのでround()
        # 小数点第5位が繰り上げの場合、資産不足になるため(- 0.0001)
        amount = round(float(funds_jpy) / last_price, 4) - 0.0001

        # Bitcoinを買う
        trade_result = zaif_private.trade(currency_pair="btc_jpy", action="bid", price=last_price, amount=amount)
        print('■ Bitcoinの購入申請を行いました')
        pprint(trade_result)
        last_price_old = Last_transaction_amount
        Last_transaction_amount = last_price
        if trade_result["order_id"] != 0:
            cancel_flag = True
            order_id = trade_result["order_id"]
        else:
            print('■ 取引が完了しました。')

    # 取引が保留となった場合、60秒待ってまだ保留の場合はキャンセルを行う
    if cancel_flag:
        print('■ 60秒間待機します。')
        time.sleep(60)
        trade_info = zaif_private.get_info2()
        if trade_info["open_orders"] > 0:
            print('■ キャンセルしました。')
            pprint(zaif_private.cancel_order(order_id=order_id))
            Last_transaction_amount = last_price_old
        else:
            print('■ 取引が完了しました。')
            pprint(trade_info)

main.pyと同じ階層にフォルダ「config」を作成し、下記jsonファイルに保存します。

zaif_keys.json
{
  "key" : "【作成したKey】",
  "secret" : "【作成したsecret】"
}

■実行結果
btcを持ってて値上がりしたとき

■ 現在の情報です。
last_price: 126725
funds_btc: 0.0075
funds_jpy: 7.9355
■ Bitcoinの売却申請を行いました。
{u'funds': {u'btc': 0.0, u'jpy': 7.9355, u'mona': 0.0, u'xem': 0.0},
 u'order_id': 156957485,
 u'received': 0.0,
 u'remains': 0.0075}
■ 60秒間待機します。
■ 取引が完了しました。
{u'deposit': {u'btc': 0.0, u'jpy': 958.373, u'mona': 0.0, u'xem': 0.0},
 u'funds': {u'btc': 0.0, u'jpy': 958.373, u'mona': 0.0, u'xem': 0.0},
 u'open_orders': 0,
 u'rights': {u'info': 1, u'personal_info': 0, u'trade': 1, u'withdraw': 0},
 u'server_time': 1491323133}

■実行結果
jpyを持ってて値下がりした時

■ 現在の情報です。
last_price: 126815
funds_btc: 0.0
funds_jpy: 959.048
■ Bitcoinの購入申請を行いました
{u'funds': {u'btc': 0.0, u'jpy': 7.9355, u'mona': 0.0, u'xem': 0.0},
 u'order_id': 156951488,
 u'received': 0.0,
 u'remains': 0.0075}
■ 60秒間待機します。
■ 取引が完了しました。
{u'deposit': {u'btc': 0.0, u'jpy': 959.048, u'mona': 0.0, u'xem': 0.0},
 u'funds': {u'btc': 0.0, u'jpy': 7.9355, u'mona': 0.0, u'xem': 0.0},
 u'open_orders': 1,
 u'rights': {u'info': 1, u'personal_info': 0, u'trade': 1, u'withdraw': 0},
 u'server_time': 1491322779}

1日無限ループで動かしてみた結果

上記コードを加工し、1分ごとに1回実行し、1日動かしてみました。

①「# 情報取得」の手前に無限ループ「while True:」を挿入
②コードの一番後ろに「time.sleep(60)」を挿入

その結果は・・・!

昨晩の1回目の取引の金額:¥957.8495

■ 取引が完了しました。
{u'deposit': {u'btc': 0.0, u'jpy': 957.8495, u'mona': 0.0, u'xem': 0.0},
 u'funds': {u'btc': 0.0, u'jpy': 957.8495, u'mona': 0.0, u'xem': 0.0},
 u'open_orders': 0,
 u'rights': {u'info': 1, u'personal_info': 0, u'trade': 1, u'withdraw': 0},
 u'server_time': 1491324869}

只今の所持金:¥958.8245

■ 現在の情報です。
last_price: 127740
funds_btc: 0.0
funds_jpy: 958.8245

計算してみると。。。
¥957.8495¥958.8245なので、¥0.975の利益・・・!
(´◉◞౪◟◉)うん…
反省点をまとめようか。

反省点というか問題点

・1分ごとの瞬間の値しか見れない(変動がわからない)
・取引額を変数に格納しているだけなので、エラーで落ちると飛ぶ
・自宅PCのコンソールで動かし続けるの美しくない(寝るときPCのファンがうるさい)
・以下の場合(条件から外れて帰ってこない場合)、取引が一切できなくなる
 ・Bitcoinを持っていてかつ値下がりした場合
 ・日本円を持っていてかつ値上がりした場合
・0.0001でも値上がりした場合でも売るってだめなのでは(利益でない・・・)

おわりに

なにはともあれ1日落ちずに動いたのは良かったです。
次回は反省点を活かし、AWS Lambda上で実行してみたいと思います!
Lambdaだと都度実行になるので、データが飛ばないようにDBにもデータを格納しないといけませんね。

※Lambdaとは、簡単に言うとコードをアップすると実行してくれるやつです。[参考]
 サーバーを立てなくていい、環境を構築しなくていい優しいフレンズです(*´ω`*)

お疲れ様でした~

更新履歴

2017/04/06:keyとsecretをjsonにして別ファイルで保存した旨の記載が抜けてました。。。

speedkingg
馬鹿なことを真剣に。
tis
創業40年超のSIerです。
https://www.tis.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした