Personal Financial Advisor Comprehensive toolkit for personal finance planning, helping individuals achieve financial wellness through budgeting, debt management, savings, investing, and goal-based planning. When to Use This Skill Creating personal budgets and spending plans Developing debt payoff strategies Planning emergency funds and savings goals Retirement planning and projections Investment portfolio allocation for individuals Tax optimization for personal finances Insurance needs assessment Net worth tracking and financial health analysis Setting and tracking financial goals Core Concepts 1. Financial Planning Hierarchy ┌─────────────────────────────────────────┐ │ WEALTH BUILDING │ │ (Investing, Retirement, Legacy) │ ├─────────────────────────────────────────┤ │ PROTECTION │ │ (Insurance, Estate Planning) │ ├─────────────────────────────────────────┤ │ DEBT ELIMINATION │ │ (High-interest → Low-interest) │ ├─────────────────────────────────────────┤ │ EMERGENCY FUND │ │ (3-6 months expenses) │ ├─────────────────────────────────────────┤ │ FOUNDATION │ │ (Budget, Cash Flow, Basic Savings) │ └─────────────────────────────────────────┘ 2. Key Financial Health Metrics Metric Target Formula Savings Rate ≥20% Savings / Gross Income Debt-to-Income <36% Monthly Debt / Monthly Income Emergency Fund 3-6 months Liquid Savings / Monthly Expenses Housing Ratio <28% Housing Costs / Gross Income Net Worth Growth Positive YoY Assets - Liabilities Budgeting Methods Pattern 1: Budgeting Frameworks from dataclasses import dataclass from typing import Dict , List , Optional from enum import Enum import pandas as pd class BudgetMethod ( Enum ) : FIFTY_THIRTY_TWENTY = "50/30/20" ZERO_BASED = "zero_based" ENVELOPE = "envelope" PAY_YOURSELF_FIRST = "pay_yourself_first" @dataclass class Income : """Monthly income sources.""" salary : float side_income : float = 0 investment_income : float = 0 other : float = 0 @property def total_gross ( self ) -
float : return self . salary + self . side_income + self . investment_income + self . other def after_tax ( self , tax_rate : float = 0.25 ) -
float : """Calculate after-tax income.""" return self . total_gross * ( 1 - tax_rate ) @dataclass class Expense : """Expense item with category.""" name : str amount : float category : str
'need', 'want', 'savings'
is_fixed : bool = True class BudgetPlanner : """Personal budget planning and analysis.""" def init ( self , income : Income , tax_rate : float = 0.25 ) : self . income = income self . tax_rate = tax_rate self . expenses : List [ Expense ] = [ ] def add_expense ( self , expense : Expense ) -
None : """Add an expense to the budget.""" self . expenses . append ( expense ) @property def monthly_income ( self ) -
float : """After-tax monthly income.""" return self . income . after_tax ( self . tax_rate )
==================== 50/30/20 RULE ====================
def fifty_thirty_twenty ( self ) -
Dict [ str , float ] : """ 50/30/20 Budget Rule. - 50% Needs: Housing, utilities, groceries, insurance, minimum debt payments - 30% Wants: Entertainment, dining out, hobbies, subscriptions - 20% Savings: Emergency fund, retirement, investments, extra debt payments """ income = self . monthly_income return { 'needs_budget' : income * 0.50 , 'wants_budget' : income * 0.30 , 'savings_budget' : income * 0.20 , 'needs_actual' : sum ( e . amount for e in self . expenses if e . category == 'need' ) , 'wants_actual' : sum ( e . amount for e in self . expenses if e . category == 'want' ) , 'savings_actual' : sum ( e . amount for e in self . expenses if e . category == 'savings' ) , } def analyze_fifty_thirty_twenty ( self ) -
Dict [ str , any ] : """Analyze budget against 50/30/20 targets.""" budget = self . fifty_thirty_twenty ( ) return { 'needs' : { 'budget' : budget [ 'needs_budget' ] , 'actual' : budget [ 'needs_actual' ] , 'variance' : budget [ 'needs_budget' ] - budget [ 'needs_actual' ] , 'on_track' : budget [ 'needs_actual' ] <= budget [ 'needs_budget' ] } , 'wants' : { 'budget' : budget [ 'wants_budget' ] , 'actual' : budget [ 'wants_actual' ] , 'variance' : budget [ 'wants_budget' ] - budget [ 'wants_actual' ] , 'on_track' : budget [ 'wants_actual' ] <= budget [ 'wants_budget' ] } , 'savings' : { 'budget' : budget [ 'savings_budget' ] , 'actual' : budget [ 'savings_actual' ] , 'variance' : budget [ 'savings_actual' ] - budget [ 'savings_budget' ] , 'on_track' : budget [ 'savings_actual' ] = budget [ 'savings_budget' ] } }
==================== ZERO-BASED BUDGETING ====================
def zero_based_budget ( self ) -
Dict [ str , float ] : """ Zero-Based Budgeting. Every dollar has a job. Income - All Expenses = $0 """ total_expenses = sum ( e . amount for e in self . expenses ) unallocated = self . monthly_income - total_expenses return { 'income' : self . monthly_income , 'total_allocated' : total_expenses , 'unallocated' : unallocated , 'is_balanced' : abs ( unallocated ) < 1.0 ,
Within $1
'expenses_by_category' : self . _group_expenses_by_category ( ) } def _group_expenses_by_category ( self ) -
Dict [ str , float ] : """Group expenses by category.""" categories = { } for expense in self . expenses : if expense . category not in categories : categories [ expense . category ] = 0 categories [ expense . category ] += expense . amount return categories
==================== ENVELOPE SYSTEM ====================
def envelope_budget ( self , envelopes : Dict [ str , float ] ) -
Dict [ str , Dict ] : """ Envelope Budgeting System. Allocate cash to specific spending categories. When envelope is empty, stop spending. """ result = { } for category , budget in envelopes . items ( ) : spent = sum ( e . amount for e in self . expenses if e . category == category ) result [ category ] = { 'budget' : budget , 'spent' : spent , 'remaining' : budget - spent , 'percent_used' : ( spent / budget * 100 ) if budget
0 else 0 } return result
==================== PAY YOURSELF FIRST ====================
def pay_yourself_first ( self , savings_target_percent : float = 0.20 ) -
Dict [ str , float ] : """ Pay Yourself First Strategy. Save first, then budget the rest for expenses. """ savings_amount = self . monthly_income * savings_target_percent spending_budget = self . monthly_income - savings_amount actual_spending = sum ( e . amount for e in self . expenses if e . category != 'savings' ) return { 'target_savings' : savings_amount , 'spending_budget' : spending_budget , 'actual_spending' : actual_spending , 'spending_variance' : spending_budget - actual_spending , 'on_track' : actual_spending <= spending_budget }
==================== SAVINGS RATE ====================
def calculate_savings_rate ( self ) -
float : """Calculate monthly savings rate.""" savings = sum ( e . amount for e in self . expenses if e . category == 'savings' ) return savings / self . income . total_gross if self . income . total_gross
0 else 0 Pattern 2: Debt Management Strategies from dataclasses import dataclass from typing import List , Dict import numpy as np @dataclass class Debt : """Individual debt account.""" name : str balance : float interest_rate : float
Annual rate as decimal
minimum_payment : float def monthly_interest ( self ) -
float : """Calculate monthly interest charge.""" return self . balance * ( self . interest_rate / 12 ) class DebtPayoffCalculator : """Debt payoff strategy calculator.""" def init ( self , debts : List [ Debt ] , extra_payment : float = 0 ) : self . debts = debts self . extra_payment = extra_payment @property def total_debt ( self ) -
float : return sum ( d . balance for d in self . debts ) @property def total_minimum_payments ( self ) -
float : return sum ( d . minimum_payment for d in self . debts ) @property def weighted_avg_rate ( self ) -
float : """Calculate weighted average interest rate.""" if self . total_debt == 0 : return 0 return sum ( d . balance * d . interest_rate for d in self . debts ) / self . total_debt
==================== DEBT SNOWBALL ====================
def debt_snowball ( self ) -
Dict : """ Debt Snowball Method. Pay minimum on all debts, put extra toward SMALLEST balance first. Psychological wins build momentum. """
Sort by balance (smallest first)
sorted_debts
sorted ( self . debts , key = lambda d : d . balance ) return self . _simulate_payoff ( sorted_debts , "snowball" )
==================== DEBT AVALANCHE ====================
def debt_avalanche ( self ) -
Dict : """ Debt Avalanche Method. Pay minimum on all debts, put extra toward HIGHEST interest rate first. Mathematically optimal - minimizes total interest paid. """
Sort by interest rate (highest first)
sorted_debts
sorted ( self . debts , key = lambda d : d . interest_rate , reverse = True ) return self . _simulate_payoff ( sorted_debts , "avalanche" ) def _simulate_payoff ( self , sorted_debts : List [ Debt ] , method : str ) -
Dict : """Simulate debt payoff over time."""
Create working copies
balances
{ d . name : d . balance for d in sorted_debts } rates = { d . name : d . interest_rate for d in sorted_debts } minimums = { d . name : d . minimum_payment for d in sorted_debts } total_paid = 0 total_interest = 0 months = 0 payoff_order = [ ] monthly_schedule = [ ] while any ( b
0 for b in balances . values ( ) ) : months += 1 if months
360 :
30 year cap
break month_interest = 0 month_principal = 0 extra_remaining = self . extra_payment
Apply interest to all debts
for name in balances : if balances [ name ]
0 : interest = balances [ name ] * ( rates [ name ] / 12 ) balances [ name ] += interest month_interest += interest
Pay minimums on all debts
for name in balances : if balances [ name ]
0 : payment = min ( minimums [ name ] , balances [ name ] ) balances [ name ] -= payment month_principal += payment if balances [ name ] <= 0 : balances [ name ] = 0 payoff_order . append ( { 'name' : name , 'month' : months } ) extra_remaining += minimums [ name ]
Freed up payment
Apply extra payment to target debt
for debt in sorted_debts : if balances [ debt . name ]
0 and extra_remaining
0 : payment = min ( extra_remaining , balances [ debt . name ] ) balances [ debt . name ] -= payment month_principal += payment extra_remaining -= payment if balances [ debt . name ] <= 0 : balances [ debt . name ] = 0 payoff_order . append ( { 'name' : debt . name , 'month' : months } ) total_interest += month_interest total_paid += month_interest + month_principal monthly_schedule . append ( { 'month' : months , 'interest_paid' : month_interest , 'principal_paid' : month_principal , 'remaining_balance' : sum ( balances . values ( ) ) } ) return { 'method' : method , 'months_to_payoff' : months , 'years_to_payoff' : months / 12 , 'total_paid' : total_paid , 'total_interest' : total_interest , 'original_balance' : self . total_debt , 'payoff_order' : payoff_order , 'monthly_schedule' : monthly_schedule } def compare_methods ( self ) -
Dict : """Compare snowball vs avalanche methods.""" snowball = self . debt_snowball ( ) avalanche = self . debt_avalanche ( ) return { 'snowball' : snowball , 'avalanche' : avalanche , 'interest_savings' : snowball [ 'total_interest' ] - avalanche [ 'total_interest' ] , 'time_difference_months' : snowball [ 'months_to_payoff' ] - avalanche [ 'months_to_payoff' ] , 'recommended' : 'avalanche' if avalanche [ 'total_interest' ] < snowball [ 'total_interest' ] else 'snowball' } Pattern 3: Emergency Fund Calculator @dataclass class MonthlyExpenses : """Monthly essential expenses.""" housing : float
Rent/mortgage
utilities : float groceries : float transportation : float insurance : float minimum_debt_payments : float other_essentials : float = 0 @property def total ( self ) -
float : return ( self . housing + self . utilities + self . groceries + self . transportation + self . insurance + self . minimum_debt_payments + self . other_essentials ) class EmergencyFundPlanner : """Emergency fund planning and tracking.""" def init ( self , monthly_expenses : MonthlyExpenses , current_savings : float = 0 , job_stability : str = "stable"
stable, moderate, unstable
) : self . expenses = monthly_expenses self . current_savings = current_savings self . job_stability = job_stability def recommended_months ( self ) -
int : """Get recommended emergency fund months based on job stability.""" recommendations = { "stable" : 3 ,
Stable job, dual income
"moderate" : 6 ,
Single income, some variability
"unstable" : 9 ,
Freelance, commission-based, volatile industry
"self_employed" : 12
Business owners
} return recommendations . get ( self . job_stability , 6 ) def target_amount ( self ) -
float : """Calculate target emergency fund amount.""" return self . expenses . total * self . recommended_months ( ) def current_coverage ( self ) -
float : """Calculate current months of coverage.""" return self . current_savings / self . expenses . total if self . expenses . total
0 else 0 def gap_analysis ( self ) -
Dict : """Analyze emergency fund gap.""" target = self . target_amount ( ) gap = max ( 0 , target - self . current_savings ) return { 'target_months' : self . recommended_months ( ) , 'target_amount' : target , 'current_savings' : self . current_savings , 'current_months_coverage' : self . current_coverage ( ) , 'gap_amount' : gap , 'percent_funded' : ( self . current_savings / target * 100 ) if target
0 else 100 , 'is_fully_funded' : self . current_savings = target } def savings_plan ( self , monthly_contribution : float ) -
Dict : """Create plan to reach emergency fund target.""" gap = self . gap_analysis ( ) [ 'gap_amount' ] if gap <= 0 : return { 'already_funded' : True , 'months_to_goal' : 0 } months_to_goal = gap / monthly_contribution if monthly_contribution
0 else float ( 'inf' ) return { 'already_funded' : False , 'gap_amount' : gap , 'monthly_contribution' : monthly_contribution , 'months_to_goal' : months_to_goal , 'years_to_goal' : months_to_goal / 12 , 'target_date_months' : int ( np . ceil ( months_to_goal ) ) } Pattern 4: Retirement Planning class RetirementPlanner : """Retirement savings and projection calculator.""" def init ( self , current_age : int , retirement_age : int , current_savings : float , annual_contribution : float , expected_return : float = 0.07 ,
7% average market return
inflation_rate : float = 0.03 ) : self . current_age = current_age self . retirement_age = retirement_age self . current_savings = current_savings self . annual_contribution = annual_contribution self . expected_return = expected_return self . inflation_rate = inflation_rate @property def years_to_retirement ( self ) -
int : return max ( 0 , self . retirement_age - self . current_age ) def future_value ( self ) -
float : """ Calculate future value of retirement savings. FV = PV × (1 + r)^n + PMT × [((1 + r)^n - 1) / r] """ n = self . years_to_retirement r = self . expected_return
Future value of current savings
fv_current
self . current_savings * ( ( 1 + r ) ** n )
Future value of annual contributions (annuity)
if r
0 : fv_contributions = self . annual_contribution * ( ( ( 1 + r ) ** n - 1 ) / r ) else : fv_contributions = self . annual_contribution * n return fv_current + fv_contributions def real_future_value ( self ) -
float : """Future value adjusted for inflation (today's dollars).""" nominal_fv = self . future_value ( ) return nominal_fv / ( ( 1 + self . inflation_rate ) ** self . years_to_retirement ) def retirement_income ( self , withdrawal_rate : float = 0.04 ) -
Dict : """ Calculate sustainable retirement income using 4% rule. The 4% rule: Withdraw 4% of portfolio in year 1, then adjust for inflation. """ portfolio = self . future_value ( ) real_portfolio = self . real_future_value ( ) return { 'portfolio_at_retirement' : portfolio , 'portfolio_real_value' : real_portfolio , 'annual_income_nominal' : portfolio * withdrawal_rate , 'annual_income_real' : real_portfolio * withdrawal_rate , 'monthly_income_nominal' : portfolio * withdrawal_rate / 12 , 'monthly_income_real' : real_portfolio * withdrawal_rate / 12 } def required_savings_for_income ( self , target_annual_income : float , withdrawal_rate : float = 0.04 ) -
Dict : """Calculate required savings to achieve target retirement income.""" required_portfolio = target_annual_income / withdrawal_rate
Solve for required annual contribution
FV = PV × (1 + r)^n + PMT × [((1 + r)^n - 1) / r]
PMT = (FV - PV × (1 + r)^n) / [((1 + r)^n - 1) / r]
n
self . years_to_retirement r = self . expected_return fv_current = self . current_savings * ( ( 1 + r ) ** n ) remaining_needed = required_portfolio - fv_current if r
0 and n
0 : annuity_factor = ( ( 1 + r ) ** n - 1 ) / r required_annual = remaining_needed / annuity_factor else : required_annual = remaining_needed / max ( n , 1 ) return { 'target_annual_income' : target_annual_income , 'required_portfolio' : required_portfolio , 'current_trajectory' : self . future_value ( ) , 'gap' : max ( 0 , required_portfolio - self . future_value ( ) ) , 'required_annual_contribution' : max ( 0 , required_annual ) , 'required_monthly_contribution' : max ( 0 , required_annual / 12 ) } def compound_growth_schedule ( self ) -
List [ Dict ] : """Generate year-by-year growth projection.""" schedule = [ ] balance = self . current_savings for year in range ( self . years_to_retirement + 1 ) : age = self . current_age + year schedule . append ( { 'year' : year , 'age' : age , 'starting_balance' : balance , 'contribution' : self . annual_contribution if year
0 else 0 , 'growth' : balance * self . expected_return if year
0 else 0 , 'ending_balance' : balance } ) if year < self . years_to_retirement : balance = balance * ( 1 + self . expected_return ) + self . annual_contribution
Update ending balances
for i in range ( len ( schedule ) - 1 ) : schedule [ i ] [ 'ending_balance' ] = schedule [ i + 1 ] [ 'starting_balance' ] schedule [ - 1 ] [ 'ending_balance' ] = balance return schedule
==================== RETIREMENT ACCOUNT OPTIMIZATION ====================
def contribution_priority ( self , has_employer_401k : bool = True , employer_match_percent : float = 0.03 , has_hsa : bool = False ) -
List [ str ] : """ Recommended contribution priority order. Standard priority: 1. 401(k) up to employer match (free money) 2. HSA (triple tax advantage) 3. Max out Roth IRA 4. Max out 401(k) 5. Taxable brokerage """ priority = [ ] if has_employer_401k and employer_match_percent
0 : priority . append ( f"1. 401(k) to employer match ( { employer_match_percent * 100 : .0f } %)" ) if has_hsa : priority . append ( "2. Max HSA ($4,150 individual / $8,300 family 2024)" ) priority . extend ( [ "3. Max Roth IRA ($7,000 / $8,000 if 50+ in 2024)" , "4. Max 401(k) ($23,000 / $30,500 if 50+ in 2024)" , "5. Taxable brokerage account" ] ) return priority Pattern 5: Investment Portfolio Allocation class PortfolioAllocator : """Personal investment portfolio allocation.""" def init ( self , age : int , risk_tolerance : str = "moderate" ) : self . age = age self . risk_tolerance = risk_tolerance
conservative, moderate, aggressive
def age_based_allocation ( self ) -
Dict [ str , float ] : """ Age-based asset allocation rule. Traditional: Bonds = Age (e.g., 30 years old = 30% bonds) Modern: Bonds = Age - 20 (more aggressive for longer life expectancy) """
Modern rule (age - 20)
bond_percent
max ( 0 , min ( 80 , self . age - 20 ) ) / 100 stock_percent = 1 - bond_percent return { 'stocks' : stock_percent , 'bonds' : bond_percent , 'rationale' : f"At age { self . age } , allocate { stock_percent * 100 : .0f } % stocks, { bond_percent * 100 : .0f } % bonds" } def risk_based_allocation ( self ) -
Dict [ str , float ] : """Allocation based on risk tolerance.""" allocations = { "conservative" : { 'stocks' : 0.30 , 'bonds' : 0.50 , 'cash' : 0.20 } , "moderate" : { 'stocks' : 0.60 , 'bonds' : 0.30 , 'cash' : 0.10 } , "aggressive" : { 'stocks' : 0.80 , 'bonds' : 0.15 , 'cash' : 0.05 } , "very_aggressive" : { 'stocks' : 0.95 , 'bonds' : 0.05 , 'cash' : 0.00 } } return allocations . get ( self . risk_tolerance , allocations [ "moderate" ] ) def three_fund_portfolio ( self , international_percent : float = 0.30 ) -
Dict [ str , float ] : """ Three-Fund Portfolio (Bogleheads approach). Simple, low-cost, diversified portfolio: 1. US Total Stock Market 2. International Stock Market 3. US Total Bond Market """ base = self . age_based_allocation ( ) stock_allocation = base [ 'stocks' ] bond_allocation = base [ 'bonds' ] return { 'us_total_stock' : stock_allocation * ( 1 - international_percent ) , 'international_stock' : stock_allocation * international_percent , 'us_total_bond' : bond_allocation , 'total' : 1.0 , 'example_funds' : { 'us_total_stock' : 'VTI, VTSAX, FSKAX' , 'international_stock' : 'VXUS, VTIAX, FTIHX' , 'us_total_bond' : 'BND, VBTLX, FXNAX' } } def target_date_equivalent ( self , retirement_year : int ) -
Dict : """Calculate allocation similar to target-date funds.""" years_to_retirement = retirement_year - 2024 if years_to_retirement
40 : stocks = 0.90 elif years_to_retirement
25 : stocks = 0.85 elif years_to_retirement
15 : stocks = 0.75 elif years_to_retirement
5 : stocks = 0.60 elif years_to_retirement
0 : stocks = 0.50 else :
In retirement
stocks
0.40 return { 'retirement_year' : retirement_year , 'years_to_retirement' : years_to_retirement , 'stocks' : stocks , 'bonds' : 1 - stocks , 'glide_path' : "Becomes more conservative as retirement approaches" } Pattern 6: Net Worth Tracker @dataclass class FinancialSnapshot : """Point-in-time financial snapshot.""" date : str
Assets
checking : float = 0 savings : float = 0 investments : float = 0
Brokerage accounts
retirement_401k : float = 0 retirement_ira : float = 0 home_value : float = 0 vehicle_value : float = 0 other_assets : float = 0
Liabilities
mortgage : float = 0 auto_loans : float = 0 student_loans : float = 0 credit_cards : float = 0 other_debt : float = 0 @property def total_assets ( self ) -
float : return ( self . checking + self . savings + self . investments + self . retirement_401k + self . retirement_ira + self . home_value + self . vehicle_value + self . other_assets ) @property def liquid_assets ( self ) -
float : return self . checking + self . savings + self . investments @property def retirement_assets ( self ) -
float : return self . retirement_401k + self . retirement_ira @property def total_liabilities ( self ) -
float : return ( self . mortgage + self . auto_loans + self . student_loans + self . credit_cards + self . other_debt ) @property def net_worth ( self ) -
float : return self . total_assets - self . total_liabilities class NetWorthTracker : """Track net worth over time.""" def init ( self ) : self . snapshots : List [ FinancialSnapshot ] = [ ] def add_snapshot ( self , snapshot : FinancialSnapshot ) -
None : """Add a financial snapshot.""" self . snapshots . append ( snapshot ) self . snapshots . sort ( key = lambda s : s . date ) def current_net_worth ( self ) -
float : """Get most recent net worth.""" return self . snapshots [ - 1 ] . net_worth if self . snapshots else 0 def net_worth_change ( self , periods : int = 1 ) -
Dict : """Calculate net worth change over periods.""" if len ( self . snapshots ) < 2 : return { 'change' : 0 , 'percent_change' : 0 } current = self . snapshots [ - 1 ] . net_worth previous = self . snapshots [ - min ( periods + 1 , len ( self . snapshots ) ) ] . net_worth change = current - previous return { 'current' : current , 'previous' : previous , 'change' : change , 'percent_change' : ( change / previous * 100 ) if previous != 0 else 0 } def financial_ratios ( self ) -
Dict [ str , float ] : """Calculate key financial health ratios.""" if not self . snapshots : return { } latest = self . snapshots [ - 1 ] return { 'liquidity_ratio' : latest . liquid_assets / latest . total_liabilities if latest . total_liabilities
0 else float ( 'inf' ) , 'debt_to_asset' : latest . total_liabilities / latest . total_assets if latest . total_assets
0 else 0 , 'emergency_fund_months' : latest . liquid_assets / ( latest . total_liabilities + 1 ) ,
Rough estimate
'retirement_progress' : latest . retirement_assets / latest . total_assets if latest . total_assets
0 else 0 } def asset_allocation ( self ) -
Dict [ str , float ] : """Current asset allocation breakdown.""" if not self . snapshots : return { } latest = self . snapshots [ - 1 ] total = latest . total_assets if total == 0 : return { } return { 'cash' : ( latest . checking + latest . savings ) / total , 'investments' : latest . investments / total , 'retirement' : latest . retirement_assets / total , 'real_estate' : latest . home_value / total , 'other' : ( latest . vehicle_value + latest . other_assets ) / total } Pattern 7: Financial Goal Planner from datetime import datetime , timedelta from typing import List , Dict , Optional @dataclass class FinancialGoal : """SMART financial goal.""" name : str target_amount : float target_date : str
YYYY-MM-DD
current_savings : float = 0 priority : int = 1
1 = highest priority
@property def remaining_amount ( self ) -
float : return max ( 0 , self . target_amount - self . current_savings ) @property def percent_complete ( self ) -
float : return ( self . current_savings / self . target_amount * 100 ) if self . target_amount
0 else 100 @property def months_remaining ( self ) -
int : target = datetime . strptime ( self . target_date , "%Y-%m-%d" ) today = datetime . now ( ) delta = target - today return max ( 0 , delta . days // 30 ) class GoalPlanner : """Multi-goal financial planning.""" def init ( self , monthly_savings_budget : float ) : self . monthly_budget = monthly_savings_budget self . goals : List [ FinancialGoal ] = [ ] def add_goal ( self , goal : FinancialGoal ) -
None : """Add a financial goal.""" self . goals . append ( goal ) self . goals . sort ( key = lambda g : g . priority ) def analyze_goal ( self , goal : FinancialGoal ) -
Dict : """Analyze single goal feasibility.""" months = goal . months_remaining required_monthly = goal . remaining_amount / months if months
0 else goal . remaining_amount return { 'goal' : goal . name , 'target_amount' : goal . target_amount , 'current_savings' : goal . current_savings , 'remaining' : goal . remaining_amount , 'percent_complete' : goal . percent_complete , 'months_remaining' : months , 'required_monthly' : required_monthly , 'is_achievable' : required_monthly <= self . monthly_budget , 'surplus_deficit' : self . monthly_budget - required_monthly } def allocate_to_goals ( self ) -
Dict [ str , float ] : """Allocate monthly savings across goals by priority.""" allocations = { } remaining_budget = self . monthly_budget for goal in self . goals : analysis = self . analyze_goal ( goal ) required = analysis [ 'required_monthly' ] allocation = min ( required , remaining_budget ) allocations [ goal . name ] = { 'allocated' : allocation , 'required' : required , 'shortfall' : max ( 0 , required - allocation ) } remaining_budget -= allocation allocations [ 'unallocated' ] = remaining_budget return allocations def summary ( self ) -
Dict : """Generate goals summary.""" total_needed = sum ( g . remaining_amount for g in self . goals ) total_monthly_required = sum ( self . analyze_goal ( g ) [ 'required_monthly' ] for g in self . goals ) return { 'total_goals' : len ( self . goals ) , 'total_amount_needed' : total_needed , 'total_monthly_required' : total_monthly_required , 'monthly_budget' : self . monthly_budget , 'budget_gap' : total_monthly_required - self . monthly_budget , 'can_achieve_all' : total_monthly_required <= self . monthly_budget } Quick Reference Key Rules of Thumb
Budgeting
FIFTY_THIRTY_TWENTY
"50% needs, 30% wants, 20% savings" PAY_YOURSELF_FIRST = "Save before you spend"
Emergency Fund
EMERGENCY_FUND
"3-6 months of essential expenses" STABLE_JOB = 3
months
UNSTABLE_JOB
6
months
SELF_EMPLOYED
12
months
Debt
DEBT_TO_INCOME_LIMIT
0.36
36% max
HOUSING_RATIO_LIMIT
0.28
28% max
Retirement
SAVINGS_RATE_TARGET
0.15
15% of income minimum
RULE_OF_25
"Save 25x annual expenses for retirement" FOUR_PERCENT_RULE = "Withdraw 4% annually in retirement"
Investing
STOCKS_ALLOCATION
lambda age : 100 - age
or 110 - age (aggressive)
Financial Health Scorecard Metric Poor Fair Good Excellent Savings Rate <5% 5-10% 10-20%
20% Emergency Fund <1 mo 1-3 mo 3-6 mo 6 mo Debt-to-Income 50% 36-50% 20-36% <20% Retirement Savings <1x salary 1-3x 3-6x 6x Net Worth Negative Break-even Growing Accelerating Best Practices Do's Pay yourself first - Automate savings before spending Build emergency fund before investing - Foundation first Take full employer match - It's free money Track net worth monthly - What gets measured improves Review and rebalance annually - Stay on track Increase savings with raises - Avoid lifestyle inflation Don'ts Don't skip emergency fund - Debt can spiral without buffer Don't time the market - Consistent investing beats timing Don't ignore high-interest debt - Paying 20% interest beats 7% returns Don't over-leverage housing - Stay under 28% of income Don't neglect insurance - Protect against catastrophic loss Don't compare to others - Focus on your own progress Common Pitfalls Pitfall Impact Solution No budget Overspending Use 50/30/20 rule No emergency fund Debt spiral Build 3-6 months first Only saving in 401k Limited access Balance with Roth & taxable Too conservative young Missed growth Age - 20 = bond percentage Lifestyle inflation Never catch up Save raises & bonuses Resources Bogleheads Investment Philosophy NerdWallet Financial Calculators Mr. Money Mustache - Financial Independence The Simple Path to Wealth (JL Collins) Parent Hub _business-finance-mastery