๐Ÿšง This site is under construction. Content and features are being added. Stay tuned! ๐Ÿšง

Building a Smarter Retirement Planner - Monte Carlo Simulation

From fixed returns to real-life uncertainty โ€” how I built a flexible, risk-aware tool for better financial planning

Posted by Kevin Cho on July 28, 2025

Python

๐Ÿงฎ Financial/Retirement Planner: From Inputs to Monte Carlo Insights

A full-stack, tax-aware financial planning engine built with Python, Flask, JavaScript, and modern web technologies — combining deterministic, stochastic, and optimizer-based simulations.


๐Ÿ“˜ Contents

  1. Why I Built This

  2. How I Built It

  3. Architecture & Technology Stack

  4. Database Design & Migrations

  5. Frontend Integration & UX Enhancements

  6. How to Input and Use the Planner

  7. Tax-Aware Engine & Withdrawal Optimizer

  8. Monte Carlo Simulation & Risk Visualization

  9. Sample Logic (Python + JavaScript)

  10. API Endpoints & Scenario Management

  11. Security Hardening

  12. What I Learned

  13. Roadmap & Closing Thoughts


1๏ธโƒฃ Why I Built This

Financial/Retirement Planning is one of the most consequential financial decisions we make — yet most online calculators are oversimplified, assume linear growth, and ignore taxes, inflation volatility, and withdrawal sequence risk.

As a data scientist + finance director, I built this planner to model how real portfolios behave, not just how they grow in theory.

Goals:

  • Capture market uncertainty using Monte Carlo simulations.

  • Integrate Canadian tax rules (RRSP, TFSA, OAS clawback, RRIF minimums).

  • Let users experiment live with assumptions and instantly visualize outcomes.

  • Build everything with production-grade web tech I use professionally:
    Python · Flask · PostgreSQL · Bootstrap · Chart.js · JavaScript · AWS EC2.

๐Ÿ‘‰ Try it live: databykevin.com/retirement


2๏ธโƒฃ How I Built It

  • Flask (Python) → backend routing, REST APIs, deterministic + stochastic logic.

  • NumPy / Pandas → financial math and Monte Carlo engine.

  • Plotly + Chart.js → responsive, interactive visualizations.

  • Bootstrap 5 → clean and mobile-friendly UI.

  • PostgreSQL @ AWS EC2 → persistent user scenarios.

  • Gunicorn + Nginx → stable production hosting.

  • Modern JS (ES6) → dynamic input syncing, tooltips, auto-recalc, optimizer logic.


3๏ธโƒฃ Architecture & Technology Stack

๐Ÿงฉ Backend — Flask API & Python Logic

Handles input parsing, financial modeling, and scenario CRUD operations via Flask Blueprints.

๐Ÿ—„๏ธ Database — PostgreSQL on EC2

Stores user accounts + serialized JSON inputs.
Uses SQLAlchemy ORM for migrations and integrity.

๐Ÿ’ป Frontend — Bootstrap + JavaScript + Plotly

Responsive UI, live re-runs on input changes, and dynamic charts (balances, taxes, optimizer).

โ˜๏ธ Deployment


 

Browser → HTTPS → Flask (Gunicorn + Nginx) → PostgreSQL on EC2


4๏ธโƒฃ Database Design & Migrations

Table Purpose
users Credentials + metadata
retirement_scenarios Scenario JSON inputs, timestamps, FK→users

Migration flow


 

flask db migrate -m "Add retirement_scenarios table" flask db upgrade

Verify in psql:


 

\c blogdb \dt retirement_scenarios SELECT * FROM retirement_scenarios;


5๏ธโƒฃ Frontend Integration & UX Enhancements

  • AJAX Save / Load for user scenarios

  • Bootstrap modals → friendly naming dialogs

  • Autosave reminders + status badge (“Saved โœ“ / Unsaved *”)

  • Keyboard + screen-reader accessibility

  • Fully responsive on desktop → mobile


6๏ธโƒฃ How to Input and Use the Planner

This section walks first-time users through every major control in the planner.

๐Ÿ Step 1 – Starting Balances

Enter your current portfolio split:

  • Taxable ($) — non-registered accounts (taxed annually).

  • RRSP ($) — tax-deferred; withdrawals taxable.

  • TFSA ($) — tax-free growth & withdrawals.
    ๐Ÿ’ก The “Total allocated” line checks that the three add up to your total investable assets.


๐Ÿ’ฐ Step 2 – Pre-Retirement Savings & Growth

  • Monthly Savings ($) — amount you currently invest monthly.

  • Annual Saving Increase Rate (%) — yearly escalation before retirement.

  • Pre-Retirement Return Rate (%) — expected annual return before retirement.
    Planner auto-routes yearly savings TFSA → RRSP → Taxable, applying TFSA caps that grow ≈ 2.1 %/yr from $7,000 (2025 base).


๐Ÿ•“ Step 3 – Retirement Timing & Expenses

  • Start Age / End Age — simulation range (life expectancy).

  • Monthly Spend ($) — after-tax living cost in today’s dollars.

  • Post-Retirement Return Rate (%) — expected investment return after retiring.

  • Inflation Rate (%) — cost-of-living growth applied to expenses and OAS.
    You can instantly test longevity risk by raising End Age and rerunning.


๐Ÿ‡จ๐Ÿ‡ฆ Step 4 – OAS / RRIF Details

  • OAS Monthly ($), Start Age, Clawback Threshold, Rate (%), Index OAS โœ“
     → models income-tested OAS clawback (15 % above threshold ≈ $90 k).

  • RRIF Start Age → auto-applies CRA minimum withdrawals (≈ 5.28 % @ 71).
    Inflation indexing is optional via checkbox.


๐Ÿ“Š Step 5 – Tax Brackets & Taxable Drag

  • Bracket 1/2 Limits + Rates → switch on progressive tax mode.

  • Taxable Drag (%) → yearly friction on Taxable growth (dividends, interest, gains).
    Use the Taxable Drag Helper Table to estimate based on:
    • allocation % • yield % • effective tax rate %
    Auto-apply fills the field for you.


๐Ÿงพ Step 6 – Withdrawal Order & Optimizer

Select order:


 

Taxable → TFSA → RRSP TFSA → Taxable → RRSP RRSP → Taxable → TFSA ... (6 combinations)

Then click Run Plan.
The system:

  1. Runs deterministic and tax-aware simulation.

  2. Displays tables + charts.

  3. If “Run Optimizer” is ON, computes the most tax-efficient hybrid order.


๐Ÿ“ˆ Step 7 – Review Outputs

  • Table A – Six-Withdrawal Ledger: year-by-year inflows/outflows per account, OAS, tax overlay, ending balances.

  • Charts:
    • Withdrawal orders (bar)  • Taxes (stack)  • Balances (line)  • Monte Carlo bands (P10–P90).

  • Download CSV (Part A) → export your projection for Excel review.


๐Ÿ’พ Step 8 – Save Your Scenario

Click Save Scenario, name it (e.g. “Base Case 2025”), and confirm.
Your inputs serialize to JSON and save in PostgreSQL.
Later, choose Load Scenario to instantly recall it for comparison.


7๏ธโƒฃ Tax-Aware Engine & Withdrawal Optimizer

Highlights:

  • Progressive tax bands or flat rate mode.

  • RRIF minimums auto-enforced ≥ 71.

  • OAS clawback 15 % above threshold.

  • Taxable Drag Helper links directly to portfolio mix.

  • Optimizer (beta) → analyzes all 6 orders + Next-$1 Analyzer to suggest best tax-aware draw sequence.


8๏ธโƒฃ Monte Carlo Simulation & Risk Visualization

  • 300 runs per simulation with geometric-mean correction (no +½σ² bias).

  • Separate distributions for returns and inflation.

  • Produces P10/P50/P90 bands & median line.

  • Displays deterministic vs probabilistic results side-by-side.

  • Clickable legend to toggle scenarios or optimizers.


9๏ธโƒฃ Sample Logic (Python + JavaScript)

Python (core loop)


 

for age in range(current_age, end_age + 1): if age < retire_age: assets += annual_saving * (1 + return_rate) else: draw = living_expense - cpp - oas assets = (assets - draw) * (1 + post_ret_rate)

Monte Carlo


 

returns = np.random.normal(mu, sigma, years) for r in returns: assets = (assets - withdrawal) * (1 + r)

JavaScript excerpt


 

function allocateByOrder(netNeed, balances, order, rrspFlat){ // dynamically draws from TFSA, RRSP, or Taxable with live tax overlay }


๐Ÿ”Œ 10๏ธโƒฃ API Endpoints & Scenario Management

Endpoint Method Purpose
/scenarios/save POST Save or update scenario
/scenarios/list GET List user scenarios
/scenarios/load/<id> GET Load scenario
/scenarios/delete/<id> DELETE Delete scenario

All protected via @login_required, user-scoped, and validated server-side.


11๏ธโƒฃ Security Hardening

  • Flask-Login authentication + pbkdf2_sha256 hashing

  • HTTPS enforced via Nginx

  • CSRF tokens on forms

  • ORM queries only (no SQL injection)

  • Rate limiting & session expiry

  • Cloud-firewall (DB port restricted to localhost)

  • Audit logging of save/load events


12๏ธโƒฃ What I Learned

  • Sequence risk & volatility dominate outcomes.

  • Taxes and draw order matter as much as return rate.

  • Monte Carlo translates fear into probability.

  • Bridging Python accuracy with JavaScript interactivity creates trust.

  • Good UX equals better financial decisions.


13๏ธโƒฃ Roadmap & Closing Thoughts

Upcoming

  • Glidepath rebalancing and dynamic inflation.

  • Multi-goal planning (education, home, retirement).

  • AI-based withdrawal optimizer v2.

  • PDF/CSV exports and summary dashboards.

  • User profiles with persistent preferences.


๐Ÿ’ฌ Final Reflection

This planner unites finance, data science, and user experience
mirroring my automation work in real-estate and portfolio analytics.

Financial Planning/Retirement is personal.
It should be data-driven, transparent, and actionable — not guesswork.

๐Ÿ‘‰ Try it yourself: databykevin.com/retirement

 

 

 

Login or Register to comment.


Comments

No comments yet.