Finding a good estimation of future RRSP withdrawals

Custom functions used in Google Sheets for ease of use and improved functionality.

Calculate a future GROSS income (in Canada)

Purpose

CanadianTaxes Google Sheets Custom Function

RRSP meltdown strategy

My RRSP estimation strategy

Solving initial net income.

function getIncomeForMe() {
    balanceToZero("currentNetIncome", "finalYearRspValue", 500, 50);
}
/**
 * 
 * @param {String} netIncomeCell - Named range of CELL that contains net income
 * @param {String} accountBalanceCell - Named range of CELL that has account balance in year after passing
 * @param {Number} startingDelta - Starting amount to adjust net income if there is a balance
 * @param {Number} maxDiff - Solve until the ending balance is plus/minus this value.
 * @returns {Number}
 */
function balanceToZero(netIncomeCell, accountBalanceCell, startingDelta, maxDiff) {
    const ss = SpreadsheetApp.getActive();
    const sheet = ss.getActiveSheet();
    const accountBalanceRange = sheet.getRange(accountBalanceCell);
    const netIncomeRange = sheet.getRange(netIncomeCell);

    const startSalary = netIncomeRange.getValue();
    const endingBalance = accountBalanceRange.getValue();
    let currentBalance = endingBalance;
    let floorDiff = 0;    //  Last salary DELTA where end balance has not gone from 0 to non zero (viceversa)
    let ceilinigDiff = endingBalance === 0 ? -startingDelta : startingDelta;

    //  Get a ballpark range of change net income - refined in following step.
    while ((endingBalance === 0 && currentBalance === 0) || (endingBalance > 0 && currentBalance !== 0)) {
        netIncomeRange.setValue(startSalary + ceilinigDiff);
        currentBalance = accountBalanceRange.getValue();

        if ((endingBalance === 0 && currentBalance === 0) || (endingBalance > 0 && currentBalance !== 0)) {
            floorDiff = ceilinigDiff;
            ceilinigDiff *= 2;
        }
    }

    //  The ceilingDiff is too much of a change.  It should be between the floor and ceiling.
    let splitDiff = (ceilinigDiff + floorDiff) / 2;
    while (Math.abs(ceilinigDiff - floorDiff) > maxDiff) {
        netIncomeRange.setValue(startSalary + splitDiff);
        currentBalance = accountBalanceRange.getValue();

        if (endingBalance === 0) {
            //  This means the startSalary was too high - since nothing was left.
            if (currentBalance === 0) {
                //  The startSalary PLUS the split difference is still TOO HIGH.  We
                //  must reduce our salary again.
                floorDiff = splitDiff;
            }
            else {
                //  The was reduced too much now.  We have something left in the pot.
                ceilinigDiff = splitDiff;
            }
        }
        else {
            //  This means the startSalary was too low - since the end balance is > 0. 
            if (currentBalance > 0) {
                //  Salary is still TOO LOW.
                floorDiff = splitDiff;
            }
            else {
                ceilinigDiff = splitDiff;
            }
        }

        splitDiff = (ceilinigDiff + floorDiff) / 2;
    }

    return startSalary + splitDiff;
}