# Doing more Monte Carlo Simulations - Kelly Criterion Project

Hi,

Just started out coding. Was doing a project to test out the Kelly Criterion, a betting system that determines what is the best allocation of your portfolio should you stake for an investment, given the odds and payoffs.

``````import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import decimal as d

# Probablility of winning
# Probablity of loss is 1-W
def kelly(Per,P,L):

Per=d.Decimal(Per).quantize(d.Decimal('1.000'))
P=d.Decimal(P).quantize(d.Decimal('1.000'))
L=d.Decimal(L).quantize(d.Decimal('1.000'))

opt= (Per/L)-((1-Per)/P)
return opt

# Per=0.6

# # Profit of event in percentage. 1+P would be the percentage amount won
# P= 0.2

# # Loss during event in percentage. 1-L is the loss for your portfolio
# L=0.2

# Using The Kelly Function

Here is an example on how to use it

a=kelly(0.6,0.2,0.2)

First variable is the % odds of profit. Between 0-1, goes to max 3 dp

Second variable is the profit if the bet is correct. Can be any positive number. Note this is 1-payoff

Third variable is the loss during event in percentage. Can be any positive number. Note this is 1-loss
PercentageOfOdds = 0.6

Profit = 1

Loss = 1

#Betting percentage for the differnet scenarios

a = kelly(PercentageOfOdds,Profit,Loss)

b = a/2 # Half Kelly

c = a*2 # Double Kelly

# Creating the monte carlo simulation with the for statements

Saving all results in a list before changing it to a dataframe

#Starting capital
amtf=d.Decimal('1')
amth=d.Decimal('1')
amtd=d.Decimal('1')

#changing the profit and loss float numbers to decimal
P=d.Decimal(Profit).quantize(d.Decimal('1.000'))
L=d.Decimal(Loss).quantize(d.Decimal('1.000'))

# List to store the simulations
fullk=[]
halfk=[]
doubk=[]

# Simulating the different senarios

for i in range(10000):
r=np.random.random()

# if the bet is in your favour

if(r<PercentageOfOdds):
amtf = amtf+amtf*P*a
amth = amth+amth*P*b
amtd = amtd+amtd*P*c

fullk.append(amtf)
halfk.append(amth)
doubk.append(amtd)

# If you lose the bet

else:
amtf = amtf-amtf*L*a
amth = amth-amth*L*b
amtd = amtd-amtd*L*c

fullk.append(amtf)
halfk.append(amth)
doubk.append(amtd)

df1=pd.DataFrame(fullk, columns = ['Full Kelly'], dtype=float)
df2=pd.DataFrame(halfk, columns = ['Half Kelly'], dtype=float)
df3=pd.DataFrame(doubk, columns = ['Double Kelly'], dtype=float)

#Printing the results

results = pd.concat([df1, df2,df3], axis=1)
results

results.plot()
plt.yscale("log")
``````

I’m trying to do a monte carlo simulation in python for half kelly (kelly criterion), full kelly, and 2X kelly.

Seems like I hit a limit of around 10,000 simulations and the amount generated is too large; it becomes infinity. I’m trying to see if it is possible to do 100,000> simulations is a way to do that?

Is there a better way to do mote carlo simulations?

All advice is welcome!

Thanks

I mean, for a start - don’t use Python lists. They take up a ton more memory because they lack strong typing. So you’re better off directly creating a dataframe and adding the values in there.

Oh ok will change that then. The code runs fine in terms of speed so far. Just that the numerical limit is hot when I run 10000 loops.

Can you show us the exact error you’re getting.

I ran your code several times with no errors and 10,000 iterations. Good job!
I do hit a `RuntimeWarning` upon graphing the results when raising the iterations to 100,000 however (unsurprisingly as many values are getting converted to np.Inf in the dataframe).

You can use `sys.float_info.max` to get the maximum value for floats.
You might have better luck using integers for large values where decimal precision might not be very important (memory allowing). Since these are profits, let’s consider USD. Is storing 10 cents on \$12,000,000.10 valuable in this particular use case? Maybe use decimal precision up till a certain amount then switch to integer precision if you can get away with it?
For instance, this will throw an `OverflowError` for me: `float(1 * 10**309)`. But this is perfectly acceptable on my system: `int(1 * 10**5000)`.
Alternatively you can store large floats as strings but I don’t think that will solve your issue here. Thanks for looking at my code! Yeah, my issue is with the np.Inf value in the data frame.

I tried to change it to an interger as suggested buy because the probability is in decimal, seems like it will change the integer to decimal after I multiply it together?

So should I just change it back to the integer at the end of the loop before appending it to the list?

Actually it seems like pandas tries to convert large integers into floats anyway. Decimal objects that are larger than a C long fail to be cast into int on my system; they can be cast to float as Inf.

Perhaps the string method is the easiest way to go here.
E.g.

``````df1 = pd.DataFrame(fullk, columns = ['Full Kelly'], dtype = str)
df1['converted'] = df1['Full Kelly'].apply(d.Decimal)
``````

This allows you to store the data in a DataFrame to work with, but honestly I think you’ll lose a lot functionality this way. I don’t think vector math will work on Decimal objects and plotting will still likely not work.

I think these values might just be too large for working with many Python libraries.

1 Like

Yeah that makes sense. Perpahs doing monte carols like is not the best in python

Thanks for all the help!

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.