The Ultimate Guide to Smart Investment Planning and Wealth Withdrawal Using Python

Investing can be one of the most powerful ways to secure your financial future, but it comes with a maze of decisions: how much to invest, where to invest, and how to manage withdrawals when the time comes. Wouldn’t it be great to have a tool that helps you model your financial future, factoring in growth rates, inflation, and taxes? While we can't predict the market, we can use Python to build an investment simulator that brings clarity to your planning.

In this blog, we’ll explore how a simple yet powerful Python script can simulate your investments over time, handle tax implications, and help you understand how long your savings will last. By the end of this post, you'll have the tools to make informed financial decisions and visualize your investment outcomes.

We're exploring a strategic approach to building lasting wealth: invest consistently for a few years with annual increments, let your investments grow, and then strategically sell them when you’re ready to stop working. While selling incurs taxes, this marks the transition to a new phase—retirement—where you live off your withdrawals. At this point, you can reinvest your gains into safer assets, like debt or large-cap funds, which offer reduced but stable earnings. With a target monthly income in mind, the plan is to withdraw an inflation-adjusted amount each month, continually adjusting to ensure your lifestyle is sustained as long as possible, until the funds eventually run out or you die.

Why Investment Planning Is Essential

Before diving into the code, let’s talk about why investment planning is crucial. You may think simply putting your money into a savings account or investing without a strategy is good enough, but this approach can have consequences:

  1. The Power of Compound Growth: Small, consistent investments can snowball into a significant sum over time, thanks to compounding. However, to fully realize this power, you need to invest strategically.

  2. Combating Inflation: Inflation erodes the purchasing power of money, meaning what you can buy today with a given amount will likely cost more in the future. Planning for inflation ensures your investments outpace these rising costs.

  3. Tax Efficiency: Taxes can significantly impact your investment returns. Proper planning minimizes tax liabilities, allowing you to retain more of your hard-earned gains.

  4. Sustainable Withdrawals: For retirees or those planning to live off their investments, knowing how much you can withdraw each year without depleting your funds is critical.

This Python investment simulator addresses all these factors, giving you a comprehensive view of your financial future.

The Core Components of the Python Script

Our investment simulator models your financial journey from the accumulation phase (where you’re building wealth) to the decumulation phase (where you’re withdrawing funds). Here’s an in-depth look at how the script works:

Constants and Setup

The script starts by defining important constants, such as the number of months in a year and the formulas for monthly growth and inflation rates:

months_per_year = 12
max_csv_months = 100 * months_per_year  # Limit CSV output to 100 years
annual_return_rate = annual_return_percent / 100
monthly_growth_rate = (1 + annual_return_rate) ** (1 / months_per_year) - 1
annual_inflation_rate = annual_inflation_percent / 100

These constants ensure our calculations are precise and reflect real-world financial dynamics.

Customizing Your Investment Strategy

One of the most exciting aspects of this Python code is that you can tailor it to match your financial situation and goals. Here are the key parameters you can adjust:

  1. Initial Monthly Investment

     initial_monthly_investment = 130000  # in currency units
    
    • This is the amount you invest every month. Adjust it based on your income and how much you’re willing to allocate for long-term growth.
  2. Yearly Increment Percentage

     yearly_increment_percent = 2  # Annual increase in your monthly investment
    
    • As your income grows, you might increase your monthly investment. This parameter models that growth. For example, if you expect a 5% annual salary raise, you might increase your contributions accordingly.
  3. Annual Return Percentage

     annual_return_percent = 17  # Expected annual return on your investment
    
    • This rate varies depending on your investment strategy. Stocks typically offer higher returns (but with more risk), while bonds are safer but yield less.
  4. Number of Years to Invest

     years = 12  # Duration of the accumulation phase
    
    • Set this to the number of years you plan to invest before making withdrawals. Longer investment horizons generally yield better returns due to compounding.
  5. Annual Inflation Percentage

     annual_inflation_percent = 5  # Expected inflation rate
    
    • Inflation reduces the purchasing power of your money. This parameter helps simulate how much you’ll need to withdraw in the future to maintain your current lifestyle.
  6. Desired Monthly Amount in Hand

     desired_monthly_in_hand = 100000  # Amount needed each month in today's money
    
    • This is the amount you’ll need each month during retirement or the withdrawal phase. The code adjusts this amount for inflation, ensuring your purchasing power remains consistent.
  7. Withdrawal Fund Growth Percentage

     withdrawal_fund_growth_percent = 8  # Annual return during the withdrawal phase
    
    • Even when you start withdrawing funds, your remaining investments will likely continue to grow. This parameter models the expected return during the withdrawal phase.
  8. LTCG and STCG Tax Percentages

     ltcg_tax_percent = 12.5  # Tax on long-term gains
     stcg_tax_percent = 20  # Tax on short-term gains
    
    • Different types of gains are taxed differently. Adjust these values to match your local tax regulations.

The Investment Phase: Building Your Wealth

The code simulates monthly investments over several years, adjusting for annual increments. Each investment is treated as a separate “lot” to simplify tax calculations later.

for year in range(1, years + 1):
    for month in range(months_per_year):
        lot_name = f"{calendar.month_name[current_month]} {current_year}"
        total_invested_amount += monthly_investment
        investment_lots.append([lot_name, monthly_investment, monthly_investment, 0])

        # Compounding growth
        for lot in investment_lots:
            lot[2] *= (1 + monthly_growth_rate)
            lot[3] += 1

Each lot grows at the monthly rate, simulating the compounding effect that makes investing so powerful. The result is a growing investment balance that can fund your future withdrawals.

Handling Taxes: LTCG and STCG

When it’s time to start withdrawing, the script first sells all investments and calculates taxes. Investments held for over 12 months incur LTCG taxes, while those held for less incur STCG taxes.

while investment_lots:
    lot_name, principal_component, current_value, age = investment_lots.popleft()
    profit = current_value - principal_component
    if age >= 12:
        initial_ltcg_tax += profit * ltcg_tax_rate if profit > 0 else 0
    else:
        initial_stcg_tax += profit * stcg_tax_rate if profit > 0 else 0

This step ensures that your net proceeds after taxes are as accurate as possible, helping you understand your actual available funds.

The Withdrawal Phase: Sustaining Your Wealth

The most critical part of any financial plan is ensuring your money lasts. Our code simulates monthly withdrawals adjusted for inflation, ensuring your lifestyle remains consistent.

monthly_withdrawal = gross_monthly_withdrawal
withdrawal_months = 0

# Adjust withdrawals for inflation and grow the remaining fund
while withdrawal_months < max_csv_months:
    if fund_balance < monthly_withdrawal:
        # If funds are insufficient, sell everything and calculate taxes
        ...
    else:
        # Withdraw the target amount, prioritizing older lots for tax efficiency
        ...
    monthly_withdrawal *= (1 + annual_inflation_rate / 12)

The withdrawal strategy prioritizes selling older lots to minimize taxes and adjusts the withdrawal amount for inflation each month.

A Comprehensive Financial Report

The script generates a detailed summary and a CSV report that captures your financial journey month by month. Here’s what you’ll see in the output:

  • Investment Summary: How much you invested, the annual return, and the total value when you started withdrawing.

  • Tax Summary: A breakdown of LTCG and STCG taxes, both at the start of withdrawals and over time.

  • Duration of Funds: How many years and months your money will last, even with inflation-adjusted withdrawals.

Example Output

You invested 1.30 lacs INR per month for 12 years, which grew at 17% per year.
Your investments increased at 2% per year.
The value of the fund when you stopped investing and started withdrawing
was 5.53 crore INR and 3.08 crore INR adjusted for inflation.
You sold all the funds and incurred 48.92 lacs INR in LTCG and
29.37 thousand INR in STCG, totaling 49.22 lacs INR.
We reinvested the remaining 5.53 crore INR into 100 different lots,
which will grow at 8% per year, and started withdrawing.
You need 1.00 lacs INR per month in today's money.
The starting withdrawal will be 1.80 lacs INR adjusted for
12 years of inflation at 5% per year.
The withdrawals will increase every month to adjust for inflation.

The fund lasted for 34 years and 5 months in the withdrawal phase.

Summary of Taxes:
Initial LTCG Tax at the start of withdrawal: 48.92 lacs INR
Initial STCG Tax at the start of withdrawal: 29.37 thousand INR
LTCG Tax during systematic withdrawals: 2.13 crore INR
STCG Tax during systematic withdrawals: 14.58 thousand INR
Total LTCG Tax (bulk sale + withdrawals): 2.62 crore INR
Total STCG Tax (bulk sale + withdrawals): 43.95 thousand INR

