A few weeks ago I started thinking about debt reduction strategies, where if someone has X debt across Y accounts, what’s the right way to address X?
I figured it should be simple. Take the highest interest rate liability and address it first. Rinse, repeat.
But then if you read the two most prominent talking heads on the matter, neither subscribe to that approach.
Dave Ramsey suggests you “snowball” your debt, where you pay the smallest debt first (ignoring interest rates), and then go up from there.
Suze Orman advises you to figure out how to make slightly more than the minimum payment on everything, and then any leftover money you’re willing to spend goes towards the highest interest rate.
I didn’t explicitly code Orman’s, but I tried a few other strategies to see how things work out. At first I was going off a few made up debts and running all the simulations against that, but I wound up with strange results and couldn’t figure out if it was because of a special set of numbers and interest rates, or if I’d found a smart strategy on accident or if I had a bug.
After working through a bunch of nuances (eg, applying the same strategy to order minimum payments as extra payments), I randomized the debts as far as minimum payment, outstanding balance, and APR.
Running that a few thousand times, I can tell you that the best way to make your debt reduction strategy more successful is to … throw more money at it. As the amount of money you can spend on debt decreases, the strategy becomes much more important (and the winners and losers are more visible).
As an extreme example, if you’ve $15,000 in debt, and you can throw $10,000 at it a month, it doesn’t matter if you pick Dave Ramsey’s plan or a whack-a-mole plan. You’re going to be fine in 2 months.
After running the simulation thousands of times with different debts, it seems that my initial instinct was correct: go with the highest interest rate. Here’s some sample output (not all scenarios are complete-able; sometimes the randomized debt outpaces debt payments, so that’s why the numbers don’t add up to 1000):
|Smallest Amount||325||671||0.33||Smallest balance first|
|Highest Interest||996||0||1.00||Highest interest rate first|
|Lowest Interest||179||817||0.18||Lowest interest rate first|
|Highest Amount||286||710||0.29||Highest balance first (changes over time)|
|Highest Card||374||622||0.38||Highest initial balance first (doesn't change until balance is 0)|
|Sprinter 1||972||24||0.98||Highest interest rate, unless within 1 month can eliminate another debt|
|Sprinter 3||787||209||0.79||Highest interest rate, unless within 3 months can eliminate another debt|
|Sprinter 6||509||487||0.51||Highest interest rate, unless within 6 months can eliminate another debt|
|Sprinter 12||337||659||0.34||Highest interest rate, unless within 12 months can eliminate another debt|
While it’s OK (and probably a nice dopamine hit) most of the time to pay off a balance if you can do it in one payment at the expense of others, most of the time you just want to focus on the highest interest rate.
A few caveats before gisting the code: I don’t have missed-payment fees (in case you’re in a situation where you can’t make the minimum payments), and I’m a little fast and loose with floating points, so it’s not perfectly accurate numbers going back and forth into debt amounts. That said, I’d expect that behavior to normalize over sufficient runs to not skew any behavior significantly.
Lastly, it’s all in one file because this was coded and written during a coffee break.
Any big mistakes in my code are promised to be well received :) Enjoy!