Pythonで仮想通貨の移動平均線とボリンジャーバンド取得③ MONAトレード動作プログラム

修正したプログラムで実トレードを動かしてみました。結果は惨敗でしたね。プラスになったりマイナスになったりを繰り返してマイナスが増えていく感じです。MONAコインだからかもしれませんが、結構利確時のキャンセルが多いですし、価格の上下が激しく損切りが頻発したりする感じです。
それとボリンジャーバンドがMONAコインだと有効では無いように思います。

作ったのでコードを載せていますが、参考程度としておくのがよろしいかと思います。

ビットコイン版に修正して試したいと思いますが、bitbankではなく、zaifの方がボーナスを貰えるので有利になります。ただし、zaifは結構APIでエラーになりやすいのが気がかりですね。

スポンサードリンク

動作環境

NCU(4コア)に、ESXiを導入した仮想サーバーを持っているため、windows7 Starter(2仮想CPU) をインストールして常時稼働させています。Starterには、リモートディスクトップのサーバ機能が無いため、高速リモートディスクトップ「Yule」を使っています。
python 3.6.4 は、Anaconda version 5.1.0 で導入しています。

スポンサードリンク

購入判断

ボリンジャーバンド(σ*1)の低偏差より低ければ、購入申請します。

利確判断

購入した価格から2%程度の利益があれば、利益を確定するため利確申請します。
ただし、平均線が上昇傾向で、4%程度の利益までは保留します。

損切り判断

購入した価格から1%程度損益になれば、損切り申請します。

コード

注意
コードを記載していますが、使用する場合は自己責任でお願いします。

key.jsonの書式は前回の記事を参照してください。

Pythonで仮想通貨の移動平均線とボリンジャーバンド取得② 公開API動作プログラム
# coding=utf-8

import json
import time
import pprint
import codecs
import slackweb
import numpy as np
import python_bitbankcc
from datetime import datetime
from decimal import (Decimal)
from logger import error_logger
from logger import trade_logger

with codecs.open('config/key.json', 'r', 'utf-8') as f:
    API_data = json.load(f)

WEBHOOK_URL = API_data["slack_webhook_url"]
slack = slackweb.Slack(WEBHOOK_URL)

API_KEY = API_data["bitbank_key"]
API_SECRET = API_data["bitbank_secret"]
COIN_NAME = 'mona'
COIN_PAIR = 'mona_jpy'
EXCHANGE = 'BitBank:'

trade_log = trade_logger.TradeLogger('bitbank', COIN_NAME)
error_log = error_logger.ErrorLogger('error')

PERIOD = 15  # ボリンジャーバンドの間隔数
LOOP_TIME = 15  # 市場価格取得間隔の秒数
CANCEL_LOOP_MAX = 4  # キャンセルするまでのループ回数 4x15=60秒
TRADE_HOLD_MAX = 4  # トレード直後に売買しないようにする回数 4x15=60秒

last_price = []  # 市場価格
cancel_flag = False  # キャンセル処理をするかのフラグ
cancel_loop_count = 0  # キャンセルまでのカウント
trade_hold_count = 0  # トレード後の売買処理しないカウント

low_borin = 0  # 低ボリンジャーバンド
moving_avg = 89999999  # 移動平均
sigma = 0  # 標準偏差
moving_avg_pre = 0  # 一つ前の移動平均
high_borin = 89999999  # 高ボリンジャーバンド

funds_jpy = 0  # 注文余力日本円
funds_coin = 0.0  # 注文余力コイン

last_trade_func = ''  # 取引機能
last_trade_order_id = 0  # 最後に取引したID
last_trade_size = 0.0  # 最後に取引したサイズ
last_trade_price = 0  # 最後に取引した価格
last_trade_price_pre = 0  # 一つ前の取引した価格(キャンセルした時用)
asset_info = False

message_func = ''  # トレードログ用
message_trade = ''  # トレードログ用
message_size = 0  # トレードログ用
message_price = 0.0  # トレードログ用

date_time = datetime.now()  # print用表示タイム
current_price = 0  # 一時的に保管する市場価格