Imagine investing consistently from the age of 30 to 42, dedicating just 12 years to building your financial foundation. With the power of compounding and strategic planning, that relatively short investment period can set you up for a life of financial freedom, allowing you to comfortably retire and sustain yourself until the age of 75. By the time you reach 42, your carefully managed investments could have grown into a massive fund that not only supports your desired lifestyle but also adjusts for inflation, ensuring your wealth retains its purchasing power over the decades.

This means you can enjoy the fruits of your labor, experience peace of mind, and make the most of your golden years without financial stress—all because you committed to investing smartly for just 12 impactful years. The path to early retirement and a worry-free future may be simpler and more attainable than you think!

The CSV File: A Comprehensive Record of Your Financial Journey

One of the most valuable outputs of this Python script is a detailed CSV report. The file contains all the data you need to analyze your investment and withdrawal plan in depth, making it perfect for tracking, planning, or even sharing with your financial advisor.

What’s Inside the CSV File?

The CSV file includes the following columns:

  1. Month: The total number of months since you started investing. This helps you keep track of the timeline and correlate it with your life plans.

  2. Fund Balance: The total value of your investments at the end of each month. It includes the compounded growth from your monthly contributions during the investment phase and the reduced balance during the withdrawal phase.

  3. Investment That Month: The amount you invested in that particular month. During the investment phase, this value is your monthly contribution. Once the investment phase ends, this becomes zero.

  4. Inflation-Adjusted Value: The real value of your fund balance after adjusting for inflation. This column helps you understand the purchasing power of your investments over time, which is crucial for long-term planning.

  5. Gross Withdrawal: The amount you withdrew before accounting for taxes. During the investment phase, this is zero. In the withdrawal phase, it starts with the inflation-adjusted amount you need and increases each month to keep up with inflation.

  6. Taxes to Pay: The taxes incurred on the withdrawn amount. This includes both LTCG and STCG taxes, and it is calculated based on the age of the lots you’re withdrawing from.

  7. Net Withdrawal: The amount you receive after taxes are deducted. This is the money you have in hand to spend, making it an essential metric for planning your lifestyle.

  8. Total Invested Amount: A running total of all the money you have invested over time. This helps you track how much of your wealth is the result of your contributions versus the returns on your investments.

  9. Lots Sold: Detailed information about the investment lots you sold in that month. Each lot includes:

    • Lot Name: The month and year when the lot was created.

    • Value Sold: How much of the lot was sold.

    • Left: The remaining value of the lot after the sale.

    • Profit: The profit made from the sale.

    • Tax: The tax paid on that profit, either as LTCG or STCG, depending on how long the lot was held.

How to Use the CSV File

The CSV report provides a granular look at your financial journey and can be incredibly helpful in various ways:

  1. Analyze Investment Growth: By reviewing the “Fund Balance” and “Inflation-Adjusted Value” columns, you can see how your investments grow over time and understand the real purchasing power of your wealth.

  2. Track Contributions: The “Investment That Month” and “Total Invested Amount” columns help you keep an eye on your total contributions, making it easy to compare them with the returns you’ve earned.

  3. Plan Withdrawals: The “Gross Withdrawal” and “Net Withdrawal” columns show how much money you’ll have in hand each month, helping you budget for future expenses.

  4. Understand Tax Implications: Taxes can have a significant impact on your withdrawals. The “Taxes to Pay” and “Lots Sold” columns give you a clear picture of how taxes affect your income, allowing you to plan for tax-efficient withdrawals.

  5. Evaluate Financial Milestones: You can pinpoint specific months where major changes occur, such as the start of withdrawals or significant tax events. This is useful for aligning your financial plan with life milestones like retirement, buying a house, or funding education.

Experimenting with Different Scenarios

The flexibility of this simulator allows you to model various financial situations:

  1. Early Retirement: Adjust the number of years to invest to see how long your funds will last if you retire early.

  2. Higher or Lower Inflation: Experiment with different inflation rates to understand how rising costs affect your future withdrawals.

  3. Aggressive vs. Conservative Returns: Simulate both high-risk, high-reward strategies and safer, lower-return investments to see how each impacts your wealth.

Take Control of Your Financial Future

Investing and planning for the future can be daunting, but with tools like this Python simulator, you can make data-driven decisions. By tweaking the parameters, you can explore various scenarios and understand the long-term impact of your investment choices.

