켈리 기준을 사용하여 최적의 베팅 크기 결정
최적의 베팅 크기를 결정하는 방법?
본 기사에서는, Stefan Jasen씨에 의해 쓰여진 "Machine Learning for Algorithmic trading, 2nd edition"의 Chapter 5, the Kelly Criterion 에 대해 공부한 내용을 정리해 갑니다.
1. The optimal size of a bet
켈리 기준은 무한히 반복되는 베팅에서 자본 가치의 성장률을 극대화하는 베팅 크기(optimal $f$)를 찾는 것을 목표로 합니다. 이 켈리 기준의 사고방식을 수식으로 떨어뜨리면 다음과 같이 됩니다.
V_n = V_{0}(1+of)^m(1-f)^{n-m}\\
G = lim_{n\rightarrow\infty}\frac{1}{n}log\frac{V_n}{V_0}\\
첫 번째 공식은 $n$번째 베팅 결과가 나온 시점에서 손에 남은 자본을 나타냅니다. 두 번째 방정식은 매번 베팅에서 자본 성장률을 의미하며 자본 성장률의 기하 평균의 로그를 취하는 형태입니다. 아래에서는 SymPy를 사용하여 optimal $f$를 계산합니다.
#変数を定義
share, odds, probability = sympy.symbols('share odds probability')
#資産の成長率を表す式を定義
G = probability*log(1+odds*share)+(1-probability)*log(1-share)
#Gをshareに関して微分したもの=0を、shareに関して解く
solve(diff(G,share),share)
#出力(期待値/odds)
[(odds*probability -(1- probability))/odds]
#odds=1でshare=f,probability=p,G=yに書き換えた形
f,p = sympy.symbols('f p')
y = p*log(1+f)+(1-p)*log(1-f)
solve(diff(y,f),f)
#出力、これがfに関するG'=0の最適解f。
2*p -1
2. Get data
이번에는 yahoofinance로부터 S&P500의 daily close price를 취득합니다. 기간은 2001-1-2~2020-12-31입니다. (사용하는 데이터는 Jansen씨와는 다릅니다.)
import pandas as pd
import numpy as np
from numpy.linalg import inv
from numpy.random import dirichlet
from sympy import symbols,solve,log,diff
from scipy.optimize import minimize_scalar,newton,minimize
from scipy.integrate import quad
from scipy.stats import norm
import yfinance as yf
import datetime
import matplotlib.pyplot as plt
GetSPYinfo = yf.Ticker("SPY")
#datetime.daterime()によりDateがDatetimeIndexとして認識される。
#同時にそれ以外のカラムはデータとして認識される。
startDate = datetime.datetime(2001,1,1)
endDate = datetime.datetime(2021,1,1)
df = GetSPYinfo.history(start = startDate, end = endDate)
3. Compute returns and standard deviation
이번에는 5년 이동평균과 표준편차를 계산하고 나서 평균치-2σ·평균치·평균치+2σ를 플롯해 나갑니다.
#年リターンを計算
Annual_returns =df_closed.resample('A').last().pct_change().dropna().to_frame('sp500')
#リターンの5年移動平均および標準偏差を計算
return_params = Annual_returns.rolling(5).agg(['mean','std']).dropna()
#.sp500をつけることで、meanとstdが列ラベルとして認識される。
return_params.sp500
#データフレームreturn_paramsの平均ラベルの列を抜き出して、そこに、平均±2σの列を付け足す。
return_params.sp500[['mean']]
return_ci = (return_params.sp500[['mean']]
.assign(lower=return_params.sp500['mean'].sub(return_params.sp500['std'].mul(2)))
.assign(upper=return_params.sp500['mean'].add(return_params.sp500['std'].mul(2))))
#各系列をプロット
plt.plot(return_ci['mean'], color = 'blue')
plt.plot(return_ci['lower'], color = 'orange')
plt.plot(return_ci['upper'], color = 'green')
labels = ['mean','mean-2sigma','mean+2sigma']
plt.legend(labels)
4. Apply Kelly rule to a single asset
The optimal size of a bet에서 자산 성장률 $G$를 나타내는 수식을 소개했습니다. 지금부터는 $E[G]$를 최대화하는 $f$를 scipy.optimize를 이용해 계산합니다.
E[G] =\int log(1+fr)P(r)dr\Leftrightarrow \frac{d}{df}E[G] = \int_{-\infty}^{\infty}\frac{r}{1+fr}P(r)dr = 0
#期待資本成長率を計算する関数を定義
def norm_integral(f,mean,std):
val, er = quad(lambda s:np.log(1+f*s)*norm.pdf(s,mean,std),mean-3*std, mean+3*std)
return -val
#期待資本成長率をfで偏微分する関数を定義
def norm_dev_integral(f,mean,std):
val,er = quad(lambda s:(s/(1+f*s))*norm.pdf(s,mean,std),m-3*std,mean+3*std)
return val
#期待資本成長率をfに関して最適化する関数を定義
#最適化に用いる(偏微分に用いる)変数f以外の変数をargsで指定
#bounds = [0,2]⇔ 掛け金の比率は0から200%に設定
def get_kelly_share(return_params):
solution = minimize_scalar(norm_integral,args=(return_params.sp500['mean'],
return_params.sp500['std']),
bounds=[0,2],method='bounded')
return solution.x
#年率リターンのdfに新たな列fを追加
Annual_returns['optimal f'] = return_params.apply(get_kelly_share, axis=1);
#meanとstdをプロット
return_params.plot(subplots=True,lw=2,figsize=(14,8));
#パフォーマンス評価
#[]だけだとpd.Seriesに変換され、[[]]だとpd.DataFrameに変換される。
print(return_params);
print(Annual_returns);
y = (Annual_returns[['sp500']].assign(kelly=Annual_returns['sp500'].
mul(Annual_returns['optimal f']))).dropna();
#sp500の累積リターンとKelly Criterionを適用した際の累積リターンをプロット
y.add(1).cumprod().sub(1).plot();
Reference
이 문제에 관하여(켈리 기준을 사용하여 최적의 베팅 크기 결정), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/Tokiwabashi_27/items/7c83d28312c4105048f2텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)