if __name__ == '__main__':
    bitbank_public = python_bitbankcc.public()
    bitbank_private = python_bitbankcc.private(API_KEY, API_SECRET)

    last_trade_price = float(bitbank_public.get_ticker(COIN_PAIR)['last'])

    while True:
        message_func = ''
        message_trade = ''
        message_price = 0
        message_size = 0.0
        date_time = datetime.now()
        start_time = time.time()
        try:
            result = bitbank_private.get_asset()
            for currency in result['assets']:
                if currency['asset'] == 'jpy':
                    funds_jpy = float(currency['free_amount'])
                if currency['asset'] == COIN_NAME:
                    funds_coin = float(currency['free_amount'])
            current_price = float(bitbank_public.get_ticker(COIN_PAIR)['last'])

        except:
            error_log.write()
            print("エラー:Cant get data")
            time.sleep(1)
            continue

        else:
            last_price.append(current_price)
            if len(last_price) <= PERIOD:
                print("■ 現在の情報です", len(last_price))
                print(str(date_time))
                print("市場取引価格:" + str(last_price[-1]))
                print(COIN_NAME + "資産:" + str(funds_coin))
                print("jpy資産:" + str(funds_jpy))
                print("最終取引価格:" + str(last_trade_price))

        if len(last_price) < 2 or asset_info:
            message_text = EXCHANGE + '現在の資産\n' + str(date_time) + '\njpy資産:' + str(funds_jpy) \
                           + '\n' + COIN_NAME + '資産:' + str(funds_coin)
            slack.notify(text=message_text)
            asset_info = False
        if len(last_price) > PERIOD:
            print('■資産、平均線、ボリンジャーバンド', len(last_price))
            print(str(date_time))
            print(COIN_NAME + '資産:', str(funds_coin))
            print('jpy資産:', str(funds_jpy))
            print('市場価格:', str(current_price))
            print('平均  :', str(moving_avg))
            print('高偏差:', str(high_borin))
            print('低偏差:', str(low_borin))
            print("最終取引価格:" + str(last_trade_price))
            message_func = EXCHANGE + '資産、平均、標準偏差'

        # 利確
        if (funds_coin >= 0.001 and current_price * 0.98 > last_trade_price
                and trade_hold_count > TRADE_HOLD_MAX):
            if moving_avg > moving_avg_pre and (current_price * 0.96) < last_trade_price:
                print('上昇傾向なので保留')
            else:
                # 売却
                ask_amount = funds_coin
                adjustment = 0
                if moving_avg > moving_avg_pre:
                    adjustment = 2
                elif moving_avg == moving_avg_pre:
                    adjustment = 1
                else:
                    adjustment = 0

                try:
                    trade_result = bitbank_private.order(COIN_PAIR, last_price[-1] - 1, str(ask_amount),
                                                         'sell', 'limit')
                    last_trade_func = 'ask'
                    last_trade_size = ask_amount
                    last_trade_price_pre = last_trade_price
                    last_trade_price = last_price[-1] - 1 + adjustment
                    last_trade_order_id = trade_result['order_id']
                    trade_hold_count = 0
                    asset_info = True

                    print('■ 利確売却申請を行いました。')
                    pprint.pprint(trade_result)
                    print("売却注文価格:" + str(last_price[-1] - 1 + adjustment))
                    print("売却注文量 :" + str(ask_amount))
                    message_func += '、利確'
                    message_trade = 'ask'
                    message_price = current_price - 1 + adjustment
                    message_size = ask_amount

                    message_text = EXCHANGE + '■ 利確売却申請を行いました。\n' + str(date_time) \
                                   + '\nPrice:' + str(current_price - 1 + adjustment) \
                                   + '\nSize:' + str(ask_amount)
                    slack.notify(text=message_text)

                except:
                    error_log.write()
                    print("エラー:cant trade[ask_up]")
                else:
                    if trade_result['status'] != 'FULLY_FILLED':
                        last_trade_order_id = trade_result['order_id']
                        cancel_flag = True
                        cancel_loop_count = 0
                    else:
                        print('■ 取引が完了しました。')
                        last_trade_order_id = 0

        # 損切り
        elif (funds_coin >= 0.001 and current_price < (last_trade_price * 0.99)
              and trade_hold_count > TRADE_HOLD_MAX):
            ask_amount = funds_coin
            try:
                # 売却
                trade_result = bitbank_private.order(COIN_PAIR, last_price[-1] - 1, str(ask_amount),
                                                     'sell', 'limit')
                last_trade_func = 'ask'
                last_trade_size = ask_amount
                last_trade_price_pre = last_trade_price
                last_trade_price = last_price[-1] - 1
                last_trade_order_id = trade_result['order_id']
                trade_hold_count = 0
                asset_info = True

                print('■ 損切売却申請を行いました。')
                pprint.pprint(trade_result)
                print("売却注文価格:" + str(last_price[-1] - 1))
                print("売却注文量 :" + str(ask_amount))
                message_func += '、損切'
                message_trade = 'ask'
                message_price = current_price - 1
                message_size = ask_amount
                message_text = EXCHANGE + '■ 損切売却申請を行いました。\n' + str(date_time) \
                               + '\nPrice:' + str(current_price - 1) + '\nSize:' + str(ask_amount)
                slack.notify(text=message_text)

            except:
                error_log.write()
                print("エラー:cant trade[ask]")
            else:
                if trade_result['status'] != 'FULLY_FILLED':
                    last_trade_order_id = trade_result['order_id']
                    cancel_flag = True
                    cancel_loop_count = 0
                else:
                    print('■ 取引が完了しました。')
                    last_trade_order_id = 0

        # コインを最小単位持っていない場合で、低偏差値より低い場合に購入
        elif (funds_coin < 0.001 and low_borin >= current_price
              and trade_hold_count > TRADE_HOLD_MAX and last_trade_order_id == 0):
            bid_amount = Decimal(funds_jpy * 0.9 / current_price).quantize(Decimal('0.001'))
            try:
                trade_result = bitbank_private.order(COIN_PAIR, last_price[-1], str(bid_amount),
                                                     'buy', 'limit')
                last_trade_func = 'bid'
                last_trade_size = bid_amount
                last_trade_price_pre = last_trade_price
                last_trade_price = last_price[-1]
                last_trade_order_id = trade_result['order_id']
                trade_hold_count = 0
                asset_info = True

                print('■ 購入申請を行いました')
                pprint.pprint(trade_result)
                print("購入注文価格:" + str(last_price[-1]))
                print("購入注文量 :" + str(bid_amount))
                message_func += '、購入'
                message_trade = 'bid'
                message_price = current_price
                message_size = bid_amount
                message_text = EXCHANGE + '■ 購入申請を行いました。\n' + str(date_time) \
                               + '\nPrice:' + str(current_price) + '\nSize:' + str(bid_amount)
                slack.notify(text=message_text)

            except:
                error_log.write()
                print("エラー:cant trade[bid]")
            else:
                if trade_result['status'] != 'FULLY_FILLED':
                    last_trade_order_id = trade_result['order_id']
                    cancel_flag = True
                    cancel_loop_count = 0
                else:
                    print('■ 取引が完了しました。')
                    last_trade_order_id = 0

        if cancel_flag and cancel_loop_count > CANCEL_LOOP_MAX:
            try:
                trade_info = bitbank_private.get_order(COIN_PAIR, last_trade_order_id)
                if trade_info["status"] == 'UNFILLED' or trade_info["status"] == 'PARTIALLY_FILLED':
                    print("■ キャンセルしました")
                    print(bitbank_private.cancel_order(COIN_PAIR, last_trade_order_id))
                    last_trade_price = last_trade_price_pre
                    message_func += 'キャンセル'
                    message_text = EXCHANGE + '■ キャンセルしました'
                    slack.notify(text=message_text)
                    trade_hold_count = 0
                else:
                    print("■ 取引が完了しました。")
                    message_text = EXCHANGE + '■ 約定しました'
                    slack.notify(text=message_text)
                    asset_info = True
                last_trade_order_id = 0
            except:
                error_log.write()
                print("エラー:cant trade[info/cancel]")
            else:
                cancel_flag = False

        if len(last_price) >= PERIOD:
            if len(last_price) != PERIOD:
                trade_log.write(
                    func=message_func,
                    coin_asset=funds_coin,
                    jpy_asset=funds_jpy,
                    market_price=current_price,
                    order_id=last_trade_order_id,
                    trade=message_trade,
                    last_trade_price=last_trade_price,
                    price=message_price,
                    size=message_size,
                    mean_line2=moving_avg,
                    sigma2=sigma)

            cancel_loop_count += 1
            trade_hold_count += 1
            moving_avg_pre = moving_avg
            moving_avg = np.average(last_price[-PERIOD:])
            sigma = np.std(last_price[-PERIOD:], ddof=1)
            high_borin = moving_avg + sigma * 1
            low_borin = moving_avg - sigma * 1

        end_time = time.time()
        elpsed_time = end_time - start_time
        if elpsed_time > LOOP_TIME:
            elpsed_time %= LOOP_TIME
            print('ake time over', str(LOOP_TIME), 'sec')

        time.sleep(LOOP_TIME - elpsed_time)

Monappy: MBDQ39VHypMQwfyR8SshuHvfPNUz321F6B

Monacoinを投げる
モナゲ(tipmona)ってなに?
そもそもMonacoinってなに?

コメントを残す

メールアドレスが公開されることはありません。

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください