2024-08-08 11:03:14 +10:00
|
|
|
{
|
|
|
|
"cells": [
|
|
|
|
{
|
|
|
|
"cell_type": "code",
|
2024-08-16 08:26:12 +10:00
|
|
|
"execution_count": 11,
|
2024-08-08 11:03:14 +10:00
|
|
|
"metadata": {},
|
|
|
|
"outputs": [],
|
|
|
|
"source": [
|
|
|
|
"from simulator import *\n",
|
|
|
|
"\n",
|
|
|
|
"# Loan properties\n",
|
|
|
|
"PERIODS_PER_YEAR = 12\n",
|
|
|
|
"LOAN_DURATION_YEARS = 30\n",
|
|
|
|
"TOTAL_LOAN_PERIODS = PERIODS_PER_YEAR * LOAN_DURATION_YEARS\n",
|
2024-08-16 08:26:12 +10:00
|
|
|
"NOMINAL_ANNUAL_INTEREST_RATE = 6.19 / 100\n",
|
|
|
|
"LOAN_PRINCIPAL = 570000\n",
|
2024-08-08 11:03:14 +10:00
|
|
|
"PERIOD_INTEREST_RATE = NOMINAL_ANNUAL_INTEREST_RATE / PERIODS_PER_YEAR\n",
|
|
|
|
"PERIOD_PAYMENT = (LOAN_PRINCIPAL * (PERIOD_INTEREST_RATE * (1 + PERIOD_INTEREST_RATE) ** TOTAL_LOAN_PERIODS) /\n",
|
|
|
|
" ((1 + PERIOD_INTEREST_RATE) ** TOTAL_LOAN_PERIODS - 1))\n",
|
|
|
|
"\n",
|
|
|
|
"def calculate_total_payments(metrics: MetricsContainer) -> float:\n",
|
|
|
|
" return metrics[\"total_payments\"] + PERIOD_PAYMENT\n",
|
|
|
|
"\n",
|
|
|
|
"def calculate_interest_payment(metrics: MetricsContainer) -> float:\n",
|
|
|
|
" return metrics[\"remaining_loan\"] * PERIOD_INTEREST_RATE\n",
|
|
|
|
"\n",
|
|
|
|
"def calculate_total_interest_paid(metrics: MetricsContainer) -> float:\n",
|
|
|
|
" return metrics[\"total_interest_paid\"] + calculate_interest_payment(metrics)\n",
|
|
|
|
"\n",
|
|
|
|
"def calculate_principal_payment(metrics: MetricsContainer) -> float:\n",
|
|
|
|
" return PERIOD_PAYMENT - calculate_interest_payment(metrics)\n",
|
|
|
|
"\n",
|
|
|
|
"def calculate_remaining_loan(metrics: MetricsContainer) -> float:\n",
|
|
|
|
" return metrics[\"remaining_loan\"] - calculate_principal_payment(metrics)\n",
|
|
|
|
"\n",
|
|
|
|
"loan_metric_configs = {\n",
|
|
|
|
" \"total_payments\": MetricConfig(initial_value=0, period_calculator=calculate_total_payments),\n",
|
|
|
|
" \"interest_payment\": MetricConfig(initial_value=None, period_calculator=calculate_interest_payment, plot=False),\n",
|
|
|
|
" \"total_interest_paid\": MetricConfig(initial_value=0, period_calculator=calculate_total_interest_paid),\n",
|
|
|
|
" \"principal_payment\": MetricConfig(initial_value=None, period_calculator=calculate_principal_payment, plot=False),\n",
|
|
|
|
" \"remaining_loan\": MetricConfig(initial_value=LOAN_PRINCIPAL, period_calculator=calculate_remaining_loan)\n",
|
|
|
|
"}"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"cell_type": "code",
|
2024-08-16 08:26:12 +10:00
|
|
|
"execution_count": 12,
|
2024-08-08 11:03:14 +10:00
|
|
|
"metadata": {},
|
|
|
|
"outputs": [],
|
|
|
|
"source": [
|
|
|
|
"# Property properties\n",
|
2024-08-16 08:26:12 +10:00
|
|
|
"DEPOSIT = 30000\n",
|
|
|
|
"ADDITIONAL_UPFRONT_COSTS = 0\n",
|
|
|
|
"ANNUAL_APPRECIATION_RATE = 7 / 100\n",
|
2024-08-08 11:03:14 +10:00
|
|
|
"INITIAL_PROPERTY_VALUE = LOAN_PRINCIPAL + DEPOSIT\n",
|
|
|
|
"PERIOD_APPRECIATION_RATE = (1 + ANNUAL_APPRECIATION_RATE) ** (1 / PERIODS_PER_YEAR) - 1\n",
|
|
|
|
"\n",
|
|
|
|
"def calculate_period_appreciation(metrics: MetricsContainer) -> float:\n",
|
|
|
|
" return metrics[\"property_value\"] * (1 + PERIOD_APPRECIATION_RATE) - metrics[\"property_value\"]\n",
|
|
|
|
"\n",
|
|
|
|
"def calculate_property_value(metrics: MetricsContainer) -> float:\n",
|
|
|
|
" return metrics[\"property_value\"] + calculate_period_appreciation(metrics)\n",
|
|
|
|
"\n",
|
|
|
|
"def calculate_equity(metrics: MetricsContainer) -> float:\n",
|
|
|
|
" return metrics[\"equity\"] + calculate_principal_payment(metrics) + calculate_period_appreciation(metrics)\n",
|
|
|
|
"\n",
|
|
|
|
"property_metric_configs = {\n",
|
|
|
|
" \"property_value\": MetricConfig(initial_value=INITIAL_PROPERTY_VALUE, period_calculator=calculate_property_value),\n",
|
|
|
|
" \"equity\": MetricConfig(initial_value=DEPOSIT, period_calculator=calculate_equity)\n",
|
|
|
|
"}"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"cell_type": "code",
|
2024-08-16 08:26:12 +10:00
|
|
|
"execution_count": 13,
|
2024-08-08 11:03:14 +10:00
|
|
|
"metadata": {},
|
|
|
|
"outputs": [],
|
|
|
|
"source": [
|
|
|
|
"# Income properties\n",
|
2024-08-16 08:26:12 +10:00
|
|
|
"INITIAL_ANNUAL_RENTAL_INCOME = 26000\n",
|
|
|
|
"RENTAL_INCOME_ANNUAL_GROWTH_RATE = 4 / 100\n",
|
2024-08-08 11:03:14 +10:00
|
|
|
"PERIOD_RENTAL_INCOME_GROWTH_RATE = (1 + RENTAL_INCOME_ANNUAL_GROWTH_RATE) ** (1 / PERIODS_PER_YEAR) - 1\n",
|
|
|
|
"INITIAL_PERIOD_RENTAL_INCOME = INITIAL_ANNUAL_RENTAL_INCOME / PERIODS_PER_YEAR\n",
|
|
|
|
"\n",
|
|
|
|
"def calculate_period_rental_income(metrics: MetricsContainer) -> float:\n",
|
|
|
|
" return metrics[\"period_rental_income\"] * (1 + PERIOD_RENTAL_INCOME_GROWTH_RATE)\n",
|
|
|
|
"\n",
|
|
|
|
"def calculate_total_rental_income(metrics: MetricsContainer) -> float:\n",
|
|
|
|
" return metrics[\"total_rental_income\"] + calculate_period_rental_income(metrics)\n",
|
|
|
|
"\n",
|
|
|
|
"def calculate_period_cashflow(metrics: MetricsContainer) -> float:\n",
|
|
|
|
" return calculate_period_rental_income(metrics) - calculate_interest_payment(metrics)\n",
|
|
|
|
"\n",
|
|
|
|
"def calculate_net_worth(metrics: MetricsContainer) -> float:\n",
|
|
|
|
" return metrics[\"net_worth\"] + calculate_period_cashflow(metrics) + calculate_period_appreciation(metrics) + calculate_principal_payment(metrics)\n",
|
|
|
|
"\n",
|
|
|
|
"income_metric_configs = {\n",
|
|
|
|
" \"period_rental_income\": MetricConfig(initial_value=INITIAL_PERIOD_RENTAL_INCOME, period_calculator=calculate_period_rental_income, plot=False),\n",
|
|
|
|
" \"total_rental_income\": MetricConfig(initial_value=0, period_calculator=calculate_total_rental_income),\n",
|
|
|
|
" \"period_cashflow\": MetricConfig(initial_value=None, period_calculator=calculate_period_cashflow, plot=False),\n",
|
|
|
|
" \"net_worth\": MetricConfig(initial_value=DEPOSIT - ADDITIONAL_UPFRONT_COSTS, period_calculator=calculate_net_worth),\n",
|
|
|
|
"}"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"cell_type": "code",
|
2024-08-16 08:26:12 +10:00
|
|
|
"execution_count": 14,
|
2024-08-08 11:03:14 +10:00
|
|
|
"metadata": {},
|
|
|
|
"outputs": [],
|
|
|
|
"source": [
|
|
|
|
"# Baseline Properties\n",
|
2024-08-16 08:26:12 +10:00
|
|
|
"ETF_ANNUAL_YIELD = 10 / 100\n",
|
2024-08-08 11:03:14 +10:00
|
|
|
"ETF_PERIOD_YIELD = (1 + ETF_ANNUAL_YIELD) ** (1 / PERIODS_PER_YEAR) - 1\n",
|
2024-08-16 08:26:12 +10:00
|
|
|
"RENTAL_COST_ANNUAL_GROWTH_RATE = 4 / 100\n",
|
|
|
|
"INITIAL_ANNUAL_RENTAL_COST = 20000\n",
|
2024-08-08 11:03:14 +10:00
|
|
|
"INITIAL_PERIOD_RENTAL_COST = INITIAL_ANNUAL_RENTAL_COST / PERIODS_PER_YEAR\n",
|
|
|
|
"PERIOD_RENTAL_COST_GROWTH_RATE = (1 + RENTAL_COST_ANNUAL_GROWTH_RATE) ** (1 / PERIODS_PER_YEAR) - 1\n",
|
|
|
|
"\n",
|
|
|
|
"def calculate_period_rental_cost(metrics: MetricsContainer) -> float:\n",
|
|
|
|
" return metrics[\"period_rental_cost\"] * (1 + PERIOD_RENTAL_COST_GROWTH_RATE)\n",
|
|
|
|
"\n",
|
|
|
|
"def calculate_total_etf_value(metrics: MetricsContainer) -> float:\n",
|
|
|
|
" rental_cost_period = calculate_period_rental_cost(metrics)\n",
|
|
|
|
" return metrics[\"total_etf_value\"] * (1 + ETF_PERIOD_YIELD) + max(PERIOD_PAYMENT - rental_cost_period, 0)\n",
|
|
|
|
"\n",
|
2024-08-16 08:26:12 +10:00
|
|
|
"def calculate_total_rent_paid(metrics: MetricsContainer) -> float:\n",
|
|
|
|
" return metrics[\"period_rental_cost\"] * (1 + PERIOD_RENTAL_COST_GROWTH_RATE)\n",
|
|
|
|
"\n",
|
2024-08-08 11:03:14 +10:00
|
|
|
"baseline_metric_configs = {\n",
|
|
|
|
" \"period_rental_cost\": MetricConfig(initial_value=INITIAL_PERIOD_RENTAL_COST, period_calculator=calculate_period_rental_cost, plot=False),\n",
|
2024-08-16 08:26:12 +10:00
|
|
|
" \"total_rent_paid\": MetricConfig(initial_value=0, period_calculator=calculate_total_rent_paid, plot=False),\n",
|
2024-08-08 11:03:14 +10:00
|
|
|
" \"total_etf_value\": MetricConfig(initial_value=DEPOSIT + ADDITIONAL_UPFRONT_COSTS, period_calculator=calculate_total_etf_value),\n",
|
|
|
|
"}"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"cell_type": "code",
|
2024-08-16 08:26:12 +10:00
|
|
|
"execution_count": 15,
|
2024-08-08 11:03:14 +10:00
|
|
|
"metadata": {},
|
|
|
|
"outputs": [
|
|
|
|
{
|
|
|
|
"data": {
|
2024-08-16 08:26:12 +10:00
|
|
|
"application/vnd.jupyter.widget-view+json": {
|
|
|
|
"model_id": "2dbd2464c5734622b7535fff03adbb31",
|
|
|
|
"version_major": 2,
|
|
|
|
"version_minor": 0
|
|
|
|
},
|
|
|
|
"image/png": "iVBORw0KGgoAAAANSUhEUgAABXgAAAMgCAYAAACZBgqXAAAAP3RFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMS5wb3N0MSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8kixA/AAAACXBIWXMAAA9hAAAPYQGoP6dpAAEAAElEQVR4nOzde3yP9f/H8ce183kzxhxmmxhzPmup6KCF9EU5R5Ok5FStKDmliIihlPo69SWhUiGHfFEhh4rIeZk5xjDb7Pz5XL8//Hy+rY2N2Gez5/122+3mc13v67pe1+VNeu6912WYpmkiIiIiIiIiIiIiIsWOg70LEBEREREREREREZEbo4BXREREREREREREpJhSwCsiIiIiIiIiIiJSTCngFRERERERERERESmmFPCKiIiIiIiIiIiIFFMKeEVERERERERERESKKQW8IiIiIiIiIiIiIsWUAl4RERERERERERGRYkoBr4iIiIiIiIiIiEgxpYBXREREREREREREpJhSwCsiIiIiIiIiIiJSTCngFRERERERERERESmmFPCKiIiIiIiIiIiIFFMKeEVERERERERERESKKQW8IiIiIiIiIiIiIsWUAl4RERERERERERGRYkoBr4iIiIiIiIiIiEgxpYBXREREREREREREpJhSwCsiIiIiIiIiIiJSTCngFRERERERERERESmmFPCKiIiIiIiIiIiIFFMKeEVERERERERERESKKQW8IiIiIiIiIiIiIsWUAl4RERERERERERGRYkoBr4iIiIiIiIiIiEgxpYBXREREREREREREpJhSwCsiIiIiIiIiIiJSTCngFRERERERERERESmmFPCKiIiIiIiIiIiIFFMKeEVERERERERERESKKQW8IiIiIiIiIiIiIsWUAl4RERERERERERGRYkoBr4iIiIiIiIiIiEgxpYBXREREREREREREpJhSwCsiIiIiIiIiIiJSTCngFRERERERERERESmmFPCKiIiIiIiIiIiIFFMKeEVERERERERERESKKQW8IiIiIiIiIiIiIsWUAl4RERERERERERGRYkoBr4iIiIiIiIiIiEgxpYBXREREREREREREpJhSwCsiIiIiIiIiIiJSTCngFRERERERERERESmmFPCKiIiIiIiIiIiIFFMKeEVERERERERERESKKQW8IiIiIiIiIiIiIsWUAl4RERERERERERGRYkoBr4iIiIiIiIiIiEgxpYBXREREREREREREpJhSwCsiIiIiIiIiIiJSTCngFRERERERERERESmmFPCKiIiIiIiIiIiIFFMKeEVERERERERERESKKQW8IiIiIiIiIiIiIsWUAl4RERERERERERGRYkoBr4iIiIiIiIiIiEgxpYBXREREREREREREpJhSwCsiIiIiIiIiIiJSTCngFRERERERERERESmmFPCKiIiIiIiIiIiIFFMKeEVERERERERERESKKQW8IiIiIiIiIiIiIsWUAl4RERERERERERGRYkoBr4iIiIiIiIiIiEgxpYBXREREREREREREpJhSwCsiIiIiIiIiIiJSTCngFRERERERERERESmmFPCKiIiIiIiIiIiIFFMKeEVERERERERERESKKQW8IiIiIiIiIiIiIsWUAl4RERERERERERGRYkoBr4iIiIiIiIiIiEgxpYBXREREpJibO3cuhmEQFxdn71JuCyEhIURFRdnl2qNHj8YwjJt6zg0bNmAYBhs2bLip5y1K4uLiMAyDuXPn3rRz3orfCxEREZFbQQGviIiISAFdCVINw+DHH3/Mtd80TYKCgjAMg0ceeeSGrvH+++/f1JDqVlq+fDkPP/wwpUuXxs3NjbCwMKKjozl37py9S8vT7t27efzxxwkODsbNzY2KFSvSqlUrpk+fbu/SboqiOHdatmxp+zNjGAb+/v40adKE2bNnY7Va7V2eiIiIyG3Byd4FiIiIiBQ3bm5uLFy4kLvvvjvH9o0bN3L8+HFcXV1v+Nzvv/8+ZcqUua4VpD179qRr167/6LrXKzo6msmTJ1OvXj2GDh2Kv78/v/zyCzNmzGDRokWsW7eO6tWrF1o9+dm8eTP33XcflStXpm/fvgQGBnLs2DF++uknYmJiGDhwoG3sgQMHcHAofusgrjZ37r33XtLS0nBxcbFLXZUqVWL8+PEAnD17lvnz59OnTx8OHjzI22+/fVOuERwcTFpaGs7OzjflfCIiIiLFiQJeERERkevUpk0blixZwrRp03By+t8/pxYuXEijRo1ISEgolDouXbqEp6cnjo6OODo6Fso1AT799FMmT55Mly5dWLBgQY5rR0VFcd9999GpUyd++eWXHM/nVrvyPPLy1ltv4evry/bt2/Hz88ux78yZMzk+F2ZQXhgcHBxwc3Oz2/V9fX154oknbJ/79etH9erVmTFjBmPHjv1HoWx2djZWqxUXFxe73qOIiIiIPRW/pQkiIiIidtatWzfOnTvH2rVrbdsyMzNZunQp3bt3z/MYq9XK1KlTqVWrFm5ubpQrV45+/fpx4cIF25iQkBB+//13Nm7caPuR9pYtWwL/aw+xceNG+vfvT9myZalUqVKOfX/vwfvtt9/SokULvL298fHxoUmTJixcuNC2/9ChQzz22GMEBgbi5uZGpUqV6Nq1KxcvXrzm/Y8ZM4ZSpUoxa9asXMFy06ZNGTp0KLt372bp0qUADBgwAC8vL1JTU/N8loGBgVgslhx133PPPXh6euLt7U3btm35/fffcxwXFRWFl5cXsbGxtGnTBm9vb3r06HHVmmNjY6lVq1aucBegbNmyOT7/vQfvlef7448/MmjQIAICAvDz86Nfv35kZmaSmJhIr169KFWqFKVKleKVV17BNE3b8VfrgVvQvrFz5szh/vvvp2zZsri6ulKzZk1mzpyZq+arzZ2rXX/JkiU0atQId3d3ypQpwxNPPMGJEydyjLnynE+cOEH79u3x8vIiICCA6OjoHL9n18PDw4M777yTS5cucfbsWQASExMZMmQIQUFBuLq6UrVqVSZMmJCjjcOV5zVp0iSmTp3KHXfcgaurK3v37r3qs/zvf/9rm0t+fn7861//Yt++fblq+vHHH2nSpAlubm7ccccdfPjhhzd0byIiIiL2oBW8IiIiItcpJCSEiIgIPv30U1q3bg1cDiUvXrxI165dmTZtWq5j+vXrx9y5c+nduzeDBg3iyJEjzJgxg19//ZVNmzbh7OzM1KlTGThwIF5eXgwfPhyAcuXK5ThP//79CQgIYOTIkVy6dOmqNc6dO5ennnqKWrVq8eqrr+Ln58evv/7KqlWr6N69O5mZmURGRpKRkcHAgQMJDAzkxIkTLF++nMTERHx9ffM876FDhzhw4ABRUVH4+PjkOaZXr16MGjWK5cuX07VrV7p06cJ7773HihUr6NSpk21camoq33zzDVFRUbag+JNPPuHJJ58kMjKSCRMmkJqaysyZM7n77rv59ddfCQkJsR2fnZ1NZGQkd999N5MmTcLDw+OqzyM4OJgtW7awZ88eateufdVx13LlOY0ZM4affvqJWbNm4efnx+bNm6lcuTLjxo1j5cqVvPPOO9SuXZtevXrd0HX+bubMmdSqVYtHH30UJycnvvnmG/r374/VauX5558HKNDc+asrc7FJkyaMHz+eP//8k5iYGDZt2sSvv/6aIwi3WCxERkbSrFkzJk2axHfffcfkyZO54447eO65527onv744w8cHR3x8/MjNTWVFi1acOLECfr160flypXZvHkzr776KqdOnWLq1Kk5jp0zZw7p6ek888wzuLq64u/vn2c/3++++47WrVtTpUoVRo8eTVpaGtOnT6d58+b88ssvtrm0e/duHnroIQICAhg9ejTZ2dmMGjXqms9PREREpEgxRURERKRA5syZYwLm9u3bzRkzZpje3t5mamqqaZqm2alTJ/O+++4zTdM0g4ODzbZt29qO++GHH0zAXLBgQY7zrVq1Ktf2WrVqmS1atLjqte+++24zOzs7z31HjhwxTdM0ExMTTW9vb7NZs2ZmWlpajrFWq9U0TdP89dd
|
|
|
|
"text/html": [
|
|
|
|
"\n",
|
|
|
|
" <div style=\"display: inline-block;\">\n",
|
|
|
|
" <div class=\"jupyter-widgets widget-label\" style=\"text-align: center;\">\n",
|
|
|
|
" Figure\n",
|
|
|
|
" </div>\n",
|
|
|
|
" <img src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABXgAAAMgCAYAAACZBgqXAAAAP3RFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMS5wb3N0MSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8kixA/AAAACXBIWXMAAA9hAAAPYQGoP6dpAAEAAElEQVR4nOzde3yP9f/H8ce183kzxhxmmxhzPmup6KCF9EU5R5Ok5FStKDmliIihlPo69SWhUiGHfFEhh4rIeZk5xjDb7Pz5XL8//Hy+rY2N2Gez5/122+3mc13v67pe1+VNeu6912WYpmkiIiIiIiIiIiIiIsWOg70LEBEREREREREREZEbo4BXREREREREREREpJhSwCsiIiIiIiIiIiJSTCngFRERERERERERESmmFPCKiIiIiIiIiIiIFFMKeEVERERERERERESKKQW8IiIiIiIiIiIiIsWUAl4RERERERERERGRYkoBr4iIiIiIiIiIiEgxpYBXREREREREREREpJhSwCsiIiIiIiIiIiJSTCngFRERERERERERESmmFPCKiIiIiIiIiIiIFFMKeEVERERERERERESKKQW8IiIiIiIiIiIiIsWUAl4RERERERERERGRYkoBr4iIiIiIiIiIiEgxpYBXREREREREREREpJhSwCsiIiIiIiIiIiJSTCngFRERERERERERESmmFPCKiIiIiIiIiIiIFFMKeEVERERERERERESKKQW8IiIiIiIiIiIiIsWUAl4RERERERERERGRYkoBr4iIiIiIiIiIiEgxpYBXREREREREREREpJhSwCsiIiIiIiIiIiJSTCngFRERERERERERESmmFPCKiIiIiIiIiIiIFFMKeEVERERERERERESKKQW8IiIiIiIiIiIiIsWUAl4RERERERERERGRYkoBr4iIiIiIiIiIiEgxpYBXREREREREREREpJhSwCsiIiIiIiIiIiJSTCngFRERERERERERESmmFPCKiIiIiIiIiIiIFFMKeEVERERERERERESKKQW8IiIiIiIiIiIiIsWUAl4RERERERERERGRYkoBr4iIiIiIiIiIiEgxpYBXREREREREREREpJhSwCsiIiIiIiIiIiJSTCngFRERERERERERESmmFPCKiIiIiIiIiIiIFFMKeEVERERERERERESKKQW8IiIiIiIiIiIiIsWUAl4RERERERERERGRYkoBr4iIiIiIiIiIiEgxpYBXREREREREREREpJhSwCsiIiIiIiIiIiJSTCngFRERERERERERESmmFPCKiIiIiIiIiIiIFFMKeEVERERERERERESKKQW8IiIiIiIiIiIiIsWUAl4RERERERERERGRYkoBr4iIiIiIiIiIiEgxpYBXREREREREREREpJhSwCsiIiIiIiIiIiJSTCngFRERERERERERESmmFPCKiIiIiIiIiIiIFFMKeEVERERERERERESKKQW8IiIiIiIiIiIiIsWUAl4RERERERERERGRYkoBr4iIiIiIiIiIiEgxpYBXREREREREREREpJhSwCsiIiIiIiIiIiJSTCngFRERERERERERESmmFPCKiIiIiIiIiIiIFFMKeEVERERERERERESKKQW8IiIiIiIiIiIiIsWUAl4RERERERERERGRYkoBr4iIiIiIiIiIiEgxpYBXREREpJibO3cuhmEQFxdn71JuCyEhIURFRdnl2qNHj8YwjJt6zg0bNmAYBhs2bLip5y1K4uLiMAyDuXPn3rRz3orfCxEREZFbQQGviIiISAFdCVINw+DHH3/Mtd80TYKCgjAMg0ceeeSGrvH+++/f1JDqVlq+fDkPP/wwpUuXxs3NjbCwMKKjozl37py9S8vT7t27efzxxwkODsbNzY2KFSvSqlUrpk+fbu/SboqiOHdatmxp+zNjGAb+/v40adKE2bNnY7Va7V2eiIiIyG3Byd4FiIiIiBQ3bm5uLFy4kLvvvjvH9o0bN3L8+HFcXV1v+Nzvv/8+ZcqUua4VpD179qRr167/6LrXKzo6msmTJ1OvXj2GDh2Kv78/v/zyCzNmzGDRokWsW7eO6tWrF1o9+dm8eTP33XcflStXpm/fvgQGBnLs2DF++uknYmJiGDhwoG3sgQMHcHAofusgrjZ37r33XtLS0nBxcbFLXZUqVWL8+PEAnD17lvnz59OnTx8OHjzI22+/fVOuERwcTFpaGs7OzjflfCIiIiLFiQJeERERkevUpk0blixZwrRp03By+t8/pxYuXEijRo1ISEgolDouXbqEp6cnjo6OODo6Fso1AT799FMmT55Mly5dWLBgQY5rR0VFcd9999GpUyd++eWXHM/nVrvyPPLy1ltv4evry/bt2/Hz88ux78yZMzk+F2ZQXhgcHBxwc3Oz2/V9fX154oknbJ/79etH9erVmTFjBmPHjv1HoWx2djZWqxUXFxe73qOIiIiIPRW/pQkiIiIidtatWzfOnTvH2rVrbdsyMzNZunQp3bt3z/MYq9XK1KlTqVWrFm5ubpQrV45+/fpx4cIF25iQkBB+//13Nm7caPuR9pYtWwL/aw+xceNG+vfvT9myZalUqVKOfX/vwfvtt9/SokULvL298fHxoUmTJixcuNC2/9ChQzz22GMEBgbi5uZGpUqV6Nq1KxcvXrzm/Y8ZM4ZSpUoxa9asXMFy06ZNGTp0KLt372bp0qUADBgwAC8vL1JTU/N8loGBgVgslhx133PPPXh6euLt7U3btm35/fffcxwXFRWFl5cXsbGxtGnTBm9vb3r06HHVmmNjY6lVq1aucBegbNmyOT7/vQfvlef7448/MmjQIAICAvDz86Nfv35kZmaSmJhIr169KFWqFKVKleKVV17BNE3b8VfrgVvQvrFz5szh/vvvp2zZsri6ulKzZk1mzpyZq+arzZ2rXX/JkiU0atQId3d3ypQpwxNPPMGJEydyjLnynE+cOEH79u3x8vIiICCA6OjoHL9n18PDw4M777yTS5cucfbsWQASExMZMmQIQUFBuLq6UrVqVSZMmJCjjcOV5zVp0iSmTp3KHXfcgaurK3v37r3qs/zvf/9rm0t+fn7861//Yt++fblq+vHHH2nSpAlubm7ccccdfPjhhzd0byIiIiL2oBW8IiIiItcpJCSEiIgIPv30U1q3bg1cDiUvXrxI165dmTZtWq5j+vXrx9y5c+nduzeDBg3iyJEjzJgxg19//ZVNmzbh7OzM1KlTGThwIF5eXgwfPhyAcuXK5ThP//79CQgIYOTIkVy6dOmqNc6dO5ennnqKWrVq8eqrr+Ln58evv/7KqlWr6N69O5mZmURGRpKRkcHAgQMJDAzkxIkTLF++nMTERHx9ffM876FDhzhw4ABRUVH4+PjkOaZXr16MGjWK5cuX07VrV7p06cJ7773HihUr6NSpk21camoq33zzDVFRUbag+JNPPuHJJ58kMjKSCRMmkJqaysyZM7n77rv59ddfCQkJsR2fnZ1NZGQkd999N5MmTcLDw+OqzyM4OJgtW7awZ88eateufdVx13LlOY0ZM4affvqJWbNm4efnx+bNm6lcuTLjxo1j5cqVvPPOO9SuXZtevXrd0HX+bubMmdSqVYtHH30UJycnvvnmG/r374/VauX5558HKNDc+asrc7FJkyaMHz+eP//8k5iYGDZt2sSvv/6aIwi3WCxERkbSrFkzJk2axHfffcfkyZO54447eO65527onv744w8cHR3x8/MjNTWVFi1acOLECfr160flypXZvHkzr776KqdOnWLq1Kk5jp0zZw7p6ek888wzuLq64u/vn2c/3++++47WrVtTpUoVRo8eTVpaGtOnT6d58+b88ssvtrm0e/duHnroIQICAhg9ejTZ2dmMGjXqms9PREREpEgxRURERKRA5syZYwLm9u3bzRkzZpje3t5mamqqaZqm2alTJ/O+++4zTdM0g4ODzbZt29qO++GHH0zAXLBgQY7zrVq1Ktf2WrVqmS1atLjqte+++24zOzs7z31HjhwxTdM
|
|
|
|
" </div>\n",
|
|
|
|
" "
|
|
|
|
],
|
2024-08-08 11:03:14 +10:00
|
|
|
"text/plain": [
|
2024-08-16 08:26:12 +10:00
|
|
|
"Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
|
2024-08-08 11:03:14 +10:00
|
|
|
]
|
|
|
|
},
|
|
|
|
"metadata": {},
|
|
|
|
"output_type": "display_data"
|
|
|
|
}
|
|
|
|
],
|
|
|
|
"source": [
|
|
|
|
"metric_configs = {\n",
|
|
|
|
" **loan_metric_configs,\n",
|
|
|
|
" **property_metric_configs,\n",
|
|
|
|
" **income_metric_configs,\n",
|
|
|
|
" **baseline_metric_configs\n",
|
|
|
|
"}\n",
|
|
|
|
"\n",
|
2024-08-16 08:26:12 +10:00
|
|
|
"%matplotlib widget\n",
|
2024-08-08 11:03:14 +10:00
|
|
|
"simulate(TOTAL_LOAN_PERIODS, metric_configs)"
|
|
|
|
]
|
|
|
|
}
|
|
|
|
],
|
|
|
|
"metadata": {
|
|
|
|
"kernelspec": {
|
|
|
|
"display_name": "investment-simulator-KPfGkdIO-py3.12",
|
|
|
|
"language": "python",
|
|
|
|
"name": "python3"
|
|
|
|
},
|
|
|
|
"language_info": {
|
|
|
|
"codemirror_mode": {
|
|
|
|
"name": "ipython",
|
|
|
|
"version": 3
|
|
|
|
},
|
|
|
|
"file_extension": ".py",
|
|
|
|
"mimetype": "text/x-python",
|
|
|
|
"name": "python",
|
|
|
|
"nbconvert_exporter": "python",
|
|
|
|
"pygments_lexer": "ipython3",
|
|
|
|
"version": "3.12.0"
|
|
|
|
},
|
|
|
|
"orig_nbformat": 4
|
|
|
|
},
|
|
|
|
"nbformat": 4,
|
|
|
|
"nbformat_minor": 2
|
|
|
|
}
|