ファイナンス機械学習:金融データ構造 練習問題 ボリンジャーバンドとCUSUM

E-mini S&P 500先物ドルバーに対し、移動平均周り5%のボリンジャーバンドを計算し、価格がバンドの内側から外側へ移行する回数を数え、その時をイベントとし、価格系列をサンプリングする。ここでは移動平均のスパンを20バーと取っている。

def getBBand2(data_df, span, alp):
    BB_df=data_df
    BB_df['TP']=(data_df['High']+data_df['Low']+ddf['Close'])/3
    BB_df['SMA'] = data_df['TP'].rolling(window=span).mean()
    sig = pd.Series(data_df['SMA']).rolling(span, min_periods=span).std()
    BB_df['BB_u'], BB_df['BB_d'] = (data_df['SMA']*(1+alp)), (data_df['SMA']*(1- alp))
    return BB_df.dropna()

def countCross(BB):
    BBcross=[]
    count=0
    for i in range(1,len(BB)):
        if( BB['Close'][i]>BB['BB_u'][i] and 
            BB['Close'][i-1]<BB['BB_u'][i-1] ):
            count+=1
            BBcross.append(BB.index[i])
        if( BB['Close'][i-1]>BB['BB_d'][i-1] and 
            BB['Close'][i]<BB['BB_d'][i]):
            count+=1
            BBcross.append(BB.index[i])
    return count,BBcross

ddf_BB=get_BB_band2(ddf,20,0.05)
count, BBcrossId=countCross(ddf_BB)
BB_price=ddf_BB.loc[BBcrossId]['Close']

同じドルバーに対し、CUSUMフィルタを使用し、$${y_t}$$をリターンとして、$${h=0.05}$$とする。

def getTEvents(gRaw, h) :
    tEvents, sPos, sNeg = [], 0, 0
    diff = gRaw.diff()
    for i in diff.index[1:]:
        sPos, sNeg = max(0, sPos + diff.loc[i]), min(0, sNeg + diff.loc[i])
        if sNeg < -h:
            sNeg = 0
            tEvents.append(i)
        elif sPos > h:
            sPos = 0
            tEvents.append(i)
    return pd.DatetimeIndex(tEvents)

ddf_rtn = ddf['Close'].pct_change().dropna()
events=getTEvents(ddf_rtn, 0.05)
CUSUM_price=ddf.loc[events]['Close']

ボリンジャーバンド、CUSUMでのイベント数は、以下の通りである。

イベント数

この二つのサンプル系列の移動標準偏差を計算する。スパンは25とした。

plt.plot(CUSUM_price.rolling(25).std().dropna()[datetime(2012, 8, 1):], label='CUSM')
plt.plot(BB_price.rolling(25).std().dropna(),label='BB 5%')
plt.legend()
移動標準偏差

CUSUMの偏差の方が小さく、不均一性が小さいとわかる。

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