最適レバレッジの近似式の誤差

ケリー基準を用いた最適レバレッジでは近似式による計算がよく使われていると思う。

近似式は

最適レバレッジ = リターンの平均 / (リターンの標準偏差 * リターンの標準偏差)

となっている。

本来の式はレバレッジについて級数展開して求めることができるが、レバレッジが小さい場合、第3項以降は無視できるほど小さくなるので、近似式では初めの2項を用いて求めている。つまり、レバレッジが小さくない場合、近似式はかなり大きな誤差を生じることになる。細かい点については以下のページがとても参考になる。

http://www.geocities.jp/y_infty/management/criterion_3.html

私はこれまで、どのくらいの誤差があるのかということを確かめることはせずに近似式を用いてきたが、レバレッジをx、累積リターンをyとした場合のグラフを作成すると、yが最大値となるxと近似式による最適レバレッジとの間になかなか無視できない誤差が時として生じることに気が付いた。そこで、どのくらいの誤差があるのかということを確かめてみた。

ここに1トレード当たりの期待利益が0.1%、リスクが0.5%の戦略があるとする。近似式を用いると最適レバレッジは0.001 / (0.005 * 0.005) = 40.0となる。この戦略に基づいて100回トレードを行うシミュレーションを繰り返し、その中から誤差の小さいものと大きいものとを選んでみた。

誤差の小さい場合

先ずは誤差が小さい場合の例を見てみよう。

誤差は0.01以下で、この程度の誤差であれば確かに無視してもよさそうだ。

誤差の大きい場合

次に誤差が大きい場合を見てみる。

誤差は15以上で大きいといえば大きいが、より問題であるのは近似式での最適レバレッジが本来の最適レバレッジでは破産レベルになっていることだ。これはさすがに無視できない。

近似式は使わないべきか

このように書くと、近似式は恐くて使えないという誤解を与えてしまうかもしれない。だが、このような誤差は何十回もシミュレーションをして、ようやく1回見かけるくらいレアなものである。また、レバレッジが小さくても誤差が大きい場合や逆にレバレッジが大きくても誤差が小さい場合もあるが、やはり近似式の性質上、レバレッジが大きいほど誤差も大きい傾向がある。

FXは日本国内では規制によってレバレッジ25倍までとなっているし、この程度のレバレッジなら、誤差も大したことはない。したがって、日本国内の規制にしたがったトレードをしている限り、近似式で問題ないだろう。

サンプルプログラム

○以下のコマンドをSpyderの「IPython console」にコピー&ペーストして「Enter」キーを2回押す。

# coding: utf-8
import matplotlib.pyplot as plt
import numpy as np

trades = 100
ret = np.random.normal(0.001, 0.005, trades)
x = np.array(range(1, 101))
y = np.zeros(trades)
for i in range(trades):
    if i == 0:
        y[i] = 1.0 * (1.0 + ret[i])
    else:
        y[i] = y[i-1] * (1.0 + ret[i])
    if y[i] < 0.0:
        y[i] = 0.0
mean = np.mean(ret)
std = np.std(ret)
kelly = mean / (std * std)
ax=plt.subplot()
plt.plot(x, y)
plt.xlabel('Trades')
plt.ylabel('Equity curve')
plt.text(0.05, 0.9, 'Kelly Approximation = ' + str(kelly),
         transform=ax.transAxes)
plt.savefig('optimal_leverage1.png', dpi=150)
plt.show()
plt.close()

n = 10000
equity_curve = np.empty(trades)
x = np.array(range(n)) / 100
y = np.empty(n)
for j in range(n):
    leverage = j / 100
    for i in range(trades):
        if i == 0:
            equity_curve[i] = 1.0 * (1.0 + ret[i] * leverage)
        else:
            equity_curve[i] = equity_curve[i-1] * (1.0 + ret[i] * leverage)
        if equity_curve[i] < 0.0:
            equity_curve[i] = 0.0
    y[j] = equity_curve[trades-1]
argmax = np.argmax(y)
ax=plt.subplot()
plt.plot(x, y)
plt.axvline(x=kelly, color='green')
plt.axvline(x=x[argmax], color='green')
plt.axhline(y=1.0, color='red')
plt.xlabel('Leverage')
plt.ylabel('Balance')
plt.text(0.05, 0.9, 'Kelly = ' + str(x[argmax]), transform=ax.transAxes)
plt.text(0.05, 0.85, 'Kelly Approximation = ' + str(kelly),
         transform=ax.transAxes)
plt.savefig('optimal_leverage2.png', dpi=150)
plt.show()
plt.close()
(2016/10/28更新)

コメント

非公開コメント