Acabo de resolver este problema: conversión de VBA a JS: salida incorrecta (¡gracias a Terry Lennox!)
Pero preferiría hacer el mismo cálculo con Math.log en lugar del método recursivo, sugirió mi cliente.
Tengo el siguiente código:
var amount = parseFloat($('#input_loan_amount').val()); //value: 250000 var initial_fee = parseFloat($('#input_initial_fee').val()); //value: 3499 var monthly_fee = parseFloat($('#input_monthly_fee').val()); //value: 99 var monthly = parseFloat($('#input_monthly_interest').val()); //value: 0.41 var rate = parseFloat($('#input_installment').val()); //value:3499 $('#result_albert').html('Calculating ...'); if (amount > 0) { amount = amount + initial_fee; if (isNaN(monthly) == true) { monthly = 0; } if (isNaN(rate) == true) { rate = 0; } monthly = monthly / 100; var monthly2 = Math.round(monthly * 100) / 100; var months = -(Math.log(1 - (monthly * amount / (rate - monthly_fee)))) / Math.log(1 + monthly); months = -(Math.log(Math.round((1 - (monthly * amount / (rate - monthly_fee))) * 100) / 100) / Math.log(Math.round((1 + monthly) * 100) / 100)); }El número antes del punto es correcto, pero los decimales no son correctos. Creo que mi fórmula meses = no es del todo correcta, pero mis habilidades matemáticas no son lo suficientemente altas...
Podemos usar la fórmula que se explica aquí: https://math.stackexchange.com/questions/3185889/how-do-i-solve-for-n-number-of-periods-in-a-loan-repayment-formula
Para sacarnos el número de meses necesarios o duración, esto es básicamente lo que nos dará la fórmula NPER en Excel.
// Using the formula n = log(A/(A-rP)) // A: monthly payment // P: principal // r: rate function nper(A, P, r) { return Math.log(A/(Ar*P))/Math.log1p(r); } function calculate() { var amount = parseFloat($('#input_loan_amount').val()); //value: 250000 var initial_fee = parseFloat($('#input_initial_fee').val()); //value: 3499 var monthly_fee = parseFloat($('#input_monthly_fee').val()); //value: 99 var monthly = parseFloat($('#input_monthly_interest').val()); //value: 0.41 var rate = parseFloat($('#input_installment').val()); //value:3499 amount=amount+initial_fee; monthly_payment = rate - monthly_fee; monthly=monthly/100; // Using formula from https://math.stackexchange.com/questions/3185889/how-do-i-solve-for-n-number-of-periods-in-a-loan-repayment-formula const durationMonths = nper(monthly_payment, amount, monthly); const roundedDuration = Math.ceil(durationMonths); const runningAdm = roundedDuration * monthly_fee; $('#durationOutput').html(roundedDuration); $('#runningAdm').html(runningAdm); } calculate() <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> <label for="input_loan_amount">Loan amount:</label> <input type="text" id="input_loan_amount" name="input_loan_amount" value="250000"> <br> <label for="input_initial_fee">Initial fee:</label> <input type="text" id="input_initial_fee" name="input_initial_fee" value="3499"> <br> <label for="input_monthly_fee">Monthly fee:</label> <input type="text" id="input_monthly_fee" name="input_monthly_fee" value="99"> <br> <label for="input_monthly_interest">Monthly interest (%):</label> <input type="text" id="input_monthly_interest" name="input_monthly_interest" value="0.41"> <br> <label for="input_installment">Fixed price:</label> <input type="text" id="input_installment" name="input_installment" value="3499"> <br> <br> <bold>Duration (months): </bold><i id="durationOutput"></i><br> <bold>Running Adm.: </bold><i id="runningAdm"></i><br> <br><br> <button type="button" onclick="calculate()">Calculate</button>