NavyaAI's picture
Create app.py with basic calculators
5584f4a verified
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 [email protected] 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()