テクノロジーであそぼ!

プログラミング(Python)や投資、仮想通貨についての情報サイト。

Python × ZaifAPI 取引時間をハックするプログラム【ボリンジャーバンド編】

f:id:kichie_com:20171222204129p:plain

改めてZaifとは?

Zaifとは国内でモナーコインを取り扱っている取引所として定評があり、ビットコイン積立など様々な種類のサービスを利用できる取引所です。さらに、仮想通貨交換業者 登録番号00002号であり大阪に本拠地が置いてあるテックビューロ株式会社が運営する仮想通貨取引所です。
何と言っても魅力はビットコインの取引手数料がマイナスである事!
取引するだけでお金がもらえる、それだけたくさん使ってもらうことに重点を置いている取引所です。

新規登録に書類審査に2週間かかるらしい

私が口座を開設した時はまだ全然流知られていなかったので、1週間ぐらいで口座が開設できたのですが、今は口座開設をしたい人が急増しており、2週間以上時間を要しているようです。

こんな記事や
Zaif(ザイフ)の本人確認が遅い・終わらない・混雑してる・届かない・こない 本人確認書類はいつ来るの? 対処方法は? | 東大生だって金が欲しい!!

こんなツイートも

少しでも取引を考えている人はプログラムを実装するのに2週間ぐらいかかると予想されるので、今登録しておくとちょうどプログラムを書き終わるのと同時に開設ができそうですね!

投資家がよく使っているボリンジャーバンドとは?

前置きはさておき、いい取引をするプログラムを書くために必要な知識をインプットしていきます。
ボリンジャーバンドとは取引をする時に売られ過ぎているか、買われ過ぎているかを判断ができる指標です。
詳しくは下記のサイトを参照していただくと非常にわかりやすいですが、簡単に言うと統計的に約95%でこのボリンジャーバンドの範囲内におさまるので、この下限で買えば反発して底値で買って高値で売れるよね?って言うものです。
株の売買サインを簡単に見極めるボリンジャーバンドの使い方

今の移動平均線の価格に一定期間の標準偏差を足した額がボリンジャーバンドの値になります。

標準偏差の計算式

標準偏差=√(期間*価格の2乗合計ー価格の合計の2乗)/√(期間*(期間-1))

例えば上の図、ローソク足の中心あたりに赤い線がありますよね?それが移動平均線、そして上下に青い線があります。その値が移動平均線に上の式の標準偏差を足したボリンジャーバンドとなります。

ボリンジャーバンド具体例

f:id:kichie_com:20171218100641p:plain
上記画像がボリンジャーバンドを反映させたチャートです。
30分に1回ぐらいは加減にタッチしており、チャートの真ん中の赤い線の移動平均線に戻っていることがわかります。
この図からはこの差、1万〜3万円幅を取れていることがわかります。
しかし、図の8時15分あたりでは、219万円あたりでタッチしているにも関わらず218万円まで落ちています。この辺りの急落には対応できないのがボリンジャーバンドのデメリットなので損切りしてあげることが重要だと考えております。
このチャートの場合その後に移動平均線まで戻っているので大丈夫ですが。。。

もしこのまま100万円台まで落ちてしまっては、大損になりかねないので、損切りするアルゴリズムもしっかり考える必要があります。

取引アルゴリズム

Zaifの自動トレードプログラム書いたら10%利益出たからそのプログラムを載せてみる
こちらのアルゴリズムにボリンジャーバンドを付加しました。

①現在の最終取引額を取得(この金額が判断の基準となる)
②データが20個溜まったらボリンジャーバンドのデータを計算し始める
③Bitcoinを持っていて(0.001以上)かつ移動平均迄上がった場合、売る!(そして、前回取引額を更新する)
④Bitcoinを持っていない(0.001以下)かつボリンジャーバンドまで下がったら、買う!(そして、前回取引額を更新する)
⑤取引が処理されない場合、1分待って、待っても処理されない場合、キャンセルする(そして、前回取引額を元に戻す)

コード

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import json
import time
import pprint
from datetime import datetime
from numpy import sqrt
from zaifapi import ZaifPublicApi
from zaifapi import ZaifTradeApi
from decimal import (Decimal)

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

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

last_price = []


def moving_ave(last_price,period):
    sum_price = 0
    for price in last_price[-period:]:
        sum_price += price
    return sum_price/period

def st_div(price,period):
    sum_price = 0
    sum_price_2 = 0
    for price in last_price[-period:]:
        sum_price += price
        sum_price_2 += price**2
    return sqrt((period*sum_price_2-sum_price**2)/period*(period-1))


def cancel_flug(trade_result):
    global order_id,cancel_flug
    if(trade_result["order_id"] != 0):
        order_id=trade_result["order_id"]
        cancel_flug=1
    else:
        print("■ 取引が完了しました。")   
    
