🐙

ビットコインの曜日効果を調べるプログラム

2022/10/22に公開

皆様は曜日効果についてご存知でしょうか?

曜日効果とは、"特定の曜日の収益率が他の曜日よりも低く、または高くなりやすい現象のこと。"とありますが、本当に存在するのでしょうか?

今現在も存在しているかもしれませんし、していないかもしれません。
していなくても、これから曜日効果が発生する可能性もあります。

そこで、この記事ではビットコインには曜日効果が存在しているか?を調査するためのプログラム(Python3)を提供します。

実際にこちらを参考に行った取引および記事のプログラムを利用したことによるいかなる損害も作者は一切の責任を負いません。自己の責任の上で使用してください。

プログラムの実行結果は、以下のように各曜日、時間ごとの始値と終値の差(0.5より上なら価格が上がることが多い、0.5未満なら価格が下がることが多い)に応じたヒートマップが出力されます(以下の出力は例です)。

# -*- coding: utf-8 -*-
import pandas as pd
from datetime import datetime
from datetime import timedelta 
import json
import requests
import seaborn as sns
import matplotlib.pyplot as plt

def get_ohlc(cur, bin, count ,page):

    res = json.loads(requests.get('https://www.bitmex.com/api/v1/trade/bucketed?symbol='+str(cur)+'&binSize='+bin+'&partial=false&count='+str(count)+'&reverse=true').text)
    columns = ['timestamp','symbol', 'open' ,'high','low','close','trades','volume','vwap','lastSize','turnover','homeNotional','foreignNotional']
    df = pd.DataFrame(res, columns=columns)
    
    for p in range(page):
    
        res = json.loads(requests.get('https://www.bitmex.com/api/v1/trade/bucketed?symbol='+str(cur)+'&binSize='+bin+'&partial=false&count='+str(count)+'&reverse=true&start='+str(count*(p+1))).text)
        columns = ['timestamp','symbol', 'open' ,'high','low','close','trades','volume','vwap','lastSize','turnover','homeNotional','foreignNotional']
         
        df = df.append(pd.DataFrame(res, columns=columns))
         
    return df

def utc2jst(time_in):
    htime = datetime.strptime(time_in , '%Y-%m-%dT%H:%M:%S.%fZ')

    d = datetime(htime.year, htime.month, htime.day, htime.hour)
    jst_d = d + timedelta(hours=9)

    return jst_d
    
def main():

    weekday = ['mon','tue','wed','thu','fri','sat','sun']
    weekday_plus   = [[0 for i in range(7)] for i2 in range(24)]
    weekday_minus  = [[0 for i in range(7)] for i2 in range(24)]
    weekday_rate  = [[0 for i in range(7)] for i2 in range(24)]
    hour_plus      = [0 for i in range(24)]
    hour_minus     = [0 for i in range(24)]

    df_1h = get_ohlc('XBTUSD', '1h', 240, 5)
    
    hour_open  = list(df_1h['open'])
    hour_close = list(df_1h['close'])
    hour_time  = list(df_1h['timestamp'])

    for i in range(len(df_1h)):
    
        jst = utc2jst(hour_time[i])
        hour_delta = hour_close[i] - hour_open[i] 

        if(hour_delta>=0): 
            hour_plus[jst.hour] += 1
            weekday_plus[jst.hour][jst.weekday()] += 1
        else:
            hour_minus[jst.hour] += 1
            weekday_minus[jst.hour][jst.weekday()] += 1

    for j in range(7):
        for i in range(24):
            if((weekday_plus[i][j]+weekday_minus[i][j])!=0):
                weekday_rate[i][j] = weekday_plus[i][j] / (weekday_plus[i][j]+weekday_minus[i][j])
            else:
                weekday_rate[i][j] = 0.5

    sns.heatmap(weekday_rate,  annot=False, center=0.5, xticklabels=weekday)     
    plt.show()

if __name__ == '__main__':
    main()

●get_ohlc関数
BitMEXからohlcデータを取得します。

BitMEXからでなければならない理由は特にありません。
1時間足であれば他の取引所のデータでも問題ありません(別途取得のためのコードは必要ですが)。

各引数は
cur:シンボル("XBTUSD"など)
bin:ohlc時間足(本プログラムでは'1h'のみ対応)
count:取得ohlc数(※1)
page:取得ohlc数(※1)

(※1)取得するohlcの本数はcount * (page+1)本となります。

●utc2jst関数
BitMEXからの取得データのtimestampはUTCなので、JSTに変換しています。
BitMEX以外のデータを入力する場合は、
"datetime.strptime(time_in , '%Y-%m-%dT%H:%M:%S.%fZ')"
の部分を各データのフォーマットに合うように修正してください。

●main関数
BitMEXよりohlc1時間足データを取得し、各時間帯ごとに終値ー始値を計算して、結果がプラスになればプラスとしてカウント、0以下ならばマイナスとしてカウントしています。
データ数を変更したい場合は、以下のget_ohlc内の引数を変えてください。
"df_1h = get_ohlc('XBTUSD', '1h', 240, 5)"

最後に、各時間帯ごとにカウントした結果をヒートマップで出力します。seabornで出力しています。ヒートマップをカスタマイズしたい場合は以下のサイトを参考にしてください。
https://seaborn.pydata.org/generated/seaborn.heatmap.html

例えば、ヒートマップの値を出したい場合は"annot=True"とすれば、以下のようにマップ内に数値を表示することができます。

以上で説明を終わります。

Discussion