Quote:
Originally Posted by self
Yes, buy-in is $3.50 ($3.19+0.31 rake, which is ~9.71%)
1st pays $12.45 and 2nd is $6.69
Thanks for the reply.
Ok. I've got some info for you.
Here are the results:
Code:
Results
Sims 1000.0000000
BuyIn 3.5000000
BR (in Buyins) 40.0000000
ROI % 10.2549714
SD 4.6981403
Trad. Ruin % 1.0534346
Iter. Ruin % 0.8533218
Sim. Ruin % 0.7000000
Sim. Win % 99.3000000
First, note that the Ruin % are in percentage. So 1.05 is 1.05%. Not 105%. But basically all three methods indicate that you have around a 1% Risk of Ruin (assuming all of your information is accurate).
There are three ruin % here including the Traditional Ruin % and the Simulated Ruin %. They are the same as before. The third Ruin % is the Iter. Ruin % is done through the use of iterative methods. I have written a sub-function that calls it:
Code:
RoR.iter <- function(prizes, probs, BI, BR) {
if(sum(prizes < 0) > 0) {stop("Prizes must not be below 0.")}
prizes.BI <- prizes/BI
BR.BI <- BR/BI
ROI.BI <- sum((prizes.BI-1)*probs)
ifelse(ROI.BI < 0, R <- 1, R <- uniroot(function(x) sum(probs*x^prizes.BI) - x, c(0,.9999999), tol=1e-70)$root)
RoR <- R^BR.BI
return(RoR)
}
The key here is finding the value R because R
number of BIs in bankroll is the Risk of Ruin. Finding the value of R is complicated and iterative methods are used to find it (i.e. "try a value and see if it works, if not adjust and find a better fitting value, stop when the fit is good."). Iterative methods are great unless there is more than one solution. For most of the problems we are talking about there is only one best solution though.
The advantage of the RoR.iter() is that it never goes over 100% (like the traditional RoR sometimes does). It is well behaved.
In any case, the new RoR.sim() function includes this sub-function:
Code:
RoR.sim <- function(prizes, probs, BI, BR, win=5*BR, sims=1000) {
if(BR < BI) {stop("BR must be higher than BI.")}
if(sum(prizes < 0) > 0) {stop("Prizes must not be below 0.")}
if(sum(probs) != 1) {stop("Finish probabilities do not total 1.00. Please adjust input probabilities.")}
if(length(prizes) != length(probs)) {stop("prizes and probs must be the same length (have the same number of elements).")}
ROI <- sum((prizes-BI)*probs) / BI
VAR <- sum((prizes-BI)^2 * probs) - ROI^2
if(sims==FALSE) {
tradRoR <- exp(-2*(ROI*BI)*BR/VAR)
iterRoR <- RoR.iter(prizes, probs, BI, BR)
out <- rbind("ROI %"=ROI, "Trad. Ruin %"=tradRoR*100, "Iter. Ruin %"=iterRoR)
colnames(out) <- "Results"
return(out)
}
res <- rep(NA, sims)
print("Simulating...please wait")
for (i in 1:sims) {
simBR <- BR
if(i == .25*sims) {print("25% of sims complete.")}
if(i == .5*sims) {print("50% of sims complete.")}
if(i == .75*sims) {print("75% of sims complete.")}
while(simBR >= BI & simBR < win) {
simBR <- simBR + sample((prizes-BI), 1, T, prob=probs)
}
res[i] <- simBR
}
tradRoR <- exp(-2*ROI*BI*BR/VAR)
iterRoR <- RoR.iter(prizes, probs, BI, BR)
out <- rbind(sims, BI, BR/BI, ROI*100, sqrt(VAR), tradRoR*100, iterRoR*100, (sum(res < BI) / sims)*100, (sum(res >= win) / sims)*100)
rownames(out) <- c("Sims", "BuyIn", "BR (in Buyins)", "ROI %", "SD", "Trad. Ruin %", "Iter. Ruin %", "Sim. Ruin %", "Sim. Win %")
colnames(out) <- "Results"
return(out)
}
So you have to run the RoR.iter() function first (to store it in R) for the RoR.sim() function to work.
But here is the code I used with the functions for your data:
Code:
RoR.sim(prizes=c(12.45, 6.69, 0, 0, 0 , 0), probs=c(.1538, .2906, .2051, .1282, .1538, .0685), BI=3.5, sims=1000, BR=40*3.5, win=1000)
Notice now that you list "prizes" instead of "profits." I think this makes the function more user-friendly. The downside is that you have to explicitly list the BI now, but that is okay in my opinion.
Here is another function I built to examine situations where you are going to play X amount of MTTs and you have a particular finish distribution. This function assumes you can always afford to play another (so it isn't a risk of ruin calculator). It is really useful for understanding variability in MTTs. It draws pretty graphs as well.
Code:
MTT.sim <- function(prizes, probs, BI, games=1000, sims=1000, CI=.95, plots=500, ignore.prob=F) {
if(sum(prizes < 0) > 0) {stop("Prizes must not be below 0.")}
if(ignore.prob==F) {
if(sum(probs) != 1) {stop("Finish probabilities do not total 1.00. Please adjust input probabilities. Or set ignore.prob==T.")}
}
if(length(prizes) != length(probs)) {stop("prizes and probs must be the same length (have the same number of elements).")}
if(CI >= 1.0 | CI <= 0) {stop("CI must be between .00 and 1.00.")}
LL <- 1-CI / 2
UL <- 1-LL
profits <- prizes - BI
profits.BI <- profits / BI
ROI <- sum(profits*probs) / BI
ROI.BI <- sum(profits.BI*probs)
ITM <- sum(probs[prizes>0])
VAR <- sum(profits^2 * probs) - ROI^2
VAR.BI <- sum(profits.BI^2 * probs) - ROI.BI^2
res <- matrix(nrow=games, ncol=sims)
cumres <- matrix(nrow=games, ncol=sims)
dswings <- rep(NA, sims)
uswings <- rep(NA, sims)
for(i in 1:sims) {
res[,i] <- sample(profits, games, T, prob=probs)
cumres[,i] <- cumsum(res[,i])
dswings[i] <- max(rle(res[,i])$lengths[rle(res[,i])$values<0])
uswings[i] <- max(rle(res[,i])$lengths[rle(res[,i])$values>0])
}
cumres.BI <- cumres / BI
op <- par(mfrow=c(2,2), font.main=1)
plot(cumsum(rep(ROI*BI,games)), type="l", lty=5, lwd=4, xlim=c(0,games),
ylim=c(min(cumres) - 3*BI, max(cumres) + 3*BI), main=paste(plots, " Simulated Profits"),
xlab="Tournaments", ylab="Profits ($)")
for(j in 1:plots) {
lines(cumres[,j], col=sample(sims, sims, T))
}
lines(cumsum(rep(ROI*BI,games)), type="l", lty=5, lwd=4)
legend("topleft", legend="Expected Line", col="black", lty=5, bty="n", lwd=4)
plot(density(cumres[games,]), main="Distribution of Profits", ylab="Density", xlab="Profits ($)", col="green")
polygon(density(cumres[games,]), col="green")
plot(cumsum(rep(ROI.BI,games)), type="l", lty=5, lwd=4, xlim=c(0,games),
ylim=c(min(cumres.BI) - 3, max(cumres.BI) + 3), main=paste(plots, " Simulated Profits"),
xlab="Tournaments", ylab="Profits (BuyIns)")
for(j in 1:plots) {
lines(cumres.BI[,j], col=sample(sims, sims, T))
}
lines(cumsum(rep(ROI.BI,games)), type="l", lty=5, lwd=4)
legend("topleft", legend="Expected Line", col="black", lty=5, bty="n", lwd=4)
plot(density(cumres.BI[games,]), main="Distribution of Profits", ylab="Density", xlab="Profits (BuyIns)", col="green")
polygon(density(cumres.BI[games,]), col="green")
out.reg <- rbind(sims, games, BI, ITM*100, ROI*100, sqrt(VAR),
min(cumres[games,]), quantile(cumres[games,],UL), mean(cumres[games,]),
median(cumres[games,]), quantile(cumres[games,],LL), max(cumres[games,]),
max(dswings), max(uswings), ((sum(cumres[games,] < 0))/sims)*100)
out.BI <- rbind(sims, games, 1, ITM*100, ROI.BI*100, sqrt(VAR.BI),
min(cumres.BI[games,]), quantile(cumres.BI[games,],UL), mean(cumres.BI[games,]),
median(cumres.BI[games,]), quantile(cumres.BI[games,],LL), max(cumres.BI[games,]),
max(dswings), max(uswings), ((sum(cumres.BI[games,] < 0))/sims)*100)
out <- cbind(out.reg, out.BI)
colnames(out) <- c("Results $", "Results BIs")
rownames(out) <- c("Simulations", "Tournies per Sim", "BuyIn", "ITM %", "ROI %", "SD", "Worst Profit",
"CI Lowerbound", "Avg. Profit", "Median Profit", "CI Upperbound", "Best Profit",
"Longest OOTM Streak", "Longest ITM Streak", "% Finishes with Loss")
return(out)
}
Running it on your data I get the following results (1000 simulations of playing 1000 $3.50 STTs):
Code:
MTT.sim(prizes=c(12.45, 6.69, 0, 0, 0 , 0), probs=c(.1538, .2906, .2051, .1282, .1538, .0685), BI=3.5)
Results $ Results BIs
Simulations 1000.00000 1000.000000
Tournies per Sim 1000.00000 1000.000000
BuyIn 3.50000 1.000000
ITM % 44.44000 44.440000
ROI % 10.25497 10.254971
SD 4.69814 1.338724
Worst Profit -89.51000 -25.574286
CI Lowerbound 354.61000 101.317143
Avg. Profit 364.47523 104.135780
Median Profit 365.20000 104.342857
CI Upperbound 373.57000 106.734286
Best Profit 815.08000 232.880000
Longest OOTM Streak 25.00000 25.000000
Longest ITM Streak 12.00000 12.000000
% Finishes with Loss 0.20000 0.200000