ファイナンス機械学習:E-mini S&P 先物 Tick imbalance Bar
tick ruleを適用して、$${b_t}$$の系列を作る。
def bt(p0,p1,b):
if np.fabs(p1-p0) <= 1e-04:
return b
else:
return np.abs(p1-p0)/(p1-p0)
def get_imbalance(data):
bs=np.zeros_like(data)
for i in np.arange(1,bs.shape[0]):
t_bt=bt(data[i-1],data[i],bs[i-1])
bs[i-1]=t_bt
return bs[:-1]
$${b_t}$$を用いて、前記事のサンプル取得時の条件$${|\theta_T| \ge E_0[T]|2P[b_t=1]-1|}$$が成り立つindex$${i_s}$$、サンプル取得間のバー数を返すコードは以下の通り。
def get_Imb_Ts(dbv,ET_0,i_prev0):
Ts,i_s=[],[]
i_prev=i_prev0
theta=dbv[0]
th=np.zeros_like(dbv)
abs_theta=np.zeros_like(dbv)
threds=np.zeros_like(dbv)
thres=ET_0*np.abs(pd.Series(dbv[:ET_0]).ewm(span=ET_0).mean().iloc[-1])
with tqdm(range(1,len(dbv))) as pbar_dbv:
for i in pbar_dbv:
theta+=dbv[i]
abs_theta[i]=np.abs(theta)
threds[i]=thres
if(abs_theta[i]>=thres) and (i>i_prev):
theta=0
Ts.append(np.float64(i-i_prev))
E_t=pd.Series(Ts).ewm(span=len(Ts)).mean().iloc[-1]
abs_Ebv=np.abs(pd.Series(dbv[:i]).ewm(span=(i-i_prev)*E_t).mean().iloc[-1])
i_s.append(i)
i_prev=i
thres=E_t*abs_Ebv
#print(i,Ts[-1],E_t,abs_Ebv,thres)
return Ts, i_s,abs_theta, threds
最初に推定されるバー数の期待値$${E_T0}$$と、サンプル計測前の$${i_{prev0}}$$を与える。
$${E_0[T]}$$の前のバーまでのバーごとの取引数のEWMAのスパン(ウィンドウ)サイズは、それまでのサンプル取得数とし、$${2P[b_t=1]-1}$$のスパンは、これから計算されるバーに含まれると期待される取引数と、一つ前の実際の取引数の積とした。
Imbarance Barの取得は、ループの中に、EWMAの計算が二箇所も入っているため、計算機負荷が高い。
そのため、E-mini S&P 先物のtickデータを、10年分、元データの約1/3に絞って行った。
price=SP_data.loc['2009-01-01':]['price']
tick_im=get_imbalance(price)
print(len(price),len(tick_im),tick_im.mean())
Ts, i_s, abs_theta, threds=get_Imb_Ts(tick_im,5000,2000)
plt.plot(abs_theta[25000:30000],label='abs theta')
plt.plot(threds[25000:30000],label='threads')
plt.legend()
plt.show()
$${b_t}$$の累積和の絶対値$${|\theta_T| }$$と、閾値$${E_0[T]|2P[b_t=1]-1|}$$の$${T^{\ast}}$$計算中の動きは、以下のグラフの通りである。
$${|\theta_T| }$$が上昇下降を繰り返し、閾値を超えたところで、ゼロに戻り、新しいバーに入ったことが確認できる。
この記事が気に入ったらサポートをしてみませんか?