oroszgy commited on
Commit
bf1c4f6
Β·
verified Β·
1 Parent(s): bb2b2aa

feat: minor cosmetic changes

Browse files
Files changed (1) hide show
  1. app.py +42 -50
app.py CHANGED
@@ -14,10 +14,16 @@ except ImportError:
14
  rate -= npv / d_npv if d_npv else 0
15
  return rate
16
 
 
 
 
 
 
 
17
  # ========== Core Model ==========
18
  def build_property_projection(purchase_price, equity, loan_years, annual_interest_rate,
19
- monthly_payment, monthly_rent, vacancy_months, annual_renovation,
20
- inflation_rate):
21
  loan_balance = purchase_price - equity
22
  monthly_interest = annual_interest_rate / 12
23
  schedule = []
@@ -77,33 +83,17 @@ def compute_etf_irr(principal, years, annual_return):
77
  cashflows = [-principal] + [0] * (years - 1) + [round(final_value)]
78
  return irr(cashflows)
79
 
80
- def build_hybrid_projection(df_property, annual_return):
81
- etf_balance = 0
82
- projection = []
83
- for _, row in df_property.iterrows():
84
- etf_balance *= (1 + annual_return)
85
- etf_balance += row["NetCashFlow"]
86
- projection.append({"Year": row["Year"], "ETF_Balance": etf_balance})
87
- return pd.DataFrame(projection)
88
-
89
- def compute_hybrid_irr(df_property, equity, df_hybrid, sell_property_at_end=True):
90
- cashflows = [-equity]
91
- for i, row in df_property.iterrows():
92
- cf = 0
93
- if i == len(df_property) - 1 and sell_property_at_end:
94
- cf += row["PropertyValue"] - row["LoanBalance"]
95
- cf += df_hybrid.iloc[-1]["ETF_Balance"]
96
- else:
97
- cf += row["NetCashFlow"]
98
- cashflows.append(cf)
99
- return irr(cashflows)
100
-
101
  # ========== Gradio App ==========
102
  def simulate(
103
- purchase_price, equity, loan_years, annual_interest_rate,
104
  monthly_payment, monthly_rent, vacancy_months, annual_renovation,
105
- inflation_rate, etf_annual_return
106
  ):
 
 
 
 
 
107
  # Property
