ファイナンス機械学習:戦略リスク 非対称のペイアウト
ここで、前記事と違うのは、年間$${n}$$回の内$${i}$$ベットの結果$${X_i}$$が利益$${\pi_+}$$となる確率が$${p}$$、損失$${\pi_-}$$となる確率が$${1-p}$$である時、$${\pi_- < \pi_+}$$ で、$${|\pi_-| \ne \pi_+}$$であることである。
よって、$${X_i}$$の期待値と分散は、
$${E[X_i]=p\pi_++(1-p)\pi_-}$$
$${V[X_i]=E[X_i^2]-E[X_i]^2=p\pi_+^2+(1-p)\pi_-^2 - (p\pi_++(1-p)\pi_-)^2= p(1-p)(\pi_+- \pi_-)^2}$$
これから、年率換算シャープレシオは
$${\theta=\displaystyle{\frac{nE[x_i]}{\sqrt{nV[X_i]}} = \frac{(\pi_+-\pi_-)P+\pi_-}{(\pi_+-\pi_-)\sqrt{p(1-p)}} \cdot\sqrt{n}}}$$
と与えられる。
当然ながら、$${|\pi_-| = \pi_+}$$であれば、対称ペイアウトと同じ式となる。
$${0\le p \le 1}$$で、上式を解けば
$${(\pi_+-\pi_-)^2(n+\theta^2)p^2 + (\pi_+-\pi_-)(2n\pi_--\theta^2(\pi_+-\pi_-))p + n\pi_-^2=0}$$から、
$${a=(\pi_+-\pi_-)^2(n+\theta^2)}$$
$${b=(\pi_+-\pi_-)(2n\pi_--\theta^2(\pi_+-\pi_-))}$$
$${c=n\pi_-^2}$$
として、
$${p=\displaystyle{\frac{-b+\sqrt{b^2-4ac}}{2a}}}$$となる。
$${[\pi_-,\pi_+,n]}$$で特徴づけられる取引ルールが、与えられた$${\theta^\ast}$$を達成するのに必要な最低の正確度を計算するコードがスニペット15.3で与えられている。
def binHR(ptsl, freq, tSR):
pt=ptsl[0]
sl=ptsl[1]
a = (freq + tSR ** 2) * (pt - sl) ** 2
b = (2 * freq * sl - tSR ** 2 * (pt - sl)) * (pt - sl)
c = freq * sl ** 2
p = (-b + (b ** 2 - 4 * a * c) ** 0.5) / (2.0 * a)
return p
同様に、$${[\pi_-,\pi_+,p]}$$で特徴づけられる取引ルールが、与えられた$${\theta^\ast}$$を達成するのに必要な最低のベット頻度を計算するコードがスニペット15.4で与えられている。
def binFreq(ptsl, p, tSR):
pt=ptsl[0]
sl=ptsl[1]
freq = (tSR * (pt - sl)) ** 2 * p * (1 - p) / ((pt - sl) * p + sl) ** 2
return freq
これから、利益確定閾値が$${\pi_+=.01}$$で、目標シャープレシオを$${\theta^\ast=1.5}$$とした時、損失確定値$${-0.01 \le \pi_- \le 0}$$、ベット頻度を年間10から100まで変化させた時に必要とされる正確度をヒートマップにしたのが以下のコードと図である。
from itertools import product
sl=np.linspace(-0.01,0,21)
pt=.01
srt=1.5
ann=250**.5
Fs=np.arange(10,100,2)
minP=[]
for comb_ in product(sl,Fs):
ptsl=[pt,comb_[0]]
p=binHR(ptsl=ptsl,freq=comb_[1],tSR=srt)
minP.append((comb_[0],comb_[1],p))
columns=['sl','frq','prob']
df=pd.DataFrame(minP,columns=columns)
mp=df.prob.to_numpy().reshape(len(sl),-1)
print(Fs[0], Fs[-1], sl[0], sl[-1])
plt.imshow(mp,cmap='viridis', extent=(Fs[0], Fs[-1], sl[0], sl[-1]),
aspect='auto',interpolation='nearest',origin='lower')
plt.xlabel('Bit Frequency')
plt.ylabel('Bottom Barrier')
plt.colorbar()
損失確定値$${-0.01 \le \pi_- \le 0}$$、正確度を$${0.5\le p \le 0.6}$$とした時に、必要とされるベット頻度をヒートマップにしたのが以下のコードと図である。
sl=np.linspace(-0.005,0,21)
pt=.01
srt=1.5
ann=250**.5
prob=np.linspace(0.5,0.6,21)
minF=[]
for comb_ in product(sl,prob):
ptsl=[pt,comb_[0]]
f=binFreq(ptsl=ptsl,p=comb_[1],tSR=srt)
minF.append((comb_[0],comb_[1],f))
columns=['sl','prob','freq']
df=pd.DataFrame(minF,columns=columns)
mf=df.freq.to_numpy().reshape(len(sl),-1)
plt.imshow(mf,cmap='viridis', extent=(prob[0], prob[-1], sl[0], sl[-1]),
aspect='auto',interpolation='nearest',origin='lower')
plt.xlabel('precision')
plt.ylabel('Bottom Barrier')
plt.colorbar()