import matplotlib.pyplot as plt import numpy_financial as npf import streamlit as st import pandas as pd import numpy as np def calculate_loan_shift_savings(current_balance, current_rate, new_rate, remaining_term, processing_fee): # Calculate monthly interest rates monthly_current_rate = current_rate / 12 / 100 monthly_new_rate = new_rate / 12 / 100 # Calculate monthly payments for current and new loan current_monthly_payment = npf.pmt(monthly_current_rate, remaining_term, -current_balance) new_monthly_payment = npf.pmt(monthly_new_rate, remaining_term, -current_balance) # Calculate total payments for current and new loan total_current_payment = current_monthly_payment * remaining_term total_new_payment = new_monthly_payment * remaining_term + processing_fee # Calculate savings savings = total_current_payment - total_new_payment return savings def loan_shift_decision_tab(): st.header("Should I Shift My Loan Calculator") current_balance = st.number_input("Current Loan Balance", min_value=0.0) current_rate = st.number_input("Current Interest Rate (Annual %)", min_value=0.0) new_rate = st.number_input("New Interest Rate (Annual %)", min_value=0.0) remaining_term = st.number_input("Remaining Term of Loan (Months)", min_value=1) processing_fee = st.number_input("Processing Fee for New Loan", min_value=0.0) if st.button("Calculate Savings"): savings = calculate_loan_shift_savings(current_balance, current_rate, new_rate, remaining_term, processing_fee) if savings > 0: st.success(f"Shifting your loan saves you ${savings:,.2f} over the remaining term of the loan.") else: st.error(f"Shifting your loan does not save money. It costs you an additional ${-savings:,.2f}.") def calculate_real_future_values(principal, interest_rate, inflation_rate, years): return np.array([principal * ((1 + interest_rate / 100) ** year) / ((1 + inflation_rate / 100) ** year) for year in np.arange(1, years + 1)]) def inflation_calculator_tab(): st.header("Multiple Investments Growth Calculator with Inflation") st.write("Calculate and compare the real value growth of multiple investments considering inflation.") # Dynamic input fields for multiple amounts, rates, and inflation rate entries = [] n_entries = st.number_input("Number of Investments", min_value=1, max_value=10, value=1, step=1) for i in range(n_entries): col1, col2 = st.columns(2) with col1: amount = st.number_input(f"Amount {i+1}", min_value=0.0, value=1000.0, format="%.2f") with col2: rate = st.number_input(f"Interest Rate {i+1} (%)", min_value=0.0, value=5.0, format="%.2f") entries.append((amount, rate)) inflation_rate = st.number_input("Annual Inflation Rate (%)", min_value=0.0, value=2.0, format="%.2f") years = st.number_input("Number of Years:", min_value=1, max_value=100, step=1) if st.button('Calculate and Plot'): plt.figure(figsize=(10, 6)) combined_future_value = np.zeros(years) for i, (amount, rate) in enumerate(entries): real_future_values = calculate_real_future_values(amount, rate, inflation_rate, years) combined_future_value += real_future_values plt.plot(range(1, years + 1), real_future_values, label=f'Investment {i+1}') plt.plot(range(1, years + 1), combined_future_value, label='Combined Investment (Adjusted for Inflation)', color='black', linestyle='--') plt.title('Investment Real Value Growth Over Time Considering Inflation') plt.xlabel('Years') plt.ylabel('Real Future Value') plt.legend() st.pyplot(plt) def calculate_emi(principal, annual_interest_rate, tenure_years): monthly_interest_rate = annual_interest_rate / (12 * 100) total_payments = tenure_years * 12 emi = principal * monthly_interest_rate / (1 - (1 + monthly_interest_rate) ** -total_payments) return emi def emi_breakdown(principal, annual_interest_rate, tenure_years): monthly_interest_rate = annual_interest_rate / (12 * 100) total_payments = tenure_years * 12 emi = calculate_emi(principal, annual_interest_rate, tenure_years) balance = principal emi_data = [] for month in range(1, total_payments + 1): interest = balance * monthly_interest_rate principal_payment = emi - interest balance -= principal_payment emi_data.append([month, emi, principal_payment, interest, balance]) return pd.DataFrame(emi_data, columns=["Month", "EMI", "Principal", "Interest", "Balance"]) def plot_emi_data(emi_df): plt.figure(figsize=(10, 5)) plt.plot(emi_df['Month'], emi_df['Principal'], label='Principal Component') plt.plot(emi_df['Month'], emi_df['Interest'], label='Interest Component') plt.xlabel('Month') plt.ylabel('Amount') plt.title('EMI Components Over Time') plt.legend() st.pyplot(plt) plt.figure(figsize=(10, 5)) plt.plot(emi_df['Month'], emi_df['Balance'], label='Remaining Balance') plt.xlabel('Month') plt.ylabel('Amount') plt.title('Loan Balance Over Time') plt.legend() st.pyplot(plt) def emi_calculator_tab(): st.header("EMI Calculator") loan_amount = st.number_input("Loan Amount", min_value=0.0, value=100000.0, step=1000.0) annual_interest_rate = st.number_input("Annual Interest Rate (%)", min_value=0.0, value=8.0, step=0.1) tenure_years = st.number_input("Tenure (Years)", min_value=1, value=10, step=1) if st.button('Calculate EMI'): emi = calculate_emi(loan_amount, annual_interest_rate, tenure_years) st.success(f"Monthly EMI: ₹ {emi:.2f}") emi_df = emi_breakdown(loan_amount, annual_interest_rate, tenure_years) plot_emi_data(emi_df) st.write(emi_df) def calculate_compound_interest(principal, annual_rate, compounding_frequency, years): """ Calculate the compound interest based on the given parameters. """ factor = { "Monthly": 12, "Quarterly": 4, "Yearly": 1 } n = factor[compounding_frequency] amount = principal * ((1 + annual_rate/(100 * n)) ** (n * years)) return amount def plot_growth(principal, annual_rate, compounding_frequency, years): """ Plot the returns of the investment over time. """ factor = { "Monthly": 12, "Quarterly": 4, "Yearly": 1 } n = factor[compounding_frequency] times = np.linspace(0, years, years * n + 1) future_values = principal * ((1 + annual_rate/(100 * n)) ** (n * times)) returns = future_values - principal plt.figure(figsize=(10, 6)) plt.plot(times, returns, color='purple', linestyle='-', linewidth=2, label='Investment Returns') plt.fill_between(times, returns, color='blue', alpha=0.3) plt.title('Investment Returns Over Time') plt.xlabel('Years') plt.ylabel('Returns (Future Value - Principal)') plt.legend() st.pyplot(plt) def plot_growth_old(principal, annual_rate, compounding_frequency, years): """ Plot the growth of the investment over time. """ factor = { "Monthly": 12, "Quarterly": 4, "Yearly": 1 } n = factor[compounding_frequency] times = np.linspace(0, years, years * n + 1) values = principal * ((1 + annual_rate/(100 * n)) ** (n * times)) plt.figure(figsize=(10, 6)) plt.plot(times, values, color='purple', linestyle='-', linewidth=2, label='Investment Growth') plt.fill_between(times, values, color='blue', alpha=0.3) plt.title('Compound Interest Growth Over Time') plt.xlabel('Years') plt.ylabel('Future Value') plt.legend() st.pyplot(plt) def compound_interest_calculator(): st.header("Compound Interest Calculator") st.write("Calculate the future value of your investment with compound interest.") principal = st.number_input("Enter the principal amount:", min_value=0.0, value=10000.0, format="%.2f") annual_rate = st.number_input("Enter the annual interest rate (%):", min_value=0.0, value=5.0, format="%.2f") compounding_frequency = st.selectbox("Select the compounding frequency:", ["Monthly", "Quarterly", "Yearly"]) years = st.number_input("Enter the number of years:", min_value=1, max_value=50, value=10, step=1) if st.button('Calculate and Plot'): future_value = calculate_compound_interest(principal, annual_rate, compounding_frequency, years) st.success(f"The future value of your investment is: ₹ {future_value:.2f}") plot_growth(principal, annual_rate, compounding_frequency, years) def calculate_fire_number(monthly_expenses, withdrawal_rate): """ Calculate the FIRE Number based on monthly expenses and withdrawal rate. Annual expenses are derived by multiplying monthly expenses by 12. """ annual_expenses = monthly_expenses * 12 fire_number = annual_expenses / (withdrawal_rate / 100) return fire_number def fire_number_calculator(): st.header("FIRE Number Calculator") st.write("Calculate the amount you need to achieve Financial Independence and Retire Early (FIRE) based on your monthly expenses.") monthly_expenses = st.number_input("Enter your monthly expenses:", min_value=0.0, value=5000.0, format="%.2f") withdrawal_rate = st.number_input("Enter your desired withdrawal rate (%):", min_value=1.0, max_value=10.0, value=4.0, format="%.2f") if st.button('Calculate FIRE Number'): fire_number = calculate_fire_number(monthly_expenses, withdrawal_rate) st.success(f"Your FIRE Number is: ₹ {fire_number:.2f}") def project_fd_value(principal, annual_rate, years): return np.array([principal * ((1 + annual_rate) ** year) for year in range(1, years + 1)]) def plot_projections_with_fd(years, best_case_values, worst_case_values, fd_values): plt.figure(figsize=(10, 6)) plt.plot(range(1, years + 1), best_case_values, label='Best Case', color='#1f77b4') # Blue plt.plot(range(1, years + 1), worst_case_values, label='Worst Case', color='#ff7f0e') # Orange plt.plot(range(1, years + 1), fd_values, label='FD Return', color='#2ca02c') # Green plt.xlabel('Years') plt.ylabel('Projected Value (₹)') plt.yscale('log') # Set the y-axis to a logarithmic scale plt.title('Investment Projections Over Time (Log Scale)') plt.legend() st.pyplot(plt) def investment_projections(investment_amount, risk_appetite, years): # Defining return rates for best and worst cases if risk_appetite >= 75: # High Risk best_case_rate = 0.15 # 15% optimistic annual return worst_case_rate = -0.05 # -5% pessimistic annual return elif 25 < risk_appetite < 75: # Medium Risk best_case_rate = 0.10 # 10% optimistic annual return worst_case_rate = 0.00 # 0% pessimistic annual return else: # Low Risk best_case_rate = 0.05 # 5% optimistic annual return worst_case_rate = 0.01 # 1% pessimistic annual return # Projecting future values best_case_value = project_future_value(investment_amount, best_case_rate, years) worst_case_value = project_future_value(investment_amount, worst_case_rate, years) return best_case_value, worst_case_value def plot_projections(years, best_case_values, worst_case_values): plt.figure(figsize=(10, 6)) plt.plot(range(1, years + 1), best_case_values, label='Best Case', color='#1f77b4') # Blue plt.plot(range(1, years + 1), worst_case_values, label='Worst Case', color='#ff7f0e') # Orange plt.xlabel('Years') plt.ylabel('Projected Value (₹)') plt.title('Investment Projections Over Time') plt.legend() st.pyplot(plt) def project_future_value(principal, annual_rate, years): return np.array([principal * ((1 + annual_rate) ** year) for year in range(1, years + 1)]) def investment_advice(income, expenses, age, risk_appetite): # Calculate the disposable income (income - expenses) disposable_income = income - expenses # Emergency Fund Recommendation emergency_fund = expenses * 6 # 6 months of expenses # Retirement Savings Recommendation (simplified example) retirement_savings = disposable_income * 0.15 # 15% of disposable income # Investment Allocation if risk_appetite >= 75: # High Risk stocks = disposable_income * 0.5 # 50% in stocks bonds = disposable_income * 0.2 # 20% in bonds mutual_funds = disposable_income * 0.3 # 30% in mutual funds elif 25 < risk_appetite < 75: # Medium Risk stocks = disposable_income * 0.3 # 30% in stocks bonds = disposable_income * 0.4 # 40% in bonds mutual_funds = disposable_income * 0.3 # 30% in mutual funds else: # Low Risk stocks = disposable_income * 0.1 # 10% in stocks bonds = disposable_income * 0.6 # 60% in bonds mutual_funds = disposable_income * 0.3 # 30% in mutual funds return { "Emergency Fund": emergency_fund, "Retirement Savings": retirement_savings, "Stocks": stocks, "Bonds": bonds, "Mutual Funds": mutual_funds } def investment_advisor(): st.title("Smart Income Investment Advisor") income = st.number_input("Enter your monthly income:", min_value=0.0, format="%.2f") expenses = st.number_input("Enter your monthly expenses:", min_value=0.0, format="%.2f") age = st.number_input("Enter your age:", min_value=18, max_value=100, step=1) risk_appetite = st.slider("Select your risk appetite (0 = Low, 100 = High):", 0, 100, 50) fd_rate = st.number_input("Enter FD Interest Rate:", min_value = 0.1, max_value = 10.0, format="%.2f") years = st.number_input("Investment Time Horizon (Years):", min_value=1, max_value=30, step=1) if st.button("Get Investment Advice"): advice = investment_advice(income, expenses, age, risk_appetite) st.write(advice) total_investment = advice["Stocks"] + advice["Bonds"] + advice["Mutual Funds"] best_case_values, worst_case_values = investment_projections(total_investment, risk_appetite, years) fd_values = project_fd_value(total_investment, fd_rate / 100, years) st.write("Projection for your total investment:") st.write(f"Best-case scenario (in {years} years): ₹ {best_case_values[-1]:.2f}") st.write(f"Worst-case scenario (in {years} years): ₹ {worst_case_values[-1]:.2f}") st.write(f"Fixed Deposit scenario (in {years} years): ₹ {fd_values[-1]:.2f}") # Plot the projections with FD plot_projections_with_fd(years, best_case_values, worst_case_values, fd_values) def calculate_sip_returns(sip_amount, duration_years, rd_fd_rate, mf_rate, index_fund_rate): # Convert annual rates to monthly rates monthly_rd_fd_rate = rd_fd_rate / 12 / 100 monthly_mf_rate = mf_rate / 12 / 100 monthly_index_fund_rate = index_fund_rate / 12 / 100 # Total months total_months = duration_years * 12 # RD/FD Returns Calculation (Compounded Monthly for simplification) rd_fd_total = 0 for month in range(total_months): rd_fd_total *= (1 + monthly_rd_fd_rate) rd_fd_total += sip_amount # Mutual Funds and Index Funds Returns Calculation (Compounded Monthly) mf_total = 0 index_fund_total = 0 for month in range(total_months): mf_total *= (1 + monthly_mf_rate) mf_total += sip_amount index_fund_total *= (1 + monthly_index_fund_rate) index_fund_total += sip_amount return rd_fd_total, mf_total, index_fund_total def sip_return_comparator_tab(): st.header("SIP Return Comparator") st.write("Compare the returns from different investment options based on your SIP.") sip_amount = st.number_input("Enter your monthly SIP amount:", min_value=500.0, value=5000.0, format="%.2f") duration_years = st.number_input("Enter the investment duration (in years):", min_value=1, max_value=30, value=5, step=1) # Optional: Allow users to modify the default interest rates rd_fd_rate = st.number_input("Enter RD/FD Interest Rate (% per annum):", min_value=0.0, value=6.0, format="%.2f") mf_rate = st.number_input("Enter Mutual Funds Return Rate (% per annum):", min_value=0.0, value=12.0, format="%.2f") index_fund_rate = st.number_input("Enter Index Funds Return Rate (% per annum):", min_value=0.0, value=10.0, format="%.2f") if st.button('Calculate SIP Returns'): rd_fd_returns, mf_returns, index_fund_returns = calculate_sip_returns(sip_amount, duration_years, rd_fd_rate, mf_rate, index_fund_rate) st.success(f"RD/FD Returns: ₹ {rd_fd_returns:.2f}\nMutual Funds Returns: ₹ {mf_returns:.2f}\nIndex Funds Returns: ₹ {index_fund_returns:.2f}") # Optional: Plotting the results for a visual comparison labels = ['RD/FD', 'Mutual Funds', 'Index Funds'] returns = [rd_fd_returns, mf_returns, index_fund_returns] colors = [(0.1, 0.2, 0.5, 0.7), (0.2, 0.6, 0.2, 0.7), (1.0, 0.5, 0.0, 0.7)] # RGBA format plt.figure(figsize=(10, 6)) plt.bar(labels, returns, color=colors) plt.title('SIP Returns Comparison') plt.ylabel('Total Returns in ₹') st.pyplot(plt) def calculate_emi(principal, interest_rate, years): monthly_interest_rate = interest_rate / (12 * 100) total_payments = years * 12 emi = principal * monthly_interest_rate * ((1 + monthly_interest_rate) ** total_payments) / ((1 + monthly_interest_rate) ** total_payments - 1) return emi def calculate_loan_eligibility(net_monthly_income, other_emis, interest_rate, tenure_years, income_multiplier=5): # Assuming the bank allows a maximum of 50% of net income towards EMI max_emi_allowed = net_monthly_income * 0.5 - other_emis monthly_interest_rate = interest_rate / (12 * 100) total_payments = tenure_years * 12 max_loan_amount = max_emi_allowed / (monthly_interest_rate * ((1 + monthly_interest_rate) ** total_payments) / ((1 + monthly_interest_rate) ** total_payments - 1)) return max_loan_amount * income_multiplier def estimate_tax_savings(interest_paid_annually, principal_paid_annually, income_tax_slab, co_purchaser): max_deduction_interest = 200000 # Section 24(b) max_deduction_principal = 150000 # Section 80C interest_deduction = min(interest_paid_annually, max_deduction_interest) principal_deduction = min(principal_paid_annually, max_deduction_principal) tax_savings = (interest_deduction + principal_deduction) * income_tax_slab / 100 if co_purchaser == "Yes": tax_savings *= 2 # Double the tax savings if there's a co-purchaser return tax_savings def calculate_profit_timeline(total_loan_amount, emi, tax_savings, initial_investment, rental_income, rental_increase_rate, inflation_rate, property_appreciation_rate, years): monthly_rental_income = rental_income cumulative_rental_income = 0 cumulative_investment = initial_investment property_value = total_loan_amount + initial_investment # Initial total property value profit_timeline = [] for year in range(1, years + 1): annual_rental_income = 0 property_value *= (1 + property_appreciation_rate) # Update property value for the year for month in range(1, 13): adjusted_rental_income = monthly_rental_income / ((1 + inflation_rate) ** (year - 1)) annual_rental_income += adjusted_rental_income cumulative_rental_income += adjusted_rental_income cumulative_investment += emi - tax_savings / 12 # Update rental income for the next year monthly_rental_income *= (1 + rental_increase_rate) # Record data for the timeline profit_timeline.append((year, cumulative_rental_income, cumulative_investment, property_value)) return pd.DataFrame(profit_timeline, columns=["Year", "Cumulative Rental Income", "Cumulative Investment", "Estimated Property Value"]) def loan_eligibility_calculator(): st.header("Loan Eligibility Calculator") st.write("Calculate your loan eligibility based on your monthly income and other factors.") net_monthly_income = st.number_input("Enter your net monthly income:", min_value=0.0, value=50000.0, format="%.2f") other_emis = st.number_input("Enter total EMI of other existing loans (if any):", min_value=0.0, value=0.0, format="%.2f") interest_rate = st.number_input("Expected loan interest rate (%):", min_value=0.0, value=8.0, format="%.2f") tenure_years = st.number_input("Expected loan tenure (years):", min_value=1, max_value=30, value=20, step=1) if st.button('Calculate Loan Eligibility'): loan_eligibility = calculate_loan_eligibility(net_monthly_income, other_emis, interest_rate, tenure_years) st.success(f"Based on the provided details, your estimated loan eligibility is: ₹ {loan_eligibility:.2f}") def emi_rental_profit_calculator(): # User Inputs cost_of_property = st.number_input("Enter the cost of the property:", min_value=100000.0, value=5000000.0, format="%.2f") renovation_cost = st.number_input("Enter the renovation cost:", min_value=0.0, value=500000.0, format="%.2f") down_payment = st.number_input("Enter the down payment:", min_value=0.0, value=1000000.0, format="%.2f") loan_amount = cost_of_property + renovation_cost - down_payment st.text(f"Total Loan Amount: {loan_amount}") interest_rate = st.number_input("Enter the home loan interest rate (%):", min_value=0.0, value=8.0, format="%.2f") years = st.number_input("Enter the number of years for the loan:", min_value=1, max_value=30, value=20, step=1) co_purchaser = st.selectbox("Is there a co-purchaser?", ["No", "Yes"]) income_tax_slab = st.number_input("Enter your income tax slab rate (%):", min_value=0.0, max_value=30.0, value=10.0, format="%.2f") initial_rental_income = st.number_input("Enter initial monthly rental income:", min_value=0.0, value=20000.0, format="%.2f") rental_increase_rate = st.number_input("Enter annual rental increase rate (%):", min_value=0.0, max_value=10.0, value=5.0, format="%.2f") / 100 inflation_rate = st.number_input("Enter annual inflation rate (%):", min_value=0.0, max_value=10.0, value=4.0, format="%.2f") / 100 property_appreciation_rate = st.number_input("Enter annual property value appreciation rate (%):", min_value=0.0, max_value=10.0, value=3.0, format="%.2f") / 100 # Calculation Button if st.button('Calculate'): emi = calculate_emi(loan_amount, interest_rate, years) st.text(f"Monthly EMI: {emi:.2f}") # Assuming the entire EMI is considered for tax savings calculation annual_emi = emi * 12 tax_savings = estimate_tax_savings(annual_emi, annual_emi, income_tax_slab, co_purchaser) st.text(f"Annual Tax Savings: {tax_savings:.2f}") # Calculate profit timeline profit_df = calculate_profit_timeline(loan_amount, emi, tax_savings, down_payment, initial_rental_income, rental_increase_rate, inflation_rate, property_appreciation_rate, years) st.write(profit_df) # Plotting the results plt.figure(figsize=(10, 4)) plt.plot(profit_df['Year'], profit_df['Cumulative Rental Income'], label='Cumulative Rental Income') plt.plot(profit_df['Year'], profit_df['Cumulative Investment'], label='Cumulative Investment') plt.plot(profit_df['Year'], profit_df['Estimated Property Value'], label='Estimated Property Value') plt.xlabel('Year') plt.ylabel('Amount') plt.title('Profit Timeline') plt.legend() st.pyplot(plt) def main(): st.title("Personal Finance Assistance") # Sidebar for navigation st.sidebar.title("Navigation") options = ["Personal Finance Assistance Tools", "Loan Eligibility Calculator", "EMI and Rental Profit Calculator", "SIP Return Comparator", "How to invest my income?", "FIRE Number Calculator", "Compound Interest Calculator", "Loan EMI Calculator"] options.append("Debt Payoff Calculator") options.append("How are my investments changing over time considering inflation ?") options.append("Should I Shift My Loan Calculator") choice = st.sidebar.radio("Choose a Calculator:", options) if choice == "Personal Finance Assistance Tools": st.text("This Space container various tools to clarify few personal finances.") st.text("Choose from left sidebar and proceed.") st.text("Suggestion are welcome, please contact at fineasyinc@gmail.com for collaboration!") elif choice == "Loan Eligibility Calculator": loan_eligibility_calculator() elif choice == "EMI and Rental Profit Calculator": emi_rental_profit_calculator() elif choice == "SIP Return Comparator": sip_return_comparator_tab() elif choice == "How to invest my income?": investment_advisor() elif choice == "FIRE Number Calculator": fire_number_calculator() elif choice == "Compound Interest Calculator": compound_interest_calculator() elif choice == "Loan EMI Calculator": emi_calculator_tab() elif choice == "How are my investments changing over time considering inflation ?": inflation_calculator_tab() elif choice == "Should I Shift My Loan Calculator": loan_shift_decision_tab() if __name__ == "__main__": main()