-
Notifications
You must be signed in to change notification settings - Fork 348
/
Copy pathcompound_interest.py
169 lines (141 loc) · 4.18 KB
/
compound_interest.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# /// script
# requires-python = ">=3.9"
# dependencies = [
# "marimo",
# "matplotlib==3.9.2",
# ]
# ///
import marimo
__generated_with = "0.8.19"
app = marimo.App()
@app.cell(hide_code=True)
def __(mo):
mo.md("""# Compound Interest""")
return
@app.cell(hide_code=True)
def __(mo):
mo.md(
"""
This notebook illustrates exponential growth, using compound interest
as an example.
"""
).callout()
return
@app.cell(hide_code=True)
def __(mo):
initial_investment = mo.ui.slider(0, 1000000, step=1e4, value=10000)
monthly_investment = mo.ui.slider(0, 50000, value=1000, step=1e3)
annual_return = mo.ui.slider(0, 0.15, value=0.07, step=0.01)
years = mo.ui.slider(1, 60, value=30)
capital_gains_tax_rate = mo.ui.slider(0.0, 1.0, value=0.32, step=0.01)
table = mo.ui.table(
[
{
"parameter": "initial investment",
"control": initial_investment,
},
{
"parameter": "monthly investment",
"control": monthly_investment,
},
{
"parameter": "annual return",
"control": annual_return,
},
{
"parameter": "years",
"control": years,
},
{
"parameter": "capital gains tax rate",
"control": capital_gains_tax_rate,
},
],
selection=None,
)
mo.md(
f"""## Investment Parameters
{table}
""")
return (
annual_return,
capital_gains_tax_rate,
initial_investment,
monthly_investment,
table,
years,
)
@app.cell(hide_code=True)
def simulate(
annual_return,
capital_gains_tax_rate,
initial_investment,
mo,
monthly_investment,
plt,
years,
):
class Portfolio:
def __init__(self, value, annual_return):
self.value = value
self.annual_return = annual_return
self.monthly_return = (1 + self.annual_return) ** (1.0 / 12) - 1
def simulate_month(self, additional_investment):
self.value += additional_investment
self.value *= 1 + self.monthly_return
return self.value
def total_return(self, months):
return (1 + self.monthly_return) ** months
portfolio = Portfolio(initial_investment.value, annual_return.value)
values = [portfolio.value]
investment_principals = [portfolio.value]
values_less_taxes = [portfolio.value]
_months = years.value * 12
for _ in range(_months):
values.append(portfolio.simulate_month(monthly_investment.value))
investment_principals.append(
investment_principals[-1] + monthly_investment.value
)
values_less_taxes.append(
investment_principals[-1]
+ (1 - capital_gains_tax_rate.value)
* (values[-1] - investment_principals[-1])
)
plt.plot(values, label="Portfolio Value")
plt.plot(values_less_taxes, label="Value, Less Capital Gains Taxes")
plt.plot(investment_principals, label="Contributed")
plt.legend()
plt.xlabel("Month")
plt.title("Net Wealth")
_prose = f"""
## Net Worth
With an initial investment of **\${initial_investment.value :,.02f}**, an annual
return of **{annual_return.value * 100:.02f}%** with
**\${monthly_investment.value:,.02f}** invested monthly, in {years.value} years
you will have approximately **\${values[-1]:,.02f}** accumulated in
equities. Assuming a long-term capitals gain tax of
**{capital_gains_tax_rate.value*100:.02f}%**, the net portfolio value is
**\${values_less_taxes[-1]:,.02f}**. Compare that to the
**\${investment_principals[-1]:,.02f}** that you contributed in total.
"""
ax = plt.gca()
mo.md(_prose)
return (
Portfolio,
ax,
investment_principals,
portfolio,
values,
values_less_taxes,
)
@app.cell
def __(ax):
ax
return
@app.cell
def __():
import marimo as mo
import matplotlib.pyplot as plt
return mo, plt
if __name__ == "__main__":
app.run()