ビットコインの一日の終値はボリンジャーバンド±2σの範囲内に何%収まっているのか?

ボリンジャーバンドは単純移動平均(SMA)と、それと終値の差の標準偏差を使って、移動平均を表す線とその上下に値動きの幅を示す線を加えた指標です。
高い確率で価格の大半がこの帯(バンド)の中に収まるだろうという予測をもとに、将来の価格を予測するために使います。

統計学によれば、

ボリンジャーバンドの±1σの範囲内に収まる確率 → 約68.3%
ボリンジャーバンドの±2σの範囲内に収まる確率 → 約95.4%
ボリンジャーバンドの±3σの範囲内に収まる確率 → 約99.7%

となるようです。

でも、そんなにおさまってなくね??
ブレイクアウトはよくあるし、1σ線や2σ線に沿うような動き(バンドウォーク)もあるので、価格がバンド内で収まっている確率は実際は理論値より低いのでは?
と思ったので、実際に集計してみました。

2019年~2022年までのビットコインの日足データを使って終値がボリンジャーバンド内にどれだけ収まるか計算してみました。(binance現物BTC/USDTペア)

結果は、

ボリンジャーバンドの±1σの範囲内に収まる確率 → 約48.2%
ボリンジャーバンドの±2σの範囲内に収まる確率 → 約88.1%
ボリンジャーバンドの±3σの範囲内に収まる確率 → 約99.0%

見事に少ない!!
2σをはみ出る確率は一割を超えるようです。
ボリンジャーバンドだけを信じて逆張りをするのは厳禁ということですね。
統計学の理論値は価格がランダムに動くことを想定しているので、それからずれるということは、ランダムでない要素が価格変動に含まれていることを示唆しています。暴騰・暴落時には何かしらランダムではない一方的な力が働いているのでしょうか。

以下は計算に使ったpythonコードです。
使うには予めccxtライブラリをインストールして下さい。

import ccxt 
import pandas as pd
import datetime
from time import sleep

def get_past_data_from_binance(candles_num, end_day, symbol, barsymbol, bar):
    binance = ccxt.binance()
    data_n = 500 #binanceで一度にとれるろうそく足の本数
    data_m = (candles_num + data_n - 1)// data_n
    data_l = candles_num % data_n
    pastdata = pd.DataFrame([])
    for i in range(0, data_m):
        sleep(0.01)
        period = data_l + data_n * (data_m - i - 1)
        data = get_past_data(binance, symbol, barsymbol, bar, period, end_day)
        data.index = list(range(len(pastdata), len(pastdata) + len(data)))
        pastdata = pd.concat([pastdata, data])
    pastdata.columns = ["timestamp", "open", "high","low","close","volume"]
    timestamp = [datetime.datetime.utcfromtimestamp(int(pastdata['timestamp'][i]/1000)) for i in range(len(pastdata))]
    pastdata['datetime'] = timestamp
    return pastdata
def get_past_data(exchange, symbol, barsymbol, bar, period, end_day):
    timest = day_to_unixtime(end_day)
    timest = timest - (period-1)*bar*60*1000
    candles = exchange.fetch_ohlcv(symbol, timeframe=barsymbol, since=timest, limit=min(500,period))
    pd_candles = pd.DataFrame(candles)
    return pd_candles
def day_to_unixtime(date_str):
    # date_str = '2018-02-01 12:30:00' or date_str = '2018-02-01'
    l = len(date_str.split())
    if l == 1:
        date_str = date_str + " 00:00:00"
    time = pd.to_datetime(date_str)
    return int(time.timestamp() * 1000)
        
if __name__ == '__main__':
    # 取得するろうそく足の本数
    candles_num = 365*4 + 1
    # テスト終了日
    end_day = "2022-12-31"
    # 通貨ペア
    symbol = "BTC/USDT"
    # ろうそく足の期間
    barsymbol = "1d"
    # ろうそく足の期間(分)
    bar = 24*60
    # binanceのAPIからろうそく足を取得します
    pd_candles = get_past_data_from_binance(candles_num, end_day, symbol, barsymbol, bar)
    # 終値
    close = pd_candles["close"]
    # ボリンジャーバンドの中心
    mid = close.rolling(window=20).mean()
    # 標準偏差
    std = close.rolling(window=20).std()
    # ボリンジャーバンドの+1σ線
    hi1 = mid + std
    # ボリンジャーバンドの-1σ線
    lo1 = mid - std
    # ボリンジャーバンドの+1σ線
    hi2 = mid + 2*std
    # ボリンジャーバンドの-1σ線
    lo2 = mid - 2*std
    # ボリンジャーバンドの+1σ線
    hi3 = mid + 3*std
    # ボリンジャーバンドの-1σ線
    lo3 = mid - 3*std

    count = 0
    count_s1 = 0
    count_s2 = 0
    count_s3 = 0
    
    for i in range(len(close)):
        if pd.isna(mid[i]): # 欠損値を除く
            continue
        count += 1
        if lo1[i]<close[i]<hi1[i]:
            count_s1 += 1
        if lo2[i]<close[i]<hi2[i]:
            count_s2 += 1
        if lo3[i]<close[i]<hi3[i]:
            count_s3 += 1

    print('-1σ~+1σ:',100*count_s1/count,'%')
    print('-2σ~+2σ:',100*count_s2/count,'%')
    print('-3σ~+3σ:',100*count_s3/count,'%')


〇宣伝〇

【Bybit】日本人にも人気のある、世界トップレベルの仮想通貨取引所
無料登録はこちら:https://www.bybit.com/register?affiliate_id=22416&group_id=0&group_type=1
☆高金利ステーキング
☆デュアル資産投資で短期オプション取引を始めよう
☆豊富なレバレッジトークンの取り扱い

【Binance】世界最大の仮想通貨取引所
無料登録はこちら:https://accounts.binance.com/en/register?ref=KJWM1JMM
☆上記リンクからの登録で取引手数料10%OFF
☆350種類以上の取扱コイン
☆豊富なセービングとステーキング

【ApeX pro】Metamaskで接続するだけで取引開始!!いま注目のDEX先物取引所!!
登録はこちら:https://affiliates.pro.apex.exchange/b/mochimochi
紹介コード: mochimochi
☆自分の資金は自分で管理!これからはDEXの時代!?
☆積極的にトレードすることでボーナスが貰える、トレードマイニング

この記事が気に入ったらサポートをしてみませんか?