#!/usr/bin/perl -w use strict; # Inputs: # ./tax_lien_monte_cristo.pl # # e.g. # ./tax_lien_monte_cristo 10 1500 7 for 10 liens at a premium of 7% at $1500 each. # Price should not include premiums. if (@ARGV != 4) { print "Usage: \n"; exit; } my $num_liens = shift @ARGV; my $price = shift @ARGV; my $premium = shift @ARGV; my $meta_iterations = shift @ARGV; # print "Using $num_liens liens at an average price of $price; assuming a premium of $premium%\n"; # print "Landing a house assumes a return of 15x on the lien amount.\n\n"; # This is the per-month interest. my $interest = 0.0083; # Each bucket is expressed in terms of (month, percentage). The stimulation picks a percentage # and then picks a month that is less than the percentage but not less than the month preceding it. my $buckets = [ [ 1, 2.6393 ], [ 2, 6.039 ], [ 3, 9.3749 ], [ 4, 12.647 ], [ 5, 15.8553 ], [ 6, 18.9998 ], [ 7, 22.0805 ], [ 8, 25.0974 ], [ 9, 28.0505 ], [ 10, 30.9398 ], [ 11, 33.7653 ], [ 12, 36.527 ], [ 13, 39.2249 ], [ 14, 41.859 ], [ 15, 44.4293 ], [ 16, 46.9358 ], [ 17, 49.3785 ], [ 18, 51.7574 ], [ 19, 54.0725 ], [ 20, 56.3238 ], [ 21, 58.5113 ], [ 22, 60.635 ], [ 23, 62.6949 ], [ 24, 64.691 ], [ 25, 66.6233 ], [ 26, 68.4918 ], [ 27, 70.2965 ], [ 28, 72.0374 ], [ 29, 73.7145 ], [ 30, 75.3278 ], [ 31, 76.8773 ], [ 32, 78.363 ], [ 33, 79.7849 ], [ 34, 81.143 ], [ 35, 82.4373 ], [ 36, 83.6678 ], [ 37, 84.8345 ], [ 38, 85.9374 ], [ 39, 86.9765 ], [ 40, 87.9518 ], ]; my $results = {}; for (my $meta_iter = 0; $meta_iter < $meta_iterations; $meta_iter+=1) { my $subtax = 0; my $total_profit = 0.0; my $iteration = 1; my $negative = 0; my $premium_amount = $price * ($premium / 100.0); my $total_principal = $premium_amount * $num_liens; my $houses = 0; for (my $x = 0; $x < $num_liens; $x+=1) { my $percent = rand(100); my $prior = 0.0; my $month = 0; foreach my $bucket (@$buckets) { $month = $bucket->[0]; if ($percent > $prior && $percent <= $bucket->[1]) { #print "Iteration $iteration fits month $month; got $percent\n"; last; } $prior = $bucket->[1]; } my $house = $month == @$buckets; my $principal = $price; # Principal to start with. This gets added on to every subtax. my $total = $price; # Running total. my $profit = 0.0; unless ($house) { # We don't have a house. Calculate the profits here. my $monthly = $principal * $interest; # Monthly accrual. Increases with subtax. for (my $i = 0; $i < $month; $i+=1) { # Time to subtax? if ($i >= 10 && (($i - 10)%12)==0) { $subtax += 1 if $i < 12; # Principal gets the price added on. $principal = $principal + $price; # Total increments by the price. $total = $total + $price; # Monthly gets updated as a function of the total. $monthly = $total * $interest; } # Add onto the monthly. $total += $monthly; } # Now calculate the premium. $profit = $total - $principal - $premium_amount; my $premium_formatted = sprintf "%.2f", $premium_amount; my $total_formatted = sprintf "%.2f", $total; my $profit_formatted = sprintf "%.2f", $profit; my $percent = $profit / $principal * 100; my $percent_formatted = sprintf "%.2f", $percent; $total_principal = $total_principal + $principal; $negative = $negative + 1 if ($profit < 0.0); $total_profit = $profit + $total_profit; # print "Iteration $iteration: Took $month months; accumulated $total_formatted; profit $percent_formatted% after premium of $premium_formatted = $profit_formatted\n"; } else { $houses = $houses + 1; $principal = $price * 3; $total_principal = $total_principal + $principal; $total = $price * 15; $profit = $price * 15.00; $total_profit = $profit + $total_profit; my $profit_formatted = sprintf "%.2f", $profit; # print "Iteration $iteration: Took 40 months; we foreclosed and got a 15x return of $profit_formatted\n"; } $iteration = $iteration + 1; } #print "\n"; my $principal_formatted = sprintf "%.2f", $total_principal; my $profit_formatted = sprintf "%.2f", $total_profit; my $percent = $total_profit / $total_principal * 100; my $percent_formatted = sprintf "%.2f", $percent; my $result = {}; $result->{profit} = $total_profit; $result->{percent} = $percent; $result->{houses} = $houses; $result->{negative} = $negative; $result->{principal} = $total_principal; $result->{subtax} = $subtax; $results->{$meta_iter} = $result; # print "For $num_liens liens, we had $negative liens with a negative return, got $houses houses, total outlay of \$$principal_formatted (including premiums and subtaxations) and made a profit of \$$profit_formatted or $percent_formatted%\n"; #print "$meta_iter,$negative,$houses,$principal_formatted,$profit_formatted,$percent_formatted\n"; } # Make averages. my $avg_profit = 0.0; my $avg_houses = 0.0; my $avg_negative = 0.0; my $avg_principal = 0.0; my $lost_money = 0.0; my $no_house_avg_profit = 0.0; my $no_house_avg_principal = 0.0; my $no_house_iter = 0.0; my $lost_money_nh = 0.0; my $avg_subtax = 0.0; foreach my $result (values %$results) { $lost_money += 1 if $result->{profit} < 0.0; $avg_profit += $result->{profit}; $avg_houses += $result->{houses}; $avg_negative += $result->{negative}; $avg_principal += $result->{principal}; $avg_subtax += $result->{subtax}; next if $result->{houses}; $no_house_iter += 1; $lost_money_nh += 1 if $result->{profit} < 0.0; $no_house_avg_principal += $result->{principal}; $no_house_avg_profit += $result->{profit}; } my $final_subtax = $avg_subtax / $meta_iterations; my $final_subtax_pct = $final_subtax / $num_liens; my $final_subtax_formatted = sprintf "%.2f", $final_subtax; my $final_subtax_pct_formatted = sprintf "%.2f", $final_subtax_pct; my $final_profit_nh = $no_house_iter > 0 ? $no_house_avg_profit / $no_house_iter : 0.0; my $final_principal_nh = $no_house_iter > 0 ? $no_house_avg_principal / $no_house_iter : 0.0; my $final_loss_nh = $no_house_iter > 0 ? $lost_money / $no_house_iter * 100 : 0.0; my $percent_nh = $no_house_iter > 0 ? $final_profit_nh / $final_principal_nh * 100 : 0.0; my $final_profit = $avg_profit / $meta_iterations; my $final_houses = $avg_houses / $meta_iterations; my $final_negative = $avg_negative / $meta_iterations; my $final_loss = $lost_money / $meta_iterations * 100; my $final_principal = $avg_principal / $meta_iterations; my $no_house_iter_avg = $no_house_iter / $meta_iterations * 100; my $percent = $final_profit / $final_principal * 100; my $percent_formatted = sprintf "%.2f", $percent; my $profit_formatted = sprintf "%.2f", $final_profit; my $houses_formatted = sprintf "%.2f", $final_houses; my $negative_formatted = sprintf "%.2f", $final_negative; my $principal_formatted = sprintf "%.2f", $final_principal; my $chance_loss = sprintf "%.2f", $final_loss; my $principal_formatted_nh = sprintf "%.2f", $final_principal_nh; my $percent_formatted_nh = sprintf "%.2f", $percent_nh; my $profit_formatted_nh = sprintf "%.2f", $final_profit_nh; my $chance_no_house = sprintf "%.2f", $no_house_iter_avg; my $chance_loss_nh = sprintf "%.2f", $final_loss_nh; print "Over $meta_iterations iterations:\n"; print " Average outlay: \$$principal_formatted\n"; print " Subtaxed the next year: $final_subtax_formatted Pct: $final_subtax_pct_formatted%\n"; print " Average profit: \$$profit_formatted; $percent_formatted%\n"; print " Number of losing iterations: $lost_money; $chance_loss%\n"; print " Number of iterations without houses: $no_house_iter; $chance_no_house\%\n"; print " Average outlay (no house only): \$$principal_formatted_nh\n"; print " Average profit (no house only): \$$profit_formatted_nh; $percent_formatted_nh%\n"; print " Number of losing iterations (no house only): $lost_money_nh; $chance_loss_nh%\n";