if __name__=='__main__':
    # get environ ver
    zaif_public = ZaifPublicApi()
    zaif_trade = ZaifTradeApi(KEY,SECRET)
    
    CANCEL_FLUG = False
    
    period = 20
    
    low_borin = 0
    m_ave       = 99999999
    high_borin = 99999999
    
    last_trade_price = int(zaif_public.last_price('btc_jpy')["last_price"])
    
    
    while(True):
        start_time = time.time()
        print("■ 現在の情報です")
        try:
            funds_btc = Decimal(zaif_trade.get_info2()['funds']['btc']).quantize(Decimal('0.0001'))
            funds_jpy = zaif_trade.get_info2()['funds']['jpy']
            last_price.append(int(zaif_public.last_price('btc_jpy')["last_price"]))

        except:
            print("エラー:Cant get data")
            continue
        
        finally:
            print("市場取引価格:"+str(last_price[-1]))
            print("btc資産:"+str(funds_btc))
            print("jpy資産:"+str(funds_jpy))
            print("最終取引価格:"+str(last_trade_price))
            
        
        if len(last_price) >= 20:
            moving_ave(last_price,20)
            st_div(last_price,20)
            
        if len(last_price) >= period:
            m_ave = moving_ave(last_price,period)
            print(m_ave)
            sigma = st_div(m_ave,period)
            high_borin = m_ave+sigma*2
            low_borin = m_ave-sigma*2
            print(high_borin,low_borin)
            
        
        
        
        #btcを持っていてm_ave以上なら利確
        if(funds_btc >= 0.001 and m_ave < last_trade_price):
            #売却
            ask_amount = funds_btc
            try:
                trade_result = zaif_trade.trade(currency_pair="btc_jpy", action="ask", price=last_price[-1], amount=ask_amount)
                last_trade_price_pre = last_trade_price
                last_trade_price = last_price[-1]
                
                print('■ Bitcoinの売却申請を行いました。')
                pprint.pprint(trade_result)
                print("売却注文価格:"+str(last_price[-1]))
                print("売却注文量 :"+str(ask_amount))
            except:
                print("エラー:cant trade[ask_up]")
                
            cancel_flug(trade_result)
            
        #btcを持っていてlow_borin-10000以下なら損切り
        elif(funds_btc >= 0.001 and low_borin-10000 > last_trade_price):
            try:
                #売却
                ask_amount = funds_btc
                trade_result = zaif_trade.trade(currency_pair="btc_jpy", action="ask", price=last_price[-1], amount=ask_amount)
                last_trade_price_pre = last_trade_price
                last_trade_price = last_price[-1]
                print('■ Bitcoinの売却申請を行いました。')
                pprint.pprint(trade_result)
                print("売却注文価格:"+str(last_price[-1]))
                print("売却注文量 :"+str(ask_amount))
            except:
                print("エラー:cant trade[ask]")
            
            cancel_flug(trade_result)
        #btcを資産の1/3以下持っていないでlastpriceより値下がりしたら買い
        elif(funds_btc < 0.001 and low_borin > last_price[-1]):
            try:
                bid_amount = (Decimal(funds_jpy)/last_price[-1]).quantize(Decimal('0.0001'))
                trade_result = zaif_trade.trade(currency_pair="btc_jpy", action="bid", price=last_price[-1], amount=bid_amount)
                last_trade_price_pre = last_trade_price
                last_trade_price = last_price[-1]
                not_able_bid_count = 0
                print('■ Bitcoinの購入申請を行いました')
                pprint.pprint(trade_result)
                print("購入注文価格:"+str(last_price[-1]))
                print("購入注文量 :"+str(bid_amount))
            except:
                print("エラー:cant trade[bid]")
                
            cancel_flug(trade_result)
            
            if CANCEL_FLUG:
                trade_info = zaif_trade.get_info2()
                if trade_info["open_orders"] > 0:
                    print("■ キャンセルしました")
                    print(zaif_trade.cancel_order(order_id=order_id))
                    last_trade_price = last_trade_price_pre
                else:
                    print("■ 取引が完了しました。")

        end_time = time.time()
        elpsed_time = end_time-start_time
        if elpsed_time > 30:
            elpsed_time %= 30
            print("take time over 30sec")
        
        print(elpsed_time)  
        time.sleep(30-elpsed_time)

結果

実行中に落ちるため後日載せます。


github始めました

落合陽一さんが公表しないコードは無意味だとなんかの番組で言ってらしたので、それに影響を受け、作成したコードは法や契約上で非公開にしなくてはいけないもの以外は公開することにしました。
よかったらフォローお願い致します。
また、プログラミングをし始めて慣れてきた人はgithubを始めるのもお勧めします。
自分の成果が目に見えると非常にモチベーションが上がります。私は下記のサイトを参考にしてgithub入門しました。
GitHub 入門

終わりに

これからも不定期ですが更新するので読者登録もしくはgithubフォローしていただくと投稿した瞬間に通知が行くと思います。
仮想通貨の取引はお金が増減しますが、読者登録は一円もかからないのでおすすめです。