So, why wait? Run the simulation, explore different strategies, and set yourself on the path to financial security. Remember, the best time to start investing was yesterday; the second-best time is today. Happy investing, and may your financial future be as bright as you’ve always dreamed!

Full Code

import csv
from collections import deque
import calendar

def calculate_investment_with_withdrawal(
        initial_lumpsum_investment,
        initial_monthly_investment, yearly_increment_percent, annual_return_percent,
        years, annual_inflation_percent, desired_monthly_in_hand, withdrawal_fund_growth_percent,
        ltcg_tax_percent, stcg_tax_percent,
        sell_and_reinvest_at_withdrawal_start  # New boolean parameter
        ):

    # Constants
    months_per_year = 12
    max_csv_months = 100 * months_per_year  # Limit CSV output
    annual_return_rate = annual_return_percent / 100
    # Monthly growth rate during the investment phase
    investment_phase_monthly_growth_rate = (1 + annual_return_rate) ** (1 / months_per_year) - 1
    annual_inflation_rate = annual_inflation_percent / 100
    ltcg_tax_rate = ltcg_tax_percent / 100
    stcg_tax_rate = stcg_tax_percent / 100

    # Queue to track each investment as a separate lot
    investment_lots = deque()  # Stores (lot_name, principal_component, current_value, age_in_months)

    # Prepare to collect data for CSV
    csv_data = [["Month", "Fund Balance", "Investment That Month", "Inflation-Adjusted Value",
                 "Gross Withdrawal", "Taxes to Pay", "Net Withdrawal", "Total Invested Amount", "Lots Sold"]]

    # Investment phase
    monthly_investment = initial_monthly_investment
    total_months_investment_phase = 0
    total_invested_amount = 0

    current_year = 2024  # Starting year for lot naming
    current_month = 11   # Starting month: November

    # Add initial lumpsum investment if it exists
    if initial_lumpsum_investment > 0:
        lumpsum_lot_name = f"Initial Lumpsum ({calendar.month_name[current_month]} {current_year})"
        investment_lots.append([lumpsum_lot_name, initial_lumpsum_investment, initial_lumpsum_investment, 0])
        total_invested_amount += initial_lumpsum_investment

    for year_num in range(1, years + 1):
        for month_num in range(months_per_year):
            total_months_investment_phase += 1

            sip_lot_name = f"SIP {calendar.month_name[current_month]} {current_year}"
            total_invested_amount += monthly_investment
            investment_lots.append([sip_lot_name, monthly_investment, monthly_investment, 0]) # New lot starts with age 0

            # Apply monthly growth and age all lots
            for lot in investment_lots:
                lot[2] *= (1 + investment_phase_monthly_growth_rate)
                lot[3] += 1

            fund_balance_inv_phase = sum(lot[2] for lot in investment_lots)
            inflation_adj_balance_inv_phase = fund_balance_inv_phase / ((1 + annual_inflation_rate) ** (total_months_investment_phase / months_per_year))

            csv_data.append([total_months_investment_phase, f"{fund_balance_inv_phase:.2f}", f"{monthly_investment:.2f}",
                             f"{inflation_adj_balance_inv_phase:.2f}", "0.00", "0.00", "0.00",
                             f"{total_invested_amount:.2f}", ""])

            current_month += 1
            if current_month > 12:
                current_month = 1
                current_year += 1
        # Increase monthly SIP investment for the next year
        monthly_investment *= (1 + yearly_increment_percent / 100)

    # --- Transition to Withdrawal Phase ---
    fund_value_at_switch_pre_tax = sum(lot[2] for lot in investment_lots) # Fund value before any decision at switch

    initial_ltcg_tax_at_switch = 0
    initial_stcg_tax_at_switch = 0
    post_tax_proceeds_at_switch = fund_value_at_switch_pre_tax # Default if no sale

    if sell_and_reinvest_at_withdrawal_start:
        # All existing lots are sold, taxes paid, and proceeds reinvested.
        # `investment_lots` will be consumed and then repopulated.

        processed_fund_value_at_switch = 0 # To verify sum if needed

        # Create a temporary list to process for tax calculation, as investment_lots will be cleared
        lots_to_sell_at_switch = list(investment_lots)
        investment_lots.clear() # Original lots will be replaced

        for lot_name, principal_component, current_value, age in lots_to_sell_at_switch:
            processed_fund_value_at_switch += current_value # This is the pre-tax value of each lot
            profit = current_value - principal_component
            tax_on_lot = 0

            if profit > 0:
                if age >= 12: # LTCG
                    tax_on_lot = profit * ltcg_tax_rate
                    initial_ltcg_tax_at_switch += tax_on_lot
                else: # STCG
                    tax_on_lot = profit * stcg_tax_rate
                    initial_stcg_tax_at_switch += tax_on_lot

        # fund_value_at_switch_pre_tax was already calculated by sum() before this block
        initial_total_tax_at_switch = initial_ltcg_tax_at_switch + initial_stcg_tax_at_switch
        post_tax_proceeds_at_switch = fund_value_at_switch_pre_tax - initial_total_tax_at_switch

        if post_tax_proceeds_at_switch > 0:
            new_lot_value = post_tax_proceeds_at_switch / 100
            for i in range(100):
                 investment_lots.append([f"ReinvestLot-{i + 1}", new_lot_value, new_lot_value, 0])
        # If post_tax_proceeds is zero or negative, investment_lots remains empty.

        withdrawal_phase_monthly_growth_rate = (1 + (withdrawal_fund_growth_percent / 100)) ** (1 / months_per_year) - 1
        growth_rate_info_for_print = f"{withdrawal_fund_growth_percent}% (on newly reinvested fund)"
        switch_action_description = (
            f"At the end of {years} years, the total value of your fund before tax was {format_in_lacs_and_crores(fund_value_at_switch_pre_tax)}.\n"
            f"All holdings were sold. An initial LTCG tax of {format_in_lacs_and_crores(initial_ltcg_tax_at_switch)} and STCG tax of {format_in_lacs_and_crores(initial_stcg_tax_at_switch)} were incurred.\n"
            f"Total tax paid at this point: {format_in_lacs_and_crores(initial_total_tax_at_switch)}.\n"
            f"The remaining amount of {format_in_lacs_and_crores(post_tax_proceeds_at_switch)} was reinvested into 100 fresh lots."
        )
    else:
        # Original lots are carried over. No bulk sale, no initial tax at switch.
        # initial_ltcg_tax_at_switch, initial_stcg_tax_at_switch remain 0.
        # post_tax_proceeds_at_switch equals fund_value_at_switch_pre_tax.
        # `investment_lots` still contains the original lots from the investment phase.
        withdrawal_phase_monthly_growth_rate = investment_phase_monthly_growth_rate # Continue with original investment growth rate
        growth_rate_info_for_print = f"{annual_return_percent}% (original investment rate continuing)"
        initial_total_tax_at_switch = 0 # Explicitly zero
        switch_action_description = (
            f"At the end of {years} years, the total value of your fund was {format_in_lacs_and_crores(fund_value_at_switch_pre_tax)}.\n"
            f"No holdings were sold at this point. The existing investments are carried forward into the withdrawal phase.\n"
            f"No initial bulk tax was paid at the start of withdrawal."
        )

    # Inflation adjustment for reporting
    inflation_adjusted_fund_value_at_switch = fund_value_at_switch_pre_tax / ((1 + annual_inflation_rate) ** years)
    # Desired withdrawal amount, inflation-adjusted to the start of withdrawal
    adjusted_desired_monthly_in_hand = desired_monthly_in_hand * ((1 + annual_inflation_rate) ** years)

    # Initial gross monthly withdrawal estimate (assuming LTCG for simplicity, actual tax is per lot sold)
    gross_monthly_withdrawal_estimate = adjusted_desired_monthly_in_hand
    if (1 - ltcg_tax_rate) > 0 : # Avoid division by zero if tax rate is 100%
        gross_monthly_withdrawal_estimate = adjusted_desired_monthly_in_hand / (1 - ltcg_tax_rate)
    elif desired_monthly_in_hand == 0: # If no withdrawal desired, gross is zero
        gross_monthly_withdrawal_estimate = 0
    else: # If tax rate is 100% and desired is non-zero, effectively infinite gross needed
        gross_monthly_withdrawal_estimate = float('inf')

    # --- Withdrawal Phase Logic ---
    monthly_withdrawal_target_gross = gross_monthly_withdrawal_estimate # This target will inflate monthly
    withdrawal_months_elapsed = 0
    current_fund_balance_withdrawal = sum(lot[2] for lot in investment_lots) # Initial balance for withdrawal phase

    total_ltcg_tax_during_withdrawal_phase = 0
    total_stcg_tax_during_withdrawal_phase = 0

    while withdrawal_months_elapsed < max_csv_months and current_fund_balance_withdrawal > 0:
        # 1. Grow all lots and age them
        for lot in investment_lots:
            lot[2] *= (1 + withdrawal_phase_monthly_growth_rate)
            lot[3] += 1

        current_fund_balance_withdrawal = sum(lot[2] for lot in investment_lots) # Update balance after growth
        if current_fund_balance_withdrawal == 0: break # No money left

        # 2. Determine amount to sell for this month's withdrawal
        amount_to_sell_gross_this_month = min(monthly_withdrawal_target_gross, current_fund_balance_withdrawal)

        monthly_tax_paid_this_withdrawal = 0
        lots_sold_details_this_withdrawal = []
        withdrawn_this_month_gross = 0

        # Temporary queue for processing lots for this month's sale (FIFO)
        processing_lots_for_sale = investment_lots 
        investment_lots = deque() # Will be rebuilt with remaining parts and unsold lots

        while amount_to_sell_gross_this_month > 0 and processing_lots_for_sale:
            lot_name, principal_component, current_value, age = processing_lots_for_sale.popleft() # Sell from oldest

            applicable_tax_rate_this_sale = stcg_tax_rate
            tax_label_this_sale = "STCG"
            if age >= 12:
                applicable_tax_rate_this_sale = ltcg_tax_rate
                tax_label_this_sale = "LTCG"

            if current_value <= amount_to_sell_gross_this_month: # Sell entire lot
                profit_on_sale = current_value - principal_component
                tax_on_sale = profit_on_sale * applicable_tax_rate_this_sale if profit_on_sale > 0 else 0
                monthly_tax_paid_this_withdrawal += tax_on_sale

                if tax_label_this_sale == "LTCG": total_ltcg_tax_during_withdrawal_phase += tax_on_sale
                else: total_stcg_tax_during_withdrawal_phase += tax_on_sale

                lots_sold_details_this_withdrawal.append(
                    f"{lot_name} (Age:{age}m): Val={current_value:.2f}, Sold={current_value:.2f}, Left=0.00, "
                    f"Profit={profit_on_sale:.2f}, Tax={tax_label_this_sale}:{tax_on_sale:.2f}"
                )
                amount_to_sell_gross_this_month -= current_value
                withdrawn_this_month_gross += current_value
            else: # Partially sell this lot
                sold_value = amount_to_sell_gross_this_month
                proportion_to_sell = sold_value / current_value
                principal_of_sold_portion = principal_component * proportion_to_sell
                profit_on_sale = sold_value - principal_of_sold_portion

                tax_on_sale = profit_on_sale * applicable_tax_rate_this_sale if profit_on_sale > 0 else 0
                monthly_tax_paid_this_withdrawal += tax_on_sale

                if tax_label_this_sale == "LTCG": total_ltcg_tax_during_withdrawal_phase += tax_on_sale
                else: total_stcg_tax_during_withdrawal_phase += tax_on_sale

                remaining_value = current_value - sold_value
                remaining_principal = principal_component * (1 - proportion_to_sell)

                lots_sold_details_this_withdrawal.append(
                    f"{lot_name} (Age:{age}m): Val={current_value:.2f}, Sold={sold_value:.2f}, Left={remaining_value:.2f}, "
                    f"Profit={profit_on_sale:.2f}, Tax={tax_label_this_sale}:{tax_on_sale:.2f}"
                )
                withdrawn_this_month_gross += sold_value
                # Add the partially remaining lot back to the front of processing_lots_for_sale
                # so it's considered first if more money is needed this month.
                processing_lots_for_sale.appendleft([lot_name, remaining_principal, remaining_value, age])
                amount_to_sell_gross_this_month = 0 # Target met

        # Add any remaining lots (unsold or final partial remainder) from processing_lots_for_sale back to investment_lots
        investment_lots.extend(processing_lots_for_sale)

        net_withdrawal_this_month = withdrawn_this_month_gross - monthly_tax_paid_this_withdrawal
        current_fund_balance_withdrawal = sum(lot[2] for lot in investment_lots) # Update balance after sales

        # Inflation-adjusted fund balance (remaining)
        total_months_from_very_start = total_months_investment_phase + withdrawal_months_elapsed + 1
        inflation_adj_remaining_fund_bal = current_fund_balance_withdrawal / ((1 + annual_inflation_rate) ** (total_months_from_very_start / months_per_year))

        csv_data.append([total_months_investment_phase + withdrawal_months_elapsed + 1, 
                         f"{current_fund_balance_withdrawal:.2f}", "0.00",
                         f"{inflation_adj_remaining_fund_bal:.2f}", f"{withdrawn_this_month_gross:.2f}",
                         f"{monthly_tax_paid_this_withdrawal:.2f}", f"{net_withdrawal_this_month:.2f}",
                         f"{total_invested_amount:.2f}", "; ".join(lots_sold_details_this_withdrawal)])

        withdrawal_months_elapsed += 1
        # Inflate the gross withdrawal target for the next month
        monthly_withdrawal_target_gross *= (1 + annual_inflation_rate / 12)

        if not investment_lots and current_fund_balance_withdrawal <=0 : # Fund depleted
            break

    # Calculate total years and months of withdrawals
    withdrawal_total_years = withdrawal_months_elapsed // 12
    withdrawal_total_remaining_months = withdrawal_months_elapsed % 12

    # Write data to CSV
    with open("investment_withdrawal_report.csv", "w", newline="") as csvfile:
        writer = csv.writer(csvfile)
        writer.writerows(csv_data)

    # --- Print Summary ---
    print(f"\nInvestment Phase:")
    print(f"You started with an initial lumpsum investment of {format_in_lacs_and_crores(initial_lumpsum_investment)}.")
    print(f"You then invested an initial {format_in_lacs_and_crores(initial_monthly_investment)} per month for {years} years.")
    print(f"Your monthly investments increased at {yearly_increment_percent}% per year.")
    print(f"The investments grew at an average of {annual_return_percent}% per year during this phase.")
    print(f"Total amount invested (Lumpsum + SIPs): {format_in_lacs_and_crores(total_invested_amount)}.")

    print(f"\nTransition to Withdrawal Phase:")
    print(switch_action_description) # This contains the conditional explanation

    print(f"\nWithdrawal Phase:")
    print(f"During the withdrawal phase, the fund is projected to grow at {growth_rate_info_for_print}.") # Conditional growth rate info
    print(f"Your desired monthly income in today's money is {format_in_lacs_and_crores(desired_monthly_in_hand)}.")
    print(f"Adjusted for {years} years of inflation at {annual_inflation_percent}%, your first month's target net withdrawal was {format_in_lacs_and_crores(adjusted_desired_monthly_in_hand)}.")
    print(f"To achieve this, the initial gross withdrawal target was estimated at {format_in_lacs_and_crores(gross_monthly_withdrawal_estimate)}.")
    print(f"Withdrawals increase monthly to keep pace with {annual_inflation_percent}% annual inflation.")

    if current_fund_balance_withdrawal <=0 and withdrawal_months_elapsed < max_csv_months :
         print(f"\nThe fund lasted for {withdrawal_total_years} years and {withdrawal_total_remaining_months} months in the withdrawal phase.")
    elif withdrawal_months_elapsed >= max_csv_months:
         print(f"\nThe fund is projected to last for at least {withdrawal_total_years} years and {withdrawal_total_remaining_months} months (simulation limit reached).")
         print(f"Remaining balance at simulation end: {format_in_lacs_and_crores(current_fund_balance_withdrawal)}")

    print(f"\nSummary of Taxes Paid:")
    print(f"  Initial LTCG Tax (at switch): {format_in_lacs_and_crores(initial_ltcg_tax_at_switch)}")
    print(f"  Initial STCG Tax (at switch): {format_in_lacs_and_crores(initial_stcg_tax_at_switch)}")
    print(f"  LTCG Tax (during withdrawals): {format_in_lacs_and_crores(total_ltcg_tax_during_withdrawal_phase)}")
    print(f"  STCG Tax (during withdrawals): {format_in_lacs_and_crores(total_stcg_tax_during_withdrawal_phase)}")
    print(f"  --------------------------------------------------")
    print(f"  Total LTCG Tax (Overall): {format_in_lacs_and_crores(initial_ltcg_tax_at_switch + total_ltcg_tax_during_withdrawal_phase)}")
    print(f"  Total STCG Tax (Overall): {format_in_lacs_and_crores(initial_stcg_tax_at_switch + total_stcg_tax_during_withdrawal_phase)}")
    print(f"  ==================================================")
    total_overall_taxes = initial_ltcg_tax_at_switch + initial_stcg_tax_at_switch + \
                          total_ltcg_tax_during_withdrawal_phase + total_stcg_tax_during_withdrawal_phase
    print(f"  Total Taxes Paid (All Types, All Phases): {format_in_lacs_and_crores(total_overall_taxes)}")

    return (withdrawal_total_years, withdrawal_total_remaining_months, fund_value_at_switch_pre_tax, 
            inflation_adjusted_fund_value_at_switch, adjusted_desired_monthly_in_hand, 
            gross_monthly_withdrawal_estimate, ltcg_tax_rate * 100, stcg_tax_rate * 100)


