-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathbuy_vs_rent.py
executable file
·134 lines (105 loc) · 3.54 KB
/
buy_vs_rent.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
#!/usr/bin/env python3
"""
- Capital gains tax/stamp duty
- Rent increase
- House upkeep
- Salary increase
"""
from dataclasses import dataclass
@dataclass
class Accounts:
savings_start: float = 0
savings_interest: float = 0.07
savings_payments: float = 0
expendible_income_increase: float = 0
rent_payments: float = 0
rent_growth: float = 0
mortgage_start: float = 0
mortgage_interest: float = 0.025
mortgage_payments: float = 0
house_value: float = 0
house_growth: float = 0.03
def __post_init__(self):
self.savings = self.savings_start
self.savings_paid = 0
self.mortgage = self.mortgage_start
self.mortgage_paid = 0
def step(self):
"""Do a single step"""
one_off_savings = 0
for month in range(12):
## Calculate mortgage value
m_interest = self.mortgage * (self.mortgage_interest / 12)
self.mortgage += m_interest
# Subtract payments
self.mortgage -= self.mortgage_payments
self.mortgage_paid += self.mortgage_payments
# The month the mortgage is paid off, put everything into savings
if self.mortgage <= 0 and self.mortgage_payments != 0:
one_off_savings = -self.mortgage
self.savings_payments += self.mortgage_payments
self.mortgage_payments = 0
self.mortgage = 0
# self.mortage_year_paid_off = year
## Calculate savings value
# Add savings interest
s_interest = self.savings * (self.savings_interest / 12)
self.savings += s_interest
# Add savings
self.savings += self.savings_payments + one_off_savings
self.savings_paid += self.savings_payments + one_off_savings
one_off_savings = 0
# Update house price (annually, it doesn't compound)
house_value_accrued = self.house_value * self.house_growth
self.house_value += house_value_accrued
self.update_total_assets()
def update_total_assets(self):
total_assets = 0
if self.mortgage_paid > 0:
house_fraction_owned = 1 - (
self.mortgage / (self.mortgage + self.mortgage_paid)
)
self.house_percent_owned = house_fraction_owned * 100
total_assets += house_fraction_owned * self.house_value
total_assets += self.savings - self.mortgage
self.total_assets = total_assets
def step_n_years(self, years):
for year in range(years):
self.step()
def pretty_print(self):
print("*" * 70)
to_print = [
"mortgage",
"mortgage_paid",
"mortgage_payments",
"savings",
"total_assets",
]
for k in to_print:
v = getattr(self, k)
v = f"{round(v, 2):,}"
info = f"{k: <50}{v: >20}"
print(info)
def print_info(info):
print("*" * 50)
for k, v in info.items():
v = round(v)
text = f"{k: <50}{v:,}"
print(text)
years = 25
initial_investment = 50000
account = Accounts(
rent_payments=1200, savings_start=initial_investment, savings_payments=800
)
account.step_n_years(years)
account.pretty_print()
house_value = 400000
mortgage_start = house_value - initial_investment
account = Accounts(
mortgage_payments=1200,
mortgage_start=mortgage_start,
house_value=house_value,
savings_payments=800,
)
account.step_n_years(years)
account.pretty_print()