ファイナンス機械学習:ベットサイズの決定 動的なベットサイズと指値
トリプルバリア法において、時刻$${t_{i,0}}$$で形成され、その時点で予測される最近のバリアに触れる時間を$${t_{i,1}}$$、予測価格を$${E_{t_{i,0}}[p_{t_{i,1}}]}$$としている。このバリアに触れるまでの時間$${t\in[t_{i,0},t_{i,1}]}$$内で、価格$${p_t}$$は変動し、また予想価格も変動する。この変動に応じで、ベットサイズを調整し、注文の指値も得る方法を説明する。
現在のポジションを$${q_t}$$とし、ポジションサイズの絶対値の最大値を$${Q}$$とする。予測価格$${f_i}$$に関する目標ポジションサイズ$${\hat{q_{i,t}}}$$は以下のように計算される。
$${\hat{q}=int[m[\omega,f_i-p_t]Q}$$、
$${m[\omega,x]}$$はベットサイズであり、
$${m[\omega,x]=\displaystyle{\frac{x}{\sqrt{w+x^2}}}}$$、
$${x=f_i-p_t}$$は現在の予測価格と市場価格の乖離度とみなされる。
$${\omega}$$は広義のシグモイド関数の幅を調整する係数である。
目標ポシジョンサイズ$${\hat{q_{i,t}}}$$は、価格が変化するにつれ、動的に調整される。損失の実現化を避ける注文サイズ$${\hat{q_{i,t}}-q_t}$$に対する損益分岐点の指値価格$${\tilde{P}}$$は、$${m[\omega,f_i-p_i]}$$の$${p_t}$$に関する逆関数の$${L}$$、
$${\displaystyle{ L[f_i, \omega,m]=f_i - m\sqrt{\frac{\omega}{1-m^2}} }}$$を用いて、
$${\tilde{p}=\displaystyle{\frac{1}{|\hat{q_{i,t}}-q_t|} \tilde{P}}}$$ $${{\tilde{P}=\sum^{|\bar{q_{i,t}}|}_{j=|q_t+sgn[\hat{q_{i,t}}-q_t]|} L[f_i,w,\frac{j}{Q}]}}$$
となる。
シグモイド関数の幅の係数$${\omega}$$は、$${x=f_i-p_t}, m^\ast=m[\omega,x]$$の関数から、
$${\omega=x^2(m^{\ast-2}=1)}$$
となる。これを用いて、乖離度に対するベットサイズを調整する。
スニペット10.4で実装される動的なポジションサイズと指値のコードと共に、シグモイド関数の代わりに冪乗関数を使ったベットサイズの関数の実装が以下である。
def betSizeSig(w,x):
return x * (w + x ** 2) ** (-0.5)
def getTPos(w,f,mP,maxPos):
return int(betSizeSig(w, f - mP) * maxPos)
def invPrice(f,w,m):
return f - m * (w / (1 - m**2)) ** 0.5
def limitPrice(tPos,pos,f,w,maxPos):
sgn = (1 if tPos >= pos else -1)
lP = 0
for j in range(abs(pos + sgn), abs(tPos + 1)):
lP += invPrice(f, w, j / float(maxPos))
lP /= tPos - pos
return lP
def getW(x,m):
return x ** 2 * (m**(-2) - 1)
def betSizeSgn(w,x):
return np.sign(x) * abs(x) ** w
このコードを使い、価格乖離度10に対して$${m^\ast=95}$$のベットサイズを返すようにし、これを用いて、最大ポジション$${Q=100, f_i=115, p_t=100}$$に対する目標ポジションと指値を返すコードは以下の通りである。
pos, maxPos, mP, f, wParams = 0, 100, 100, 115, {'divergence': 10, 'm': 0.95}
w = getW(wParams['divergence'], wParams['m']) # calibrate w
Tpos = getTPos(w, f, mP, maxPos) # get target position
lP = limitPrice(Tpos, pos, f, w, maxPos) # limit price for order
print(f'Calibrated w: {w}')
print(f'Target position: {Tpos}')
print(f'Limit price for order: {lP}')
またシグモイド関数と冪乗関数を使ったベットサイズの乖離度の関数の比較は以下の通り(練習問題10.4)。
X = np.linspace(-1.0, 1.0, 1000)
width=0.1
power=2
bSize_sig=np.array([betSizeSig(width,x) for x in X])
bSize_sgn=np.array([betSizeSgn(power,x) for x in X])
plt.figure(figsize=(14,7))
plt.plot(X,bSize_sig,label='Sigmond')
plt.plot(X,bSize_sgn,label='Power')
plt.legend()
plt.xlabel('Price divergence')
plt.ylabel('Bet Size')
plt.show()