Kelly Criterion
Introduction
The Kelly criterion is a mathematical formula for bet sizing, which is frequently used by investors to decide how much money they should allocate to each investment or bet through a predetermined fraction of assets. This approach is valid when the expected returns are known. The Kelly bet size is found by maximizing the expected value of the logarithm of wealth, which is equivalent to maximizing the expected geometric growth rate. It was described by J. L. Kelly Jr, a researcher at Bell Labs, in 1956.
A lot of variations of the classical Kelly Criterion have been proposed. We will specifically take a look at four of these proposed methods:
-
Continuous-Time Kelly, which is derived from the classical case by taking a continuous probability distribution of outcomes into consideration, rather than a discrete one.
-
Optimal Allocation Kelly, which builds on top of the continuous time case by taking \(n\) assets into account, and derives its formulas from linear algebra.
-
Risk Constrained Kelly (RCK), which imposes an additional constraint by limiting the probability of a drawdown above a certain threshold. There are two variations of RCK:
-
The Finite Risk Constraint Kelly, where the are a finite amount of outcomes.
-
The General Risk Constraint Kelly,where there are an infinite amount of outcomes.
-
Discrete-Time Kelly
An overview of the theory behind the Kelly Criterion is given here. For a more detailed explanation, see Thorp, E. O. (2011).
Say we want wager even money bets made on i.i.d bets of a biased coin . Let \(p>1 / 2\) be the probability of winning and \(q=1-p\), the probability of losing. Let \(X_{0}\) be the initial capital. Suppose we choose the goal of maximizing the expected value \(E\left(X_{n}\right)\) after \(n\) trials. How much should we bet, \(B_{k}\), on the \(k\) th trial? Denote \(T_{k}=1,\) if the \(k\) th trial is a win and if \(T_{k}=-1,\) if it is a loss. Therefore \(X_{k}=X_{k-1}+T_{k} B_{k}\) for \(k=1,2,3, \ldots\), and \(X_{n}=X_{0}+\sum_{k=1}^{n} T_{k} B_{k}\). And we obtain
Let us bet according to \(B_i = f X_{i−1}\), where \(0 \le f \le 1\) is the fixed fraction of wealth we are betting. Let \(S\) and \(F\) denote the number of successes and failures respectively. Then we have \(X_n = X_0(1+f)^{S}(1-f)^{F}\). We can write \(e^{n log [\frac{X_n}{X_0}]^{\frac{1}{n}}}\), where \(G(f) = log[\frac{X_n}{X_0}]^{\frac{1}{n}}\) is the exponential rate of increase. Kelly chose to maximize the expected value of the growth rate coefficient, \(g(f)\), where
Calculating the derivative of \(g(f)\) and setting equal to zero we find the optimal size bet for fastest growth as
The Kelly criterion can easily be extended to uneven payoffs. Suppose we win \(b\) units for every unit wager and lose \(a\) units. Further, suppose that on each trial the win probability is \(p > 0\) and \(m = bp − aq > 0\) so that the game is advantageous. We again maximize \(g(f)\) to obtain
It is well known that Kelly optimal bets can lead to substantial drawdown risk. One ad hoc method for handling this is to compute a Kelly optimal bet \(f^{\star}\), and then use the so-called fractional Kelly bet given by
\[f= cf^{\star}\]
where \(c \in(0,1)\) is the fraction. The fractional Kelly bet scales down the (risky) bets by \(c\). Fractional Kelly bets have smaller drawdowns than Kelly bets, at the cost of reduced growth rate. We will see that trading off growth rate and drawdown risk can be more directly (and better) handled.
Continuous-Time Kelly Bet Sizing
When applying the Kelly criterion to securities markets, a new analytic problems is encountered. A bet on a security typically has many outcomes. This leads to the use of continuous instead of discrete probability distributions. Therefore we need to find, \(f\), as to maximize \(g(f ) = E [ln(1 + f)] = \int (1 + f x) dP (x)\), where \(P (x)\) is a probability measure describing the outcomes. Frequently the problem is to find an optimum portfolio from among \(n\) securities.
Let \(X\) be a random variable with \(P(X=m+s)=P(X=m-s)=0.5\). Then \(E(X)=m, \operatorname{Var}(X)=s^{2}\). With initial capital \(V_{0}\), betting fraction \(f\), and return per unit of \(X\), the result is
where \(r\) is the rate of return on the remaining capital. Then
Now subdivide the time interval into \(n\) equal independent steps, keeping the same drift and the same total variance. Thus \(m, s^{2}\) and \(r\) are replaced by \(m / n, s^{2} / n\) and \(r / n\), respectively. We have \(n\) independent \(X_{i}, i=1, \ldots, n\), with
Taking \(E(\log (\cdot))\) of both sides gives \(g(f)\). Expanding the result in a power series leads to
The following is a summary of results derived
Implementation
- class ContinuousTimeKelly(returns: array, risk_free_rate: float = 0, trading_days: int = 252)
-
ContinuousTimeKelly implements the continuous-time approximation to the kelly criterion.
As presented in The Kelly Criterion in Blackjack Sports Betting and The Stock Market by Edward O. Thorp.
- __init__(returns: array, risk_free_rate: float = 0, trading_days: int = 252)
-
Initialize ContinuousTimeKelly class with needed parameters.
- Parameters:
-
-
returns – (np.array) Returns vector for n assets.
-
risk_free_rate – (float) Yearly risk-free rate to use in calculations.
-
trading_days – (int) Number of trading days in a year.
-
- capital_growth_std(bet_size: float) float
-
Computes the capital growth standard deviation given the bet size.
\[Sdev(G_{\infty}(f)) = sf\]Where s is the standard deviation of the mean returns and f is the bet size.
- Parameters:
-
bet_size – (float) Kelly bet size (\(f\)).
- Returns:
-
(float) Expected growth rate standard deviation (\(Sdev(G_{\infty}(f))\)).
- expected_capital_growth_rate(bet_size: float = 1.0) float
-
Computes the expected capital growth rate given the bet size.
\[g_{\infty}(f) = r + f(m - r) - s^2f^2/2\]Where f is the bet size, m is the mean returns, r is the risk-free rate, and s is the standard deviation.
- Parameters:
-
bet_size – (float) Kelly bet size (\(f\)).
- Returns:
-
(float) Expected capital growth rate (\(g_{\infty}\)).
- optimal_bet_size(fraction: float = 1.0) float
-
Computes optimal kelly bet size.
\[cf^* = c(m - r) / s^2\]Where c is the fractional value, m is the mean returns, r is the risk-free rate, and s is the standard deviation.
- Parameters:
-
fraction – (float) Fractional kelly value (\(c\)).
- Returns:
-
(float) Optimal kelly bet size.
- optimal_capital_growth_std(fraction: float = 1.0) float
-
Computes the optimal capital growth standard deviation.
\[Sdev(G_{\infty}(cf^*)) = c(m - r) / s\]Where m is the mean returns, r is the risk-free rate, c is the fractional kelly value, \(f^*\) is the optimal kelly bet, and s is the standard deviation.
- Parameters:
-
fraction – (float) Fractional kelly value (\(c\)).
- Returns:
-
(float) Expected capital growth rate standard deviation (\(Sdev(G_{\infty}(cf^*))\)).
- optimal_expected_capital_growth_rate(fraction: float = 1.0) float
-
Computes the optimal expected capital growth rate.
\[g_{\infty}(cf*) = ((m - r)^2(c - c^2/2))/s^2 + r\]Where c is the fractional value, f* is the optimal kelly bet, m is the mean returns, r is the risk-free rate, and s is the standard deviation.
- Parameters:
-
fraction – (float) Fractional kelly value (\(c\)).
- Returns:
-
(float) Optimal expected capital growth rate (\(g_{\infty}\)).
- optimal_time_to_growth(std_k: int, fraction: float) float
-
Computes the time it will take an investment to grow larger than the initial invested amount with a confidence \(k\) standard deviations for a given bet size.
\[t_k = k^2c^2((m - r)^2/s^2)/((m - r)^2/s^2(c - c^2/2) + r)^2\]- Parameters:
-
-
std_k – (float) Standard deviations of confidence (\(k\)).
-
fraction – (float) Fractional kelly value (\(c\)).
-
- Returns:
-
(float) Time \(t_k\) to achieve optimal growth at \(k\) confidence.
- time_to_growth(bet_size: float, std_k: int) float
-
Computes the time it will take an investment to grow larger than the initial invested amount with a confidence \(k\) standard deviations for a given bet size.
\[t_k = k^2s^2f^2/g_{\infty}^2\]Where k is the standard deviation for the investment to be larger than the invested amount, \(f\) is the kelly bet size, \(g_{\infty}\) is the expected capital growth rate, and s is the standard deviation of the returns.
- Parameters:
-
-
bet_size – (float) Kelly bet size (\(f\)).
-
std_k – (float) Standard deviations of confidence (\(k\)).
-
- Returns:
-
(float) Time \(t_k\) to achieve growth at \(k\) confidence.
Examples
# Importing tools
import matplotlib.pyplot as plt
from mlfinlab.datasets.load_datasets import load_stock_prices
from mlfinlab.bet_sizing.kelly import ContinuousTimeKelly
# Lets load some securities prices
prices = load_stock_prices().iloc[:, [6,8]]
# Here we are getting the returns for the past 1000 days
returns = prices.iloc[-1000:,:].pct_change().dropna()
# Plot the prices to inspect
plt.plot(prices.iloc[-1000:,])
plt.legend(returns.columns.values)
# Initialise class with risk free rate = 0.03, by default it is 0
ck = ContinuousTimeKelly(returns, risk_free_rate = 0.03)
# Get the optimal bet size
optimal_bet = ck.optimal_bet_size()
# Use fractional kelly betting with c = 0.5
half_kelly_bet = ck.optimal_bet_size(fraction=0.5)
# Now we can get the expected capital gowth rate g(f) and the std of g(f)
expected_growth = ck.optimal_expected_capital_growth_rate()
expected_growth_std = ck.optimal_capital_growth_std()
Optimal Allocation Kelly
Let’s now consider the case of determining the optimal bet sizes given a portfolio of \(n\) securities. Let \(f_{0}\) be a riskless security with return \(r\) and \(f_{1}, \ldots, f_{n}\) the portfolio fractions, where \(f_{0} +\cdots+f_{n}=1\). Let \(C=\left(s_{i j}\right)\) be the matrix such that \(s_{i j}, i, j=1, \ldots, n\), is the covariance of the \(i\) th and \(j\) th securities and \(M=\left(m_{1}, m_{2}, \ldots, m_{n}\right)^{T}\) be the row vector such that \(m_{i}, i=1, \ldots, n\), is the drift rate of the \(i\) th security. Then the portfolio satisfies
where \(F^{T}=\left(f_{1}, \ldots, f_{n}\right)\) and \(T\) means “transpose”, and \(R\) is the column vector \((r, r, \ldots, r)^{T}\) of length \(n\).
The previous results for one security plus a riskless security thus apply to \(g_{\infty}\left(f_{1}, \ldots, f_{n}\right)=m-s^{2} / 2\). This is a standard quadratic maximization problem. Using the equation for \(s^2\) and solving the simultaneous equations \(\partial g_{\infty} / \partial f_{i}=0, i=1, \ldots, n\), we get
where for a unique solution we require \(C^{-1}\) to exist, i.e., \(\operatorname{det} C \neq 0\). When all the securities are uncorrelated, \(C\) is diagonal and we have \(f_{i}^{*}=\left(m_{i}-r\right) / s_{i i}\) or \(f_{i}^{*}= \left(m_{i}-r\right) / s_{i}^{2}\).
Warning
Due to instability when inverting the covariance matrix, the
OptimalAllocationKelly
class will work best with a small (max. 5 or 6) number of securities or portfolio strategies.
Implementation
- class OptimalAllocationKelly(returns: DataFrame, risk_free_rate: float = 0, trading_days: int = 252)
-
OptimalAllocationKelly implements the placing of many bets across different portfolios of securities of trading strategies in order to achieved maximum capital growth.
- __init__(returns: DataFrame, risk_free_rate: float = 0, trading_days: int = 252)
-
Document parameters, expose trading days option.
- capital_growth_rate(f_allocate=None, fraction: float = 1.0) float
-
Returns capital growth rate for the betting allocation.
\[g(F^*) = r + F^{T}CF/2\]- Parameters:
-
-
f_allocate – (float) The betting (allocation) vector specified.
-
fraction – (float) Fractional kelly value.
-
- Returns:
-
(float) Capital growth rate.
- optimal_betting_vector(fraction: float = 1.0) array
-
Computes optimal betting vector across n portfolios of securities or trading strategies.
\[F = C^{-1}[M - R]\]- Parameters:
-
fraction – (float) Fractional kelly value.
- Returns:
-
(np.array) Optimal betting vector.
- sharpe_ratio(f_allocate=None, fraction: float = 1.0) float
-
Returns sharpe ratio for optimal betting allocation.
\[S = \sqrt{F^{*T}CF^*}\]- Parameters:
-
-
f_allocate – (float) The betting (allocation) vector specified.
-
fraction – (float) Fractional kelly value.
-
- Returns:
-
(float) Sharpe ratio.
Examples
# Importing tools
from mlfinlab.bet_sizing.kelly import OptimalAllocationKelly
from mlfinlab.datasets.load_datasets import load_stock_prices
# Get returns for 3 assets / securities
prices = load_stock_prices().iloc[-1000:, [-1,-4,-12]]
returns = prices.pct_change().dropna()
# Get optimal bet allocation
kelly = OptimalAllocationKelly(returns,risk_free_rate = 0.02)
bet_allocation = kelly.optimal_betting_vector()
# Get the growth rate and sharpe ratio for optimal bet.
growth_rate = kelly.capital_growth_rate()
sharpe_ratio = kelly.sharpe_ratio()
Risk-Constrained Kelly Bet Sizing
As in the previous sections, say we want to place a fixed fraction of our total wealth (assumed positive) on \(n\) bets. We denote the fractions as \(f \in \mathbf{R}^{n}\), so \(f \geq 0\) and \(\mathbf{1}^{T} f=1\), where \(\mathbf{1}\) is the vector with all components 1 . Denoted \(r \in \mathbf{R}_{+}^{n}\), so the wealth after the bet changes by the (random) factor \(r^{T} b\). This means that \(f_{0}\) represents the fraction of our wealth that we do not wager, or hold as cash. The bet vector \(f=e_{0}\) corresponds to not betting at all.
As was the case in the previous section, we want \(f\) to maximize \(\mathbf{E} \log \left(r^{T} f\right)\), the growth rate of wealth. We can also state the maximization problem as
with variable \(f\). We call a solution \(f{*}\) of this problem a set of Kelly optimal bets. The Kelly gambling problem is always feasible, since we could have \(f=e_{n}\) (which corresponds to not placing at all).
We can look at Risk-Constrained Kelly bet sizing which simply adds additional constraints on the formulation above in order to limit downside risk. A brief overview of the methodology is given here. For a more detailed explanation please see Busseti, E., Ryu, E.K. and Boyd, S., 2016.
Let \(W_{t} = X_t/X_0\), i.e the return on the initial investment at time \(t\). Define the minimum wealth as the infimum of the wealth trajectory over time,
In this case we define the drawdown as \(1-W^{\min }\), while we define drawdown risk as \(\operatorname{Prob}\left(W^{\min }<\alpha\right)\), where \(\alpha \in(0,1)\) is a given target (undesired) minimum wealth. This risk depends on the bet vector \(f\) in a very complicated way. There is in general no formula for the risk in terms of \(f\), but we can always (approximately) compute the drawdown risk for a given \(f\) using Monte Carlo simulation. As an example, a drawdown risk of \(0.1\) for \(\alpha=0.7\) means the probability of experiencing more than \(30 \%\) drawdown is only \(10 \%\). The smaller the drawdown risk (with any target), the better.
We can add a drawdown risk constraint to the Kelly maximization problem formulated earlier, to obtain
with variable \(f\), where \(\alpha, \beta \in(0,1)\) are given parameters. The last constraint limits the probability of a drop in wealth of value \(\alpha\) to be no more than \(\beta\).
We can now derive a condition that bounds the drawdown risk. Consider any \(\lambda>0\) and bet \(b\). For any \(\alpha \in(0,1)\) and \(\beta \in(0,1)\) that satisfies \(\lambda=\log \beta / \log \alpha\) we have
Replacing the drawdown risk constraint in the problem with \(\lambda=\log \beta / \log \alpha\), yields the risk-constrained Kelly gambling problem (RCK).
Finite Risk-constrained Kelly Criterion
For the finite outcomes case we can restate the RCK problem in a convenient and tractable form. We first take the \(\log\) of the last constraint and get
where \(\pi_{i}\) is the probability of the $i$’th outcome, we then write it as
To see that this constraint is convex we note that the log-sum-exp function is convex and increasing, and its arguments are all convex functions of \(f\) (since \(log(r_t^T f)\) is concave), so the lefthand side function is convex in f. Thus we have
The implementation is reformulated as a quadratic approximation of the RCK problem, which the authors call the quadratic RCK problem (QRCK), to which it can be shown that it has a close connection to Markowitz portfolio optimization.
Implementation
- class FiniteRiskConstrainedKelly(returns_r: array, probabilities_pi: array, n_outcomes: int, alpha: float = 0, beta: float = 0, lambda_risk: float = 0)
-
FiniteRiskConstrainedKelly implements risk constrained kelly betting for finite returns.
As presented in Risk-Constrained Kelly Gambling by Busseti, Ryu and Boyd.
- __init__(returns_r: array, probabilities_pi: array, n_outcomes: int, alpha: float = 0, beta: float = 0, lambda_risk: float = 0)
-
Initialize FiniteRiskConstrainedKelly class with needed parameters.
- Parameters:
-
-
returns_r – (np.array) Returns vector for n assets.
-
probabilities_pi – (np.array) Probabilities (\(\pi\)) vector of returns for n assets.
-
n_outcomes – (np.array) Number of outcomes (\(k\)).
-
alpha – (float) Max target drawdown (\(\alpha\)).
-
beta – (float) Probability of drawdown (\(\beta\)).
-
lambda_risk – (float) Risk-aversion parameter (\(\lambda\)).
-
- optimal_bet_size(asset_n: int, fraction: float = 1.0) float
-
Select optimal bet size for the n-th asset.
- Parameters:
-
-
asset_n – (int) The n-th asset in the betting vector.
-
fraction – (float) Fractional kelly bet value.
-
- Returns:
-
(float) Bet size.
- optimal_betting_vector(fraction: float = 1.0) array
-
Returns optimal betting vector.
- Parameters:
-
fraction – (float) Fractional kelly value.
- Returns:
-
(np.array) Optimal betting vector.
- optimal_quadratic_bet_size(asset_n: int, fraction: float = 1.0) float
-
Select optimal quadratic bet size for the n-th asset.
- Parameters:
-
-
asset_n – (int) The n-th asset in the betting vector.
-
fraction – (float) Fractional kelly bet value.
-
- Returns:
-
(float) Bet size.
- optimal_quadratic_betting_vector(fraction: float = 1.0) array
-
Returns optimal quadratic betting vector.
- Parameters:
-
fraction – (float) Fractional kelly value.
- Returns:
-
(np.array) Optimal quadratic betting vector.
Examples
# Importing tools
from mlfinlab.bet_sizing import FiniteRiskConstrainedKelly
from mlfinlab.util.bet_sizing import draw_batch_finite_returns
# Drawing sample returns
returns_r, probabilities_pi = draw_batch_finite_returns(seed=0)
outcomes = 100
alpha = 0.7
# Applying RCK
rck = FiniteRiskConstrainedKelly(returns_r, probabilities_pi, n_outcomes=outcomes,
alpha=alpha, beta=0.1)
mid_rck = FiniteRiskConstrainedKelly(returns_r, probabilities_pi, n_outcomes=outcomes,
lambda_risk=5.5)
no_constraint_rck = FiniteRiskConstrainedKelly(returns_r, probabilities_pi,
n_outcomes=outcomes,
lambda_risk=0)
# Checking results
rck_b = rck.optimal_betting_vector()
mid_rck_b = mid_rck.optimal_betting_vector()
no_rck_b = no_constraint_rck.optimal_betting_vector()
General Risk-constrained Kelly Criterion
For the case of general returns we can solve the RCK problem using a stochastic optimization method. A primal-dual stochastic gradient method applied to the Lagrangian
with \(f \in \Delta_{\varepsilon}\) and \(\kappa \geq 0\). (As in the unconstrained Kelly optimization case, we make the technical assumption that \(f_{n}^{*}>\varepsilon>0\).) In can be shown that the RCK problem has an optimal dual variable \(\kappa^{*}\) for the constraint \(\mathbf{E}\left(r^{T} f\right)^{-\lambda} \leq 1\), which implies that solving the RCK problem is equivalent to finding a saddle point of \(L(f, \kappa)\).
The implementation is reformulated as a quadratic approximation of the RCK problem, which the authors call the quadratic RCK problem (QRCK), to which it can be shown that it has a close connection to Markowitz portfolio optimization.
Implementation
- class GeneralRiskConstrainedKelly(returns: array, alpha: float = 0, beta: float = 0, lambda_risk: float = 0)
-
GeneralRiskConstrainedKelly implements risk constrained kelly betting for infinite returns.
As presented in Risk-Constrained Kelly Gambling by Busseti, Ryu and Boyd.
- __init__(returns: array, alpha: float = 0, beta: float = 0, lambda_risk: float = 0)
-
Initialize GeneralRiskConstrainedKelly class with needed parameters.
- Parameters:
-
-
returns – (np.array) Returns vector for n assets.
-
alpha – (float) Max target drawdown (\(\alpha\)).
-
beta – (float) Probability of drawdown (\(\beta\)).
-
lambda_risk – (float) Risk-aversion parameter (\(\lambda\)).
-
- optimal_bet_size(asset_n: int, fraction: float = 1.0) float
-
Select optimal bet size for the n-th asset.
- Parameters:
-
-
asset_n – (int) The n-th asset in the betting vector.
-
fraction – (float) Fractional kelly bet value.
-
- Returns:
-
(float) Bet size.
- optimal_betting_vector(fraction: float = 1.0) array
-
Returns optimal betting vector.
- Parameters:
-
fraction – (float) Fractional kelly value.
- Returns:
-
(np.array) Optimal betting vector.
- optimal_quadratic_bet_size(asset_n: int, fraction: float = 1.0) float
-
Select optimal quadratic bet size for the n-th asset.
- Parameters:
-
-
asset_n – (int) The n-th asset in the betting vector.
-
fraction – (float) Fractional kelly bet value.
-
- Returns:
-
(float) Bet size.
- optimal_quadratic_betting_vector(fraction: float = 1.0) array
-
Returns optimal quadratic betting vector.
- Parameters:
-
fraction – (float) Fractional kelly value.
- Returns:
-
(np.array) Optimal quadratic betting vector.
Examples
# Importing tools
from mlfinlab.bet_sizing.kelly import FiniteRiskConstrainedKelly
from mlfinlab.util.bet_sizing import draw_batch_finite_returns
# Drawing sample returns
sample_returns = draw_batch_infinite_returns(seed=10)
alpha = 0.7
# Applying RCK
rck = GeneralRiskConstrainedKelly(sample_returns, alpha=alpha, beta=0.1)
mid_constrained_rck = GeneralRiskConstrainedKelly(sample_returns, lambda_risk=5.7)
no_constraint_rck = GeneralRiskConstrainedKelly(sample_returns, lambda_risk=0)
# Checking results
rck_b = rck.optimal_betting_vector()
mid_rck_b = mid_constrained_rck.optimal_betting_vector()
no_rck_b = no_constraint_rck.optimal_betting_vector()
Monte Carlo Utilities
The following utilities are adapted from Busseti et. al (2016). from their notebooks for Risk-Constrained Kelly Gambling. You might want to use these utilities to validate your risk-constrained kelly betting results via method of simulations.
Helper utilities for Kelly criterion bet sizing research.
- compute_drawdown_probability(w_mins: array, alpha: float) float
-
Computes probability of a drawdown greater than target alpha of minimum wealth. Defined as the drawdown risk.
\[\boldsymbol{Prob}(W^{min} < \alpha)\]- Parameters:
-
-
w_mins – (np.array) Array with welath trajectories.
-
alpha – (float) Desired target \(\alpha\) for which we want to avoid dropping our minimium wealth.
-
- Returns:
-
(float) Probability of drawdown for given target.
- compute_wealth_miniminums(logw_samples: array) array
-
Returns the minimum wealth (\(W^{min}\)) trajectories from the log returns.
- Parameters:
-
logw_samples – (np.array) Log of cumulative wealth returns.
- Returns:
-
(np.array) Wealth trajectories.
- draw_batch_finite_returns(n_draws: int = 20, outcomes: int = 100, seed: int = 0) Tuple[array, array]
-
Function performs
n_draws
for \(K\) possibleoutcomes
.Probabilities are sampled from a uniform distribution on [0, 1]. The 30 returns are sampled uniformly as well from [0.7, 1.3]. The probability that a return vector \(r\) contains at least one “extreme” return (e.g. 0.2 or 2) is approximately 0.45.
Returns a tuple of returns \(r\) and probabilities \(\pi\).
- Parameters:
-
-
n_draws – (int) Number of draws to perform (e.g. n - 1 assets or securities)
-
outcomes – (int) Number of \(K\) outcomes
-
seed – (int) Seed for random number generator.
-
- Returns:
-
(Tuple[np.array, np.array]) Tuple of returns \(r\) and probabilities \(\pi\)
- draw_batch_infinite_returns(n_draws: int = 20, draws: int = 1000000, seed: int = 0) array
-
Function performs a batch of
n_draws
(e.g. each draw is the nth asset) where for each draw a sample ofdraws
number of returns is produced.For infinite returns we draw from a mixture of lognormals.
- Parameters:
-
-
n_draws – (int) Number of draws to perform (e.g. n assets or securities).
-
draws – (int) Number of observations to sample for each draw.
-
seed – (int) Seed for random number generator.
-
- Returns:
-
(np.array) Array of
n_draws
each havingdraws
number of sample returns.
- empirical_cdf(samples: array, grid: array) array
-
Returns the observed cumulative distribution function for the log returns.
- Parameters:
-
-
samples – (np.array) Sample of log returns.
-
grid – (np.array) Series to which accumulate the log returns.
-
- Returns:
-
(np.array) Cumulative distribution function (CDF) for the log returns.
- growth_rate_wealth_mins(logw_samples: array) float
-
Returns average growth rate of log wealth returns.
- Parameters:
-
logw_samples – (np.array) Log of wealth returns for n assets.
- Returns:
-
(float) Growth rate of wealth.
- sample_monte_carlo_finite_returns(returns_r: array, probabilities_pi: array, n_samples: int = 10000, mc_time: int = 100) array
-
Sample returns for finite distributions. This is function is used to perform monte carlo simulations for the
FiniteRiskConstrainedKelly
class.- Parameters:
-
-
returns_r – (np.array) Sample asset returns.
-
probabilities_pi – (np.array) Sample probabilities of returns.
-
n_samples – (int) Number of samples to draw.
-
mc_time – (int) Monte carlo time.
-
- Returns:
-
(np.array) Simulated returns.
- sample_monte_carlo_infinite_returns(n_samples: int = 10000, mc_time: int = 100, n_assets: int = 20) array
-
Sample returns for infinite distributions. This is function is used to perform monte carlo simulations for the
GeneralRiskConstrainedKelly
class.- Parameters:
-
-
n_samples – (int) Number of samples.
-
n_assets – (int) Number of assets.
-
mc_time – (int) Monte carlo time.
-
- Returns:
-
(np.array) Simulated returns.
- simulate_trajectories(sampled_returns: array, bet_vector_b: array) array
-
Simulate wealth trajectories for Kelly betting monte carlo simulations.
Function will take sampled returns and multiply by the betting vector produced by the given Kelly Criterion implementation.
- Parameters:
-
-
sampled_returns – (np.array) Sample returns for n assets.
-
bet_vector_b – (np.array) Bet size for n assets.
-
- Returns:
-
(np.array) Cumulative wealth returns for each asset given the bet size.
Research Notebook
The following research notebooks can be used to better understand Kelly Criterion bet sizing.