Time Weighted Rate of Return Calculator Excel

Time Weighted Rate of Return Calculator (Excel Compatible)
#twrr-calculator-container .calc-box { background: #f8f9fa; border: 1px solid #e9ecef; border-radius: 8px; padding: 25px; margin-bottom: 30px; box-shadow: 0 4px 6px rgba(0,0,0,0.05); } #twrr-calculator-container h2 { margin-top: 0; color: #2c3e50; border-bottom: 2px solid #3498db; padding-bottom: 10px; margin-bottom: 20px; } #twrr-calculator-container .input-group { margin-bottom: 15px; } #twrr-calculator-container .period-group { background: #ffffff; border: 1px solid #ddd; padding: 15px; margin-bottom: 15px; border-radius: 6px; } #twrr-calculator-container label { display: block; font-weight: 600; margin-bottom: 5px; color: #555; font-size: 0.9em; } #twrr-calculator-container input[type="number"] { width: 100%; padding: 10px; border: 1px solid #ccc; border-radius: 4px; font-size: 16px; box-sizing: border-box; /* Fix padding issues */ } #twrr-calculator-container .btn-calc { background-color: #27ae60; color: white; border: none; padding: 15px 30px; font-size: 18px; font-weight: bold; border-radius: 4px; cursor: pointer; width: 100%; transition: background 0.2s; } #twrr-calculator-container .btn-calc:hover { background-color: #219150; } #twrr-calculator-container .result-box { background: #e8f6f3; border: 1px solid #c3e6cb; color: #155724; padding: 20px; border-radius: 6px; margin-top: 20px; text-align: center; display: none; } #twrr-calculator-container .result-value { font-size: 2.5em; font-weight: bold; display: block; margin: 10px 0; color: #27ae60; } #twrr-calculator-container .result-breakdown { text-align: left; margin-top: 15px; font-size: 0.9em; border-top: 1px solid #c3e6cb; padding-top: 10px; } #twrr-calculator-container .period-title { font-weight: bold; color: #3498db; margin-bottom: 10px; display: block; text-transform: uppercase; font-size: 0.8em; letter-spacing: 1px; } #twrr-calculator-container .help-text { font-size: 0.8em; color: #777; margin-top: 2px; } @media (min-width: 600px) { #twrr-calculator-container .flex-row { display: flex; gap: 15px; } #twrr-calculator-container .flex-col { flex: 1; } }

TWRR Calculator

The value of the investment at the very beginning.
Period 1 (First Cash Flow Event)
Period 2 (Second Cash Flow Event)
The final value of the investment at the end of the analysis.
Total Time-Weighted Return 0.00%

What is Time-Weighted Rate of Return (TWRR)?

The Time-Weighted Rate of Return (TWRR) is the standard method used in the investment industry to measure the performance of a portfolio. Unlike simple percentage growth calculations, TWRR eliminates the distorting effects of external cash flows (deposits and withdrawals).

When you deposit money into an account, the total value goes up, but that doesn't mean your investment performance improved. TWRR separates the growth into distinct sub-periods based on when cash flows occur, calculates the return for each sub-period, and links them together geometrically.

Why use this over standard Excel IRR?

Excel's XIRR or IRR functions calculate the "Money-Weighted Rate of Return." This tells you how well you did considering your timing of deposits. However, TWRR tells you how well the investment strategy performed, regardless of when you added or removed money. This makes TWRR the preferred metric for comparing fund managers or investment strategies.

The TWRR Excel Formula Logic

To replicate this calculator in Excel manually, you would follow these steps (which this tool automates):

  1. Define Sub-Periods: Every time a cash flow (deposit/withdrawal) occurs, a new sub-period ends.
  2. Calculate Sub-Period Returns ($r_n$):
    r = (Ending Value - Beginning Value) / Beginning Value
    Note: The "Ending Value" is the market value just BEFORE the cash flow occurs.
  3. Establish New Basis: The beginning value for the next period is the previous ending value PLUS the cash flow.
  4. Chain Link (Geometric Mean):
    TWRR = [(1 + r1) * (1 + r2) * ... * (1 + rn)] - 1

Example Calculation

Imagine an investor starts with 1,000.

  • Period 1: The portfolio grows to 1,100. The investor then deposits 500.
    Return: (1,100 – 1,000) / 1,000 = 10%.
    New Basis: 1,100 + 500 = 1,600.
  • Period 2: The portfolio (now starting at 1,600) grows to 1,760 at the end.
    Return: (1,760 – 1,600) / 1,600 = 10%.
  • Total TWRR: (1.10 * 1.10) – 1 = 21%.

Notice that even though the balance grew from 1,000 to 1,760 (a 76% increase in raw dollars), the actual investment performance is 21% because much of the increase came from the 500 deposit.

function calculateTWRR() { // 1. Get Inputs var initialVal = parseFloat(document.getElementById('initialValue').value); var finalVal = parseFloat(document.getElementById('finalValue').value); // Period 1 Data var p1End = parseFloat(document.getElementById('p1_endVal').value); var p1Flow = parseFloat(document.getElementById('p1_cashFlow').value); // Period 2 Data var p2End = parseFloat(document.getElementById('p2_endVal').value); var p2Flow = parseFloat(document.getElementById('p2_cashFlow').value); // Validation if (isNaN(initialVal) || isNaN(finalVal) || initialVal === 0) { alert("Please enter a valid Initial Portfolio Value and Final Value."); return; } var currentBasis = initialVal; var cumulativeMultiplier = 1.0; var breakdownHtml = "Period Breakdown:"; // — PERIOD 1 CALCULATION — // Only process period 1 if inputs are present if (!isNaN(p1End)) { // Calculate return for Period 1 var r1 = (p1End – currentBasis) / currentBasis; cumulativeMultiplier = cumulativeMultiplier * (1 + r1); // Update basis for next period: End Value + Cash Flow var flow1 = isNaN(p1Flow) ? 0 : p1Flow; currentBasis = p1End + flow1; breakdownHtml += "Period 1 Return: " + (r1 * 100).toFixed(2) + "%"; } // — PERIOD 2 CALCULATION — // Only process period 2 if inputs are present AND period 1 was valid if (!isNaN(p2End)) { // If user skipped period 1 input but filled period 2, logic fails. // We assume sequential filling. var r2 = (p2End – currentBasis) / currentBasis; cumulativeMultiplier = cumulativeMultiplier * (1 + r2); var flow2 = isNaN(p2Flow) ? 0 : p2Flow; currentBasis = p2End + flow2; breakdownHtml += "Period 2 Return: " + (r2 * 100).toFixed(2) + "%"; } // — FINAL PERIOD CALCULATION — // Calculate return from last known basis to final value var rFinal = (finalVal – currentBasis) / currentBasis; cumulativeMultiplier = cumulativeMultiplier * (1 + rFinal); breakdownHtml += "Final Period Return: " + (rFinal * 100).toFixed(2) + "%"; // — TOTAL TWRR — var totalTWRR = cumulativeMultiplier – 1; var percentageTWRR = (totalTWRR * 100).toFixed(2); // Display Results document.getElementById('twrrResult').innerHTML = percentageTWRR + "%"; document.getElementById('breakdownOutput').innerHTML = breakdownHtml; document.getElementById('resultOutput').style.display = "block"; }

Leave a Comment