Dividend Income Calculator and DRIP Simulator
Dividend investing is a popular strategy for building passive income. But how much will your dividends grow over time with reinvestment? In this tutorial, we build a dividend calculator that models DRIP (Dividend Reinvestment Plan) compounding, projects future income, and visualises the snowball effect.
Prerequisites
- ✓Basic Python
- ✓Understanding of dividends and compound interest
Step 1.Install dependencies
Standard data science stack for calculations and charts.
pip install pandas matplotlib numpyStep 2.Define your dividend holdings
Each holding has the current dividend per share and an estimated annual dividend growth rate.
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
holdings = [
{"ticker": "JNJ", "shares": 50, "price": 155.0, "annual_div": 4.76, "div_growth": 0.06},
{"ticker": "KO", "shares": 100, "price": 62.0, "annual_div": 1.94, "div_growth": 0.05},
{"ticker": "PG", "shares": 40, "price": 165.0, "annual_div": 3.76, "div_growth": 0.07},
{"ticker": "O", "shares": 75, "price": 55.0, "annual_div": 3.08, "div_growth": 0.04},
]
total_income = sum(h["shares"] * h["annual_div"] for h in holdings)
print(f"Current annual dividend income: ${total_income:,.2f}")
print(f"Monthly income: ${total_income/12:,.2f}")Step 3.Simulate DRIP over 20 years
Each year: collect dividends, buy more shares at current price, then grow the dividend and price.
def simulate_drip(initial_holdings, years=20):
yearly_data = []
current = [dict(h) for h in initial_holdings]
original_costs = [h["shares"] * h["price"] for h in initial_holdings]
for year in range(years + 1):
annual_income = sum(h["shares"] * h["annual_div"] for h in current)
portfolio_value = sum(h["shares"] * h["price"] for h in current)
total_cost = sum(original_costs)
yoc = (annual_income / total_cost) * 100 if total_cost > 0 else 0
yearly_data.append({
"Year": year,
"Annual Income": round(annual_income, 2),
"Portfolio Value": round(portfolio_value, 2),
"Yield on Cost": round(yoc, 2)
})
for h in current:
new_shares = (h["annual_div"] * h["shares"]) / h["price"]
h["shares"] += new_shares
h["annual_div"] *= (1 + h["div_growth"])
h["price"] *= 1.05 # Assume 5% price appreciation
return pd.DataFrame(yearly_data)
df = simulate_drip(holdings, 20)
print(df.to_string(index=False))Step 4.Compare DRIP vs no DRIP
DRIP creates a compounding snowball. The difference grows dramatically over time.
def simulate_no_drip(initial_holdings, years=20):
yearly_data = []
current = [dict(h) for h in initial_holdings]
for year in range(years + 1):
annual_income = sum(h["shares"] * h["annual_div"] for h in current)
portfolio_value = sum(h["shares"] * h["price"] for h in current)
yearly_data.append({"Year": year, "Annual Income": round(annual_income, 2), "Portfolio Value": round(portfolio_value, 2)})
for h in current:
h["annual_div"] *= (1 + h["div_growth"])
h["price"] *= 1.05
return pd.DataFrame(yearly_data)
df_no_drip = simulate_no_drip(holdings, 20)
print(f"Year 20 with DRIP: ${df.iloc[-1]['Annual Income']:,.0f}/year income")
print(f"Year 20 without DRIP: ${df_no_drip.iloc[-1]['Annual Income']:,.0f}/year income")Step 5.Visualise the dividend snowball
Side-by-side comparison showing the power of reinvesting dividends over time.
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(16, 6))
ax1.bar(df["Year"], df["Annual Income"], color="cyan", alpha=0.7, label="With DRIP")
ax1.bar(df_no_drip["Year"], df_no_drip["Annual Income"], color="gray", alpha=0.4, label="Without DRIP")
ax1.set_xlabel("Year")
ax1.set_ylabel("Annual Dividend Income ($)")
ax1.set_title("Dividend Income Growth")
ax1.legend()
ax2.plot(df["Year"], df["Portfolio Value"], color="cyan", linewidth=2, label="With DRIP")
ax2.plot(df_no_drip["Year"], df_no_drip["Portfolio Value"], color="gray", linewidth=2, label="Without DRIP")
ax2.set_xlabel("Year")
ax2.set_ylabel("Portfolio Value ($)")
ax2.set_title("Portfolio Value Growth")
ax2.legend()
plt.tight_layout()
plt.savefig("dividend_drip.png", dpi=150)
plt.show()Expected Output
Current annual dividend income: $1,003.00
Monthly income: $83.58
Year 20 with DRIP: $5,842/year income
Year 20 without DRIP: $3,215/year incomeNext Steps
- →Add tax impact modelling (ISA vs GIA)
- →Include monthly contribution additions
- →Build a dividend calendar showing payment dates
Recommended Reading
The Single Best Investment →As an Amazon Associate we may earn from qualifying purchases.