108
  df_property = build_property_projection(purchase_price, equity, loan_years,
109
  annual_interest_rate, monthly_payment,
@@ -115,24 +105,27 @@ def simulate(
115
  df_etf = build_etf_projection(equity, loan_years, etf_annual_return)
116
  etf_irr = compute_etf_irr(equity, loan_years, etf_annual_return)
117
 
118
- # Hybrid
119
- df_hybrid = build_hybrid_projection(df_property, etf_annual_return)
120
- hybrid_irr = compute_hybrid_irr(df_property, equity, df_hybrid)
121
-
122
  # Results summary
123
  summary = f"""
124
  πŸ“Š **Results after {loan_years} years**:
125
- - Property IRR: {prop_irr*100:.2f}%
126
- - ETF IRR: {etf_irr*100:.2f}%
127
- - Hybrid IRR (Property + ETF cashflows): {hybrid_irr*100:.2f}%
128
 
129
  πŸ’° Final Values:
130
- - Property Net Worth: {df_property.iloc[-1]['NetWorth']:,} HUF
131
- - ETF Value: {df_etf.iloc[-1]['ETF_Value']:,} HUF
132
- - Hybrid Value (Property + ETF): {df_property.iloc[-1]['NetWorth'] + df_hybrid.iloc[-1]['ETF_Balance']:,} HUF
133
  """
134
 
135
- return summary, df_property, df_etf, df_hybrid
 
 
 
 
 
 
 
 
 
136
 
137
  with gr.Blocks(title="Investment Simulator") as demo:
138
  gr.Markdown("# 🏠 vs πŸ“ˆ Investment Simulator")
@@ -140,24 +133,23 @@ with gr.Blocks(title="Investment Simulator") as demo:
140
 
141
  with gr.Row():
142
  with gr.Column():
143
- purchase_price = gr.Number(value=60_000_000, label="Purchase Price (HUF)")
144
- equity = gr.Number(value=20_000_000, label="Equity (HUF)")
145
- loan_years = gr.Number(value=20, label="Loan Term (years)")
146
- annual_interest_rate = gr.Number(value=0.03, label="Annual Interest Rate (THM)")
147
- monthly_payment = gr.Number(value=220_000, label="Monthly Loan Payment (HUF)")
148
- monthly_rent = gr.Number(value=170_000, label="Monthly Rent (HUF)")
149
- vacancy_months = gr.Number(value=1, label="Vacancy (months/year)")
150
- annual_renovation = gr.Number(value=100_000, label="Annual Renovation (HUF)")
151
- inflation_rate = gr.Number(value=0.045, label="Inflation Rate")
152
- etf_annual_return = gr.Number(value=0.11, label="ETF Annual Return")
153
 
154
  run_button = gr.Button("Run Simulation")
155
 
156
  with gr.Column():
157
  results = gr.Markdown()
158
- df_property_out = gr.Dataframe(interactive=False)
159
- df_etf_out = gr.Dataframe(interactive=False)
160
- df_hybrid_out = gr.Dataframe(interactive=False)
161
 
162
  run_button.click(
163
  simulate,
@@ -166,7 +158,7 @@ with gr.Blocks(title="Investment Simulator") as demo:
166
  monthly_payment, monthly_rent, vacancy_months, annual_renovation,
167
  inflation_rate, etf_annual_return
168
  ],
169
- outputs=[results, df_property_out, df_etf_out, df_hybrid_out]
170
  )
171
 
172
  if __name__ == "__main__":
 
14
  rate -= npv / d_npv if d_npv else 0
15
  return rate
16
 
17
+ def format_huf(x):
18
+ return f"{x:,.0f} HUF".replace(",", " ")
19
+
20
+ def format_pct(x):
21
+ return f"{x*100:.2f}%"
22
+
23
  # ========== Core Model ==========
24
  def build_property_projection(purchase_price, equity, loan_years, annual_interest_rate,
25
+ monthly_payment, monthly_rent, vacancy_months,
26
+ annual_renovation, inflation_rate):
27
  loan_balance = purchase_price - equity
28
  monthly_interest = annual_interest_rate / 12
29
  schedule = []
 
83
  cashflows = [-principal] + [0] * (years - 1) + [round(final_value)]
84
  return irr(cashflows)
85
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
  # ========== Gradio App ==========
87
  def simulate(
88
+ purchase_price, equity, loan_years, annual_interest_rate_pct,
89
  monthly_payment, monthly_rent, vacancy_months, annual_renovation,
90
+ inflation_rate_pct, etf_annual_return_pct
91
  ):
92
+ # Convert % to decimals
93
+ annual_interest_rate = annual_interest_rate_pct / 100
94
+ inflation_rate = inflation_rate_pct / 100
95
+ etf_annual_return = etf_annual_return_pct / 100
96
+
97
  # Property
98
  df_property = build_property_projection(purchase_price, equity, loan_years,
99
  annual_interest_rate, monthly_payment,
 
105
  df_etf = build_etf_projection(equity, loan_years, etf_annual_return)
106
  etf_irr = compute_etf_irr(equity, loan_years, etf_annual_return)
107
 
 
 
 
 
108
  # Results summary
109
  summary = f"""
110
  πŸ“Š **Results after {loan_years} years**:
111
+ - Property IRR: {format_pct(prop_irr)}
112
+ - ETF IRR: {format_pct(etf_irr)}
 
113
 
114
  πŸ’° Final Values:
115
+ - Property Net Worth: {format_huf(df_property.iloc[-1]['NetWorth'])}
116
+ - ETF Value: {format_huf(df_etf.iloc[-1]['ETF_Value'])}
 
117
  """
118
 
119
+ # Format tables for readability
120
+ df_property_fmt = df_property.copy()
121
+ for col in ["InterestPaid", "PrincipalPaid", "LoanBalance",
122
+ "RentIncome", "NetCashFlow", "PropertyValue", "NetWorth"]:
123
+ df_property_fmt[col] = df_property_fmt[col].apply(lambda x: format_huf(x))
124
+
125
+ df_etf_fmt = df_etf.copy()
126
+ df_etf_fmt["ETF_Value"] = df_etf_fmt["ETF_Value"].apply(lambda x: format_huf(x))
127
+
128
+ return summary, df_property_fmt, df_etf_fmt
129
 
130
  with gr.Blocks(title="Investment Simulator") as demo:
131
  gr.Markdown("# 🏠 vs πŸ“ˆ Investment Simulator")
 
133
 
134
  with gr.Row():
135
  with gr.Column():
136
+ purchase_price = gr.Number(value=60_000_000, label="Purchase Price (HUF)", precision=0)
137
+ equity = gr.Number(value=20_000_000, label="Equity (HUF)", precision=0)
138
+ loan_years = gr.Number(value=20, label="Loan Term (years)", precision=0)
139
+ annual_interest_rate = gr.Number(value=3.0, label="Loan Interest (THM %)", precision=2)
140
+ monthly_payment = gr.Number(value=220_000, label="Monthly Loan Payment (HUF)", precision=0)
141
+ monthly_rent = gr.Number(value=170_000, label="Monthly Rent (HUF)", precision=0)
142
+ vacancy_months = gr.Number(value=1, label="Vacancy (months/year)", precision=0)
143
+ annual_renovation = gr.Number(value=100_000, label="Annual Renovation (HUF)", precision=0)
144
+ inflation_rate = gr.Number(value=4.5, label="Inflation Rate (%)", precision=2)
145
+ etf_annual_return = gr.Number(value=11.0, label="ETF Annual Return (%)", precision=2)
146
 
147
  run_button = gr.Button("Run Simulation")
148
 
149
  with gr.Column():
150
  results = gr.Markdown()
151
+ df_property_out = gr.Dataframe(interactive=False, wrap=True)
152
+ df_etf_out = gr.Dataframe(interactive=False, wrap=True)
 
153
 
154
  run_button.click(
155
  simulate,
 
158
  monthly_payment, monthly_rent, vacancy_months, annual_renovation,
159
  inflation_rate, etf_annual_return
160
  ],
161
+ outputs=[results, df_property_out, df_etf_out]
162
  )
163
 
164
  if __name__ == "__main__":