Click the button for the variable you want to solve:
Calculation Result
Understanding the TI BA II Plus Logic
The Texas Instruments BA II Plus is the industry standard for financial professionals and CFA candidates. Unlike standard calculators, it uses a specific Time Value of Money (TVM) cash flow convention.
Cash Flow Convention (The Sign Rule)
One of the most common errors when using a TI BA II Plus is ignoring the sign of the numbers. To get a valid result, you must treat money leaving your pocket as a negative number and money coming in as a positive number.
PV (Present Value): If you are investing money today, enter it as a negative (e.g., -10,000).
PMT (Payment): Periodic deposits are negative; periodic receipts are positive.
FV (Future Value): The amount you receive at the end is usually positive.
Key Components
Variable
Description
N
Total number of compounding periods (Years × P/Y).
I/Y
Nominal annual interest rate (entered as a percentage, e.g., 5 for 5%).
P/Y
Payments per year (12 for monthly, 1 for annual).
BGN/END
BGN is for payments at the start of the period (rent); END is for the end (loans).
Example: Calculating a Mortgage Payment
Assume a $300,000 loan at 4.5% interest for 30 years with monthly payments.
Set P/Y to 12.
N = 360 (30 years * 12).
I/Y = 4.5.
PV = 300,000.
FV = 0 (loan is paid off).
Solve for PMT. Result: -1,520.06 (Negative because you pay it).
function calculateTI(target) {
var n = parseFloat(document.getElementById('ti_n').value);
var iy = parseFloat(document.getElementById('ti_iy').value);
var pv = parseFloat(document.getElementById('ti_pv').value) || 0;
var pmt = parseFloat(document.getElementById('ti_pmt').value) || 0;
var fv = parseFloat(document.getElementById('ti_fv').value) || 0;
var py = parseFloat(document.getElementById('ti_py').value) || 12;
var mode = parseInt(document.getElementById('ti_mode').value);
var resultDisplay = document.getElementById('ti_result_display');
var resultBox = document.getElementById('ti_result_box');
var message = document.getElementById('ti_message');
resultBox.style.display = 'block';
// Periodic Rate
var i = (iy / 100) / py;
var bgnFactor = (mode === 1) ? (1 + i) : 1;
try {
if (target === 'FV') {
if (isNaN(n) || isNaN(iy)) throw "N and I/Y are required";
var fv_calc;
if (i === 0) {
fv_calc = -(pv + (pmt * n));
} else {
fv_calc = -(pv * Math.pow(1 + i, n) + pmt * bgnFactor * ((Math.pow(1 + i, n) – 1) / i));
}
resultDisplay.innerHTML = "FV = " + fv_calc.toLocaleString(undefined, {minimumFractionDigits: 2, maximumFractionDigits: 2});
message.innerHTML = "The future value of the investment/loan.";
}
else if (target === 'PV') {
if (isNaN(n) || isNaN(iy)) throw "N and I/Y are required";
var pv_calc;
if (i === 0) {
pv_calc = -(fv + (pmt * n));
} else {
pv_calc = -(fv / Math.pow(1 + i, n) + pmt * bgnFactor * ((1 – Math.pow(1 + i, -n)) / i));
}
resultDisplay.innerHTML = "PV = " + pv_calc.toLocaleString(undefined, {minimumFractionDigits: 2, maximumFractionDigits: 2});
message.innerHTML = "The present value or principal amount.";
}
else if (target === 'PMT') {
if (isNaN(n) || isNaN(iy)) throw "N and I/Y are required";
var pmt_calc;
if (i === 0) {
pmt_calc = -(pv + fv) / n;
} else {
pmt_calc = -(pv * Math.pow(1 + i, n) + fv) / (bgnFactor * ((Math.pow(1 + i, n) – 1) / i));
}
resultDisplay.innerHTML = "PMT = " + pmt_calc.toLocaleString(undefined, {minimumFractionDigits: 2, maximumFractionDigits: 2});
message.innerHTML = "The periodic payment amount.";
}
else if (target === 'N') {
if (isNaN(iy)) throw "I/Y is required";
var n_calc;
if (i === 0) {
n_calc = -(pv + fv) / pmt;
} else {
var numerator = (pmt * bgnFactor – fv * i) / (pmt * bgnFactor + pv * i);
if (numerator <= 0) throw "Error: Invalid Cash Flow (Check Signs)";
n_calc = Math.log(numerator) / Math.log(1 + i);
}
resultDisplay.innerHTML = "N = " + n_calc.toFixed(4);
message.innerHTML = "Total number of periods.";
}
else if (target === 'IY') {
if (isNaN(n)) throw "N is required";
var iy_calc = solveForRate(n, pmt, pv, fv, mode, py);
resultDisplay.innerHTML = "I/Y = " + (iy_calc * 100 * py).toFixed(4) + "%";
message.innerHTML = "The annual nominal interest rate.";
}
} catch (e) {
resultDisplay.innerHTML = "Error";
message.innerHTML = e;
}
}
function solveForRate(n, pmt, pv, fv, mode, py) {
var rate = 0.1; // Initial guess
var iteration = 0;
var maxIterations = 100;
var precision = 0.0000001;
for (iteration = 0; iteration < maxIterations; iteration++) {
var bgn = (mode === 1) ? (1 + rate) : 1;
var f = 0;
var df = 0;
if (Math.abs(rate) < 0.00001) {
f = pv + pmt * n + fv;
df = pmt * n; // Approximation
} else {
var powN = Math.pow(1 + rate, n);
var powNMinus1 = Math.pow(1 + rate, n – 1);
f = pv * powN + pmt * bgn * ((powN – 1) / rate) + fv;
// Derivative df/drate
var term1 = pv * n * powNMinus1;
var term2;
if (mode === 1) {
// Simplified derivative for BGN mode
term2 = pmt * (((powN – 1) / rate) + (1 + rate) * (n * powNMinus1 * rate – (powN – 1)) / (rate * rate));
} else {
term2 = pmt * (n * powNMinus1 * rate – (powN – 1)) / (rate * rate);
}
df = term1 + term2;
}
var newRate = rate – f / df;
if (Math.abs(newRate – rate) < precision) return newRate;
rate = newRate;
}
return rate;
}
function resetTI() {
document.getElementById('ti_n').value = '';
document.getElementById('ti_iy').value = '';
document.getElementById('ti_pv').value = '';
document.getElementById('ti_pmt').value = '';
document.getElementById('ti_fv').value = '';
document.getElementById('ti_py').value = '12';
document.getElementById('ti_mode').value = '0';
document.getElementById('ti_result_box').style.display = 'none';
}