def format_in_lacs_and_crores(amount):
    if amount is None: return "N/A"
    if amount == float('inf'): return "Effectively Infinite (due to 100% tax)"
    if amount >= 1e7:  # Greater than or equal to 1 crore
        return f"{amount / 1e7:.2f} crore INR"
    elif amount >= 1e5:  # Greater than or equal to 1 lac
        return f"{amount / 1e5:.2f} lacs INR"
    elif amount >= 1e3:  # Greater than or equal to 1 thousand
        return f"{amount / 1e3:.2f} thousand INR"
    else:
        return f"{amount:.2f} INR"


# --- Main execution ---
# Easily adjustable values
initial_lumpsum_investment = 500000
initial_monthly_investment = 50000
yearly_increment_percent = 2
annual_return_percent = 12          # Growth rate during investment phase
years = 10                          # Number of years to invest
annual_inflation_percent = 6
desired_monthly_in_hand = 70000
withdrawal_fund_growth_percent = 8  # Growth rate of NEW fund if sold & reinvested
ltcg_tax_percent = 10               # LTCG tax percentage
stcg_tax_percent = 15               # STCG tax percentage

# New toggle:
# True = Sell all at withdrawal, pay tax, reinvest into new fund growing at withdrawal_fund_growth_percent.
# False = Carry over original investments, no bulk tax at switch, original investments continue growing at annual_return_percent.
sell_and_reinvest_at_withdrawal_start = False

# Perform the calculations
(res_withdrawal_years, res_withdrawal_months, res_fund_val_at_switch,
 res_inf_adj_fund_val_at_switch, res_inf_adj_first_withdrawal,
 res_est_initial_gross_withdrawal, res_ltcg_rate, res_stcg_rate) = \
    calculate_investment_with_withdrawal(
        initial_lumpsum_investment,
        initial_monthly_investment,
        yearly_increment_percent,
        annual_return_percent,
        years,
        annual_inflation_percent,
        desired_monthly_in_hand,
        withdrawal_fund_growth_percent,
        ltcg_tax_percent,
        stcg_tax_percent,
        sell_and_reinvest_at_withdrawal_start # Pass the new flag
    )

# Display the results (summary is now printed within the function)
print("\n_________________________________________________________________________")
print("The detailed monthly report has been saved to 'investment_withdrawal_report.csv'.")
print("The summary of the investment and withdrawal projection is printed above.")
print("_________________________________________________________________________")
0
Subscribe to my newsletter

Read articles from Jyotiprakash Mishra directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Jyotiprakash Mishra
Jyotiprakash Mishra

I am Jyotiprakash, a deeply driven computer systems engineer, software developer, teacher, and philosopher. With a decade of professional experience, I have contributed to various cutting-edge software products in network security, mobile apps, and healthcare software at renowned companies like Oracle, Yahoo, and Epic. My academic journey has taken me to prestigious institutions such as the University of Wisconsin-Madison and BITS Pilani in India, where I consistently ranked among the top of my class. At my core, I am a computer enthusiast with a profound interest in understanding the intricacies of computer programming. My skills are not limited to application programming in Java; I have also delved deeply into computer hardware, learning about various architectures, low-level assembly programming, Linux kernel implementation, and writing device drivers. The contributions of Linus Torvalds, Ken Thompson, and Dennis Ritchie—who revolutionized the computer industry—inspire me. I believe that real contributions to computer science are made by mastering all levels of abstraction and understanding systems inside out. In addition to my professional pursuits, I am passionate about teaching and sharing knowledge. I have spent two years as a teaching assistant at UW Madison, where I taught complex concepts in operating systems, computer graphics, and data structures to both graduate and undergraduate students. Currently, I am an assistant professor at KIIT, Bhubaneswar, where I continue to teach computer science to undergraduate and graduate students. I am also working on writing a few free books on systems programming, as I believe in freely sharing knowledge to empower others.