Money-weighted Return Calculation

Money-Weighted Return Calculation | Professional Financial Calculator :root { –primary: #004a99; –primary-dark: #003366; –success: #28a745; –bg-color: #f8f9fa; –text-color: #333; –border-color: #ddd; –white: #ffffff; –shadow: 0 4px 6px rgba(0,0,0,0.1); } * { box-sizing: border-box; margin: 0; padding: 0; } body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; line-height: 1.6; color: var(–text-color); background-color: var(–bg-color); } .container { max-width: 960px; margin: 0 auto; padding: 20px; } /* Header */ header { text-align: center; margin-bottom: 40px; padding: 20px 0; border-bottom: 2px solid var(–primary); } h1 { color: var(–primary); font-size: 2.5rem; margin-bottom: 10px; } h2, h3 { color: var(–primary-dark); margin-top: 30px; margin-bottom: 15px; } p { margin-bottom: 15px; } /* Calculator Styles */ .calc-container { background: var(–white); padding: 30px; border-radius: 8px; box-shadow: var(–shadow); margin-bottom: 50px; border: 1px solid var(–border-color); } .input-section { margin-bottom: 30px; } .input-group { margin-bottom: 20px; } .input-group label { display: block; font-weight: 600; margin-bottom: 8px; color: var(–primary-dark); } .input-group input, .input-group select { width: 100%; padding: 12px; border: 1px solid var(–border-color); border-radius: 4px; font-size: 16px; } .input-group input:focus { outline: none; border-color: var(–primary); box-shadow: 0 0 0 3px rgba(0, 74, 153, 0.1); } .helper-text { font-size: 0.85rem; color: #666; margin-top: 5px; } .error-msg { color: #dc3545; font-size: 0.85rem; margin-top: 5px; display: none; } .cash-flow-list { margin-bottom: 20px; border: 1px solid var(–border-color); border-radius: 4px; padding: 15px; background: #fdfdfd; } .cash-flow-row { display: flex; gap: 10px; margin-bottom: 10px; align-items: flex-end; flex-wrap: wrap; } .cash-flow-row > div { flex: 1; min-width: 120px; } .btn { padding: 12px 24px; border: none; border-radius: 4px; cursor: pointer; font-weight: 600; font-size: 16px; transition: background 0.2s; } .btn-primary { background-color: var(–primary); color: white; } .btn-primary:hover { background-color: var(–primary-dark); } .btn-secondary { background-color: #6c757d; color: white; } .btn-secondary:hover { background-color: #5a6268; } .btn-outline { background: transparent; border: 1px solid var(–primary); color: var(–primary); padding: 8px 16px; font-size: 14px; } .btn-remove { background: #dc3545; color: white; padding: 12px; min-width: auto; flex: 0; } .controls { display: flex; gap: 10px; margin-top: 20px; flex-wrap: wrap; } /* Results Section */ .results-section { background: #f1f8ff; padding: 25px; border-radius: 8px; margin-top: 30px; border-left: 5px solid var(–primary); } .main-result { text-align: center; margin-bottom: 25px; } .result-label { font-size: 1.1rem; color: #555; margin-bottom: 5px; } .result-value { font-size: 2.5rem; font-weight: 700; color: var(–primary); } .intermediate-results { display: flex; justify-content: space-between; flex-wrap: wrap; gap: 20px; margin-bottom: 20px; } .int-res-box { flex: 1; min-width: 140px; background: white; padding: 15px; border-radius: 6px; box-shadow: 0 2px 4px rgba(0,0,0,0.05); text-align: center; } .int-res-value { font-size: 1.25rem; font-weight: 600; color: var(–success); } /* Table & Chart */ .data-visuals { margin-top: 30px; } table { width: 100%; border-collapse: collapse; margin-bottom: 20px; background: white; } th, td { padding: 12px; text-align: left; border-bottom: 1px solid var(–border-color); } th { background-color: var(–primary); color: white; } .chart-container { width: 100%; height: 300px; background: white; border: 1px solid var(–border-color); border-radius: 4px; padding: 10px; position: relative; margin-top: 20px; } /* Article Styles */ article { background: white; padding: 40px; border-radius: 8px; box-shadow: var(–shadow); } article ul, article ol { margin-left: 25px; margin-bottom: 20px; } article li { margin-bottom: 10px; } .variable-table { width: 100%; margin: 20px 0; border: 1px solid var(–border-color); } .variable-table th { background: #e9ecef; color: var(–text-color); } .faq-item { margin-bottom: 20px; border-bottom: 1px solid #eee; padding-bottom: 20px; } .faq-question { font-weight: 700; color: var(–primary); margin-bottom: 8px; display: block; } .related-links { background: #f8f9fa; padding: 20px; border-radius: 6px; margin-top: 30px; } .related-links a { color: var(–primary); text-decoration: none; font-weight: 600; } .related-links a:hover { text-decoration: underline; } @media (max-width: 600px) { .cash-flow-row { flex-direction: column; align-items: stretch; background: #f0f0f0; padding: 10px; border-radius: 4px; } .btn-remove { margin-top: 5px; } .intermediate-results { flex-direction: column; } }

Money-Weighted Return Calculator

Accurately measure your investment performance by accounting for the timing and size of cash flows.

1. Initial Investment

Enter as a positive number (treated as outflow).

2. Cash Flows (Deposits & Withdrawals)

3. Ending Valuation

Current value of the portfolio.
Money-Weighted Return (Annualized)
0.00%

Calculated using the XIRR formula.

Net Profit/Loss
$0.00
Total Invested
$0.00
Investment Period
0.0 Years

Cash Flow Schedule

Date Type Amount

Cash Flow Visualization

Blue: Initial/Deposits (Outflows) | Green: Withdrawals/Ending (Inflows)

What is Money-Weighted Return Calculation?

The money-weighted return calculation (MWRR) is a measure of the performance of an investment that accounts for the timing and size of cash flows into and out of the portfolio. Unlike the Time-Weighted Return (TWRR), which isolates the manager's performance from the investor's deposit and withdrawal decisions, the money-weighted return reflects the actual internal rate of return (IRR) experienced by the individual investor.

This metric is particularly useful for investors who actively contribute to or withdraw from their accounts. It answers the question: "What annual interest rate would I need on a bank account to match the final dollar value I have today, given all my deposits and withdrawals?"

Money-Weighted Return Formula and Explanation

Mathematically, the money-weighted return is the discount rate ($r$) that sets the net present value (NPV) of all cash flows equal to zero. This is equivalent to the Internal Rate of Return (IRR) formula extended for irregular time intervals (often called XIRR).

The formula is expressed as:

0 = CF₀ + CF₁/(1+r)^t₁ + CF₂/(1+r)^t₂ + … + CFₙ/(1+r)^tₙ
Variable Meaning Unit
CF₀ Initial Investment (Outflow) Currency ($)
CF₁, CF₂… Subsequent Cash Flows (Deposits/Withdrawals) Currency ($)
CFₙ Final Value (treated as an Inflow) Currency ($)
r Money-Weighted Return Rate Percentage (%)
t Time in years from start date Years

Practical Examples of Money-Weighted Return Calculation

Example 1: The Lucky Timer

Investor A starts with $10,000 on January 1st. The market drops 10%, leaving them with $9,000. On June 1st, they deposit another $100,000. The market then rallies 20%. Because the majority of their money ($100,000) participated in the rally, their money-weighted return calculation will be significantly higher than the time-weighted return, reflecting that their timing added value.

Example 2: The Unlucky Withdrawal

Investor B starts with $50,000. The portfolio grows by 10% to $55,000. They withdraw $30,000 to buy a car. The remaining $25,000 subsequently drops by 50%. Even though the fund manager might report a modest loss for the year, Investor B's personal money-weighted return will be terrible because they withdrew capital before the drop, but the remaining balance took a massive hit relative to its size.

How to Use This Calculator

  1. Enter Initial Investment: Input the date you opened the account and the starting amount.
  2. Add Cash Flows: Click "Add Cash Flow" for every deposit or withdrawal.
    • Select "Deposit" if you added money.
    • Select "Withdrawal" if you took money out.
  3. Enter Ending Value: Input the current date (or end date of the period) and the final portfolio value.
  4. Calculate: Press the button to see your annualized return.

Key Factors That Affect Results

  • Timing of Flows: Deposits made just before a market rally increase MWRR. Deposits made before a crash decrease it.
  • Size of Flows: Large cash flows have a heavier "weight" in the calculation. A 50% gain on $100 is less impactful than a 10% gain on $1,000,000.
  • Market Volatility: High volatility combined with frequent cash flows creates the largest divergence between MWRR and TWRR.
  • Investment Duration: Short-term calculations can be extremely volatile and annualized numbers may look unrealistically high or low.
  • Fees and Taxes: If cash flows are net of fees, the return will be lower. Ensure you consistently use either gross or net figures.
  • Inflation: This calculator provides the nominal return. To find the real return, you must subtract the inflation rate.

Frequently Asked Questions (FAQ)

What is the difference between MWRR and TWRR?

TWRR (Time-Weighted Return) eliminates the effect of cash flows to measure the manager's skill. MWRR (Money-Weighted Return) includes the effect of cash flows to measure the investor's actual experience.

Can MWRR be negative while the market is up?

Yes. If you deposit a large sum of money right before a market dip, your personal return could be negative even if the market was up for the year prior to your deposit.

Why does the calculator show an error?

The calculation requires an iterative solution. If cash flows are erratic or dates are invalid, the mathematical solver may not converge. Ensure dates are chronological and amounts are valid.

Is this the same as XIRR in Excel?

Yes, this calculator uses the same mathematical logic as the XIRR function in Excel or Google Sheets.

How do I handle dividends?

If dividends are reinvested, ignore them (they are part of the ending balance). If they are withdrawn as cash, treat them as a "Withdrawal" cash flow.

What is a good money-weighted return?

A "good" return depends on your risk profile and benchmark. Generally, outpacing inflation (3-4%) plus a risk premium (4-6%) is considered a solid long-term target for equities.

Does this calculate CAGR?

If there are no intermediate cash flows, MWRR equals CAGR (Compound Annual Growth Rate). With cash flows, MWRR is the more accurate metric.

Why is the result annualized?

Standard financial reporting annualizes returns to make them comparable across different time periods. A 10% return over 6 months is roughly 21% annualized.

© 2023 Financial Tools Inc. All rights reserved.

// Initialize default dates window.onload = function() { var today = new Date(); var lastYear = new Date(); lastYear.setFullYear(today.getFullYear() – 1); document.getElementById('endDate').valueAsDate = today; document.getElementById('startDate').valueAsDate = lastYear; // Add one empty cash flow row by default addCashFlowRow(); }; function addCashFlowRow() { var container = document.getElementById('cashFlowContainer'); var div = document.createElement('div'); div.className = 'cash-flow-row'; var html = "; html += '
'; html += '
Deposit (In)Withdrawal (Out)
'; html += '
'; html += ''; div.innerHTML = html; container.appendChild(div); } function removeRow(btn) { var row = btn.parentNode; row.parentNode.removeChild(row); } function resetCalculator() { document.getElementById('startAmount').value = "; document.getElementById('endAmount').value = "; document.getElementById('cashFlowContainer').innerHTML = "; addCashFlowRow(); document.getElementById('resultsSection').style.display = 'none'; document.getElementById('globalError').style.display = 'none'; var today = new Date(); var lastYear = new Date(); lastYear.setFullYear(today.getFullYear() – 1); document.getElementById('endDate').valueAsDate = today; document.getElementById('startDate').valueAsDate = lastYear; } function getDaysDiff(d1, d2) { var t2 = d2.getTime(); var t1 = d1.getTime(); return (t2 – t1) / (24 * 3600 * 1000); } // XIRR Implementation using Newton-Raphson function calculateXIRR(transactions) { var guess = 0.1; // 10% initial guess var x0 = guess; var x1 = 0.0; var err = 1e-5; var maxIter = 100; var i = 0; // Sort transactions by date transactions.sort(function(a, b) { return a.date – b.date; }); var t0 = transactions[0].date; for (i = 0; i < maxIter; i++) { var fValue = 0.0; var fDerivative = 0.0; for (var j = 0; j < transactions.length; j++) { var p = transactions[j].amount; var d = getDaysDiff(t0, transactions[j].date) / 365.0; // Avoid division by zero or negative base issues var base = 1.0 + x0; if (base <= 0) base = 0.000001; fValue += p / Math.pow(base, d); fDerivative += -d * p / Math.pow(base, d + 1); } if (Math.abs(fDerivative) < 1e-10) { break; } x1 = x0 – fValue / fDerivative; if (Math.abs(x1 – x0) = endDate) { errorDiv.innerText = "Start date must be before end date."; errorDiv.style.display = 'block'; return; } // Build Transaction Array // Convention: Outflows (Investments) are negative, Inflows (Withdrawals/Final Value) are positive var transactions = []; // Initial Investment (Outflow) transactions.push({ date: startDate, amount: -1 * Math.abs(startAmt), type: 'Initial' }); // Intermediate Flows var cfRows = document.getElementsByClassName('cash-flow-row'); // Note: The first and last rows in DOM are inputs, intermediate are in container // We specifically target the dynamic container rows var container = document.getElementById('cashFlowContainer'); var dynamicRows = container.getElementsByClassName('cash-flow-row'); var totalDeposits = startAmt; var totalWithdrawals = 0; for (var i = 0; i 0) { var dDate = new Date(dStr); if (dDate endDate) { errorDiv.innerText = "Cash flow dates must be between start and end dates."; errorDiv.style.display = 'block'; return; } if (type === 'deposit') { transactions.push({ date: dDate, amount: -1 * amt, type: 'Deposit' }); totalDeposits += amt; } else { transactions.push({ date: dDate, amount: amt, type: 'Withdrawal' }); totalWithdrawals += amt; } } } // Ending Value (Treated as Inflow) transactions.push({ date: endDate, amount: Math.abs(endAmt), type: 'Ending Value' }); // 2. Calculate XIRR var mwrr = 0; try { mwrr = calculateXIRR(transactions); } catch (e) { errorDiv.innerText = "Calculation failed. Please check your inputs."; errorDiv.style.display = 'block'; return; } if (isNaN(mwrr) || !isFinite(mwrr)) { errorDiv.innerText = "Could not converge to a result. Try adjusting dates or amounts."; errorDiv.style.display = 'block'; return; } // 3. Display Results document.getElementById('resultsSection').style.display = 'block'; // Format Percentage var percentage = (mwrr * 100).toFixed(2) + "%"; document.getElementById('mwrrResult').innerText = percentage; // Net Profit // Profit = (Ending Value + Withdrawals) – (Initial + Deposits) var netProfit = (endAmt + totalWithdrawals) – totalDeposits; var profitClass = netProfit >= 0 ? '#28a745' : '#dc3545'; var profitSign = netProfit >= 0 ? '+' : '-'; document.getElementById('netProfit').innerText = profitSign + "$" + Math.abs(netProfit).toFixed(2); document.getElementById('netProfit').style.color = profitClass; document.getElementById('totalInvested').innerText = "$" + totalDeposits.toFixed(2); var years = getDaysDiff(startDate, endDate) / 365.0; document.getElementById('periodYears').innerText = years.toFixed(1) + " Years"; // 4. Update Table updateTable(transactions); // 5. Update Chart drawChart(transactions, startDate, endDate); } function updateTable(transactions) { var tbody = document.querySelector('#scheduleTable tbody'); tbody.innerHTML = "; // Sort for display var sorted = transactions.slice().sort(function(a,b){ return a.date – b.date; }); for (var i = 0; i < sorted.length; i++) { var t = sorted[i]; var tr = document.createElement('tr'); var dateStr = t.date.toLocaleDateString(); var amountStr = "$" + Math.abs(t.amount).toFixed(2); var typeStr = t.type; // Color coding var color = t.amount < 0 ? '#004a99' : '#28a745'; // Blue for out, Green for in tr.innerHTML = '' + dateStr + '' + typeStr + '' + (t.amount < 0 ? '-' : '+') + amountStr + ''; tbody.appendChild(tr); } } function drawChart(transactions, startDate, endDate) { var container = document.getElementById('chartContainer'); container.innerHTML = "; // Clear // Setup SVG var width = container.clientWidth; var height = container.clientHeight; var padding = 40; var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); svg.setAttribute("width", "100%"); svg.setAttribute("height", "100%"); svg.setAttribute("viewBox", "0 0 " + width + " " + height); // Determine scales var totalDays = getDaysDiff(startDate, endDate); if (totalDays === 0) totalDays = 1; var maxAmt = 0; for(var i=0; i maxAmt) maxAmt = Math.abs(transactions[i].amount); } // Draw Axis Lines var lineX = document.createElementNS("http://www.w3.org/2000/svg", "line"); lineX.setAttribute("x1", padding); lineX.setAttribute("y1", height – padding); lineX.setAttribute("x2", width – padding); lineX.setAttribute("y2", height – padding); lineX.setAttribute("stroke", "#ccc"); svg.appendChild(lineX); // Draw Bars var sorted = transactions.slice().sort(function(a,b){ return a.date – b.date; }); for(var i=0; i<sorted.length; i++) { var t = sorted[i]; var daysFromStart = getDaysDiff(startDate, t.date); var xPos = padding + (daysFromStart / totalDays) * (width – 2 * padding); var barHeight = (Math.abs(t.amount) / maxAmt) * (height – 2 * padding); var yPos = (height – padding) – barHeight; var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); rect.setAttribute("x", xPos – 5); // Center bar rect.setAttribute("y", yPos); rect.setAttribute("width", 10); rect.setAttribute("height", barHeight); // Color: Negative (Investment) = Blue, Positive (Return) = Green rect.setAttribute("fill", t.amount < 0 ? "#004a99" : "#28a745"); // Tooltip title var title = document.createElementNS("http://www.w3.org/2000/svg", "title"); title.textContent = t.type + ": $" + Math.abs(t.amount).toFixed(2) + " on " + t.date.toLocaleDateString(); rect.appendChild(title); svg.appendChild(rect); } // Add Start/End Date Labels var textStart = document.createElementNS("http://www.w3.org/2000/svg", "text"); textStart.setAttribute("x", padding); textStart.setAttribute("y", height – 10); textStart.setAttribute("font-size", "12"); textStart.setAttribute("fill", "#666"); textStart.textContent = startDate.toLocaleDateString(); svg.appendChild(textStart); var textEnd = document.createElementNS("http://www.w3.org/2000/svg", "text"); textEnd.setAttribute("x", width – padding); textEnd.setAttribute("y", height – 10); textEnd.setAttribute("font-size", "12"); textEnd.setAttribute("fill", "#666"); textEnd.setAttribute("text-anchor", "end"); textEnd.textContent = endDate.toLocaleDateString(); svg.appendChild(textEnd); container.appendChild(svg); } function copyResults() { var mwrr = document.getElementById('mwrrResult').innerText; var profit = document.getElementById('netProfit').innerText; var text = "Money-Weighted Return Calculation Results:\n"; text += "Annualized Return: " + mwrr + "\n"; text += "Net Profit: " + profit + "\n"; text += "Generated by Financial Calculator."; var tempInput = document.createElement("textarea"); tempInput.value = text; document.body.appendChild(tempInput); tempInput.select(); document.execCommand("copy"); document.body.removeChild(tempInput); alert("Results copied to clipboard!"); }

Leave a Comment