-
-
Save anirudhjoshi/1215859 to your computer and use it in GitHub Desktop.
Monte Carlo simulation of the payoffs to angel investing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
# | |
# Monte Carlo simulation of the payoffs to angel investing. | |
# | |
# Assume a pool of N different investors, each investing in D deals, | |
# with a fixed time horizon and a fixed distribution of payoffs. | |
# Randomly simulate each investor's total payoff, then compute the | |
# mean and std dev of all IRRs in the overall pool. | |
# | |
# This gives an individual angel an idea of what kind of payoff & | |
# variance to expect from investing in a certain # of deals. | |
# | |
# Written by Jeff Miller @jmillerinc. | |
# | |
# See: http://jmillerinc.com/2010/04/27/angel-investing-simulation | |
# | |
# Payoff distribution from http://www.gabrielweinberg.com/blog/2010/03/ | |
# angel-investing-portfolio-scenario-planner-spreadsheet.html | |
import math | |
import optparse | |
import random | |
DEFAULT_NUM_INVESTORS = 10000 | |
DEFAULT_NUM_DEALS = 20 | |
NUM_YEARS = 5 | |
PROBS = [.50, .20, .15, .13, .02] | |
PAYOFFS = [ 0, 1, 3, 10, 20] | |
def random_draw(cum_probs): | |
"""Randomly draw from a discrete distribution with the given | |
cumulative probabilities. Return the index of the probability | |
bucket that was drawn.""" | |
z = random.random() | |
for i, p in enumerate(cum_probs): | |
if z <= p: | |
return i | |
raise Exception('Execution should never reach this point: ' + | |
'cumulative probabilities are invalid.') | |
def cumulative_probabilities(probs): | |
"""Given a discrete distribution as a list of probabilities, | |
return the list of cumulative probabilities.""" | |
result = [sum(probs[0:i+1]) for i in range(len(probs))] | |
assert abs(result[-1] - 1.0) < 1e-6 | |
return result | |
if __name__ == '__main__': | |
option_parser = optparse.OptionParser() | |
option_parser.add_option('-n', type='int', dest='num_investors', default=DEFAULT_NUM_INVESTORS, | |
metavar='N', help='Simulate N investors (default %d)' % DEFAULT_NUM_INVESTORS) | |
option_parser.add_option('-d', type='int', dest='num_deals', default=DEFAULT_NUM_DEALS, | |
metavar='D', help='Simulate D deals per investor (default %d)' % DEFAULT_NUM_DEALS) | |
options, args = option_parser.parse_args() | |
num_investors = options.num_investors | |
num_deals = options.num_deals | |
# Simulate N investors doing D deals each. | |
n = 0 | |
summ = 0.0 | |
summ2 = 0.0 | |
cum_probs = cumulative_probabilities(PROBS) | |
deal_size = 1.0/float(num_deals) | |
for i in range(num_investors): | |
total_payoff = sum(deal_size * PAYOFFS[random_draw(cum_probs)] for j in range(num_deals)) | |
irr = pow(total_payoff, 1.0/NUM_YEARS) - 1 | |
summ += irr | |
summ2 += irr*irr | |
n += 1 | |
mean_irr = summ/n | |
std_irr = math.sqrt((summ2 - summ*summ/n)/(n-1)) | |
print 'N = %5d D = %3d mean_irr = %8.4f std_irr = %8.4f' % (num_investors, num_deals, mean_irr, std_irr) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment