Time-Weighted Rate of Return (TWRR) Calculator
What is Time-Weighted Rate of Return (TWRR)?
The Time-Weighted Rate of Return (TWRR) is a performance measure used in investing to assess the performance of an investment portfolio over a specific period, independent of the timing of cash flows (deposits and withdrawals). Unlike money-weighted rate of return, TWRR eliminates the distorting effects of external cash flows, providing a truer picture of the investment manager's skill or the underlying asset's performance.
To calculate TWRR, we break the evaluation period into sub-periods based on when external cash flows occur. For each sub-period, we calculate the rate of return. Then, we geometrically link these sub-period returns to get the overall TWRR for the entire period.
The formula for a single period with no external cash flows is straightforward:
TWRR = (Ending Value - Beginning Value) / Beginning Value
or
TWRR = (Ending Value / Beginning Value) - 1
When external cash flows are present, we first adjust the portfolio value before each cash flow to isolate the return generated by the investment itself. The adjusted value right before an inflow is (Value before inflow - Inflow). The adjusted value right before an outflow is (Value before outflow + Outflow).
This calculator simplifies the process by assuming a single period with total inflows and outflows. The formula used here is a practical approximation for cases where there's one overall net cash flow effect. If there are multiple distinct cash flows, a more granular calculation segmenting each cash flow's impact would be necessary.
The formula implemented in this calculator for a single period with net cash flow is:
Let B = Beginning Portfolio Value
Let E = Ending Portfolio Value
Let CI = Total External Cash Inflows (Deposits)
Let CO = Total External Cash Outflows (Withdrawals)
Net Cash Flow = CI - CO
Adjusted Beginning Value = B + CO - CI
TWRR = ((E - (B + CO - CI)) / (B + CO - CI)) - 1
Or simplified: TWRR = (E - B - CI + CO) / (B - CI + CO)
Example Calculation:
Suppose your portfolio starts with $10,000 (Beginning Value).
Over the year, you deposit a total of $500 and withdraw $200.
At the end of the year, your portfolio is worth $12,000 (Ending Value).
Beginning Value (B) = 10000
Ending Value (E) = 12000
Cash Inflows (CI) = 500
Cash Outflows (CO) = 200
Adjusted Beginning Value = 10000 + 200 – 500 = 9700
TWRR = ((12000 – 9700) / 9700) – 1
TWRR = (2300 / 9700) – 1
TWRR ≈ 0.2371 – 1
TWRR ≈ 0.2371 or 23.71%
function calculateTWRR() {
var beginningValue = parseFloat(document.getElementById("beginningValue").value);
var endingValue = parseFloat(document.getElementById("endingValue").value);
var externalCashFlow = parseFloat(document.getElementById("externalCashFlow").value); // Inflows
var externalCashOutflows = parseFloat(document.getElementById("externalCashOutflows").value); // Outflows
var resultDiv = document.getElementById("result");
resultDiv.innerHTML = ""; // Clear previous results
if (isNaN(beginningValue) || isNaN(endingValue) || isNaN(externalCashFlow) || isNaN(externalCashOutflows)) {
resultDiv.innerHTML = "Please enter valid numbers for all fields.";
return;
}
if (beginningValue <= 0) {
resultDiv.innerHTML = "Beginning portfolio value must be greater than zero.";
return;
}
// For TWRR, we adjust the beginning value to account for the impact of cash flows.
// The portfolio's performance is measured from the adjusted beginning value.
// Adjusted Beginning Value = Beginning Value + Total Withdrawals – Total Deposits
var adjustedBeginningValue = beginningValue + externalCashOutflows – externalCashFlow;
if (adjustedBeginningValue <= 0) {
resultDiv.innerHTML = "Adjusted beginning value is zero or negative. Cannot calculate TWRR.";
return;
}
// TWRR = (Ending Value – Adjusted Beginning Value) / Adjusted Beginning Value
var twrr = (endingValue – adjustedBeginningValue) / adjustedBeginningValue;
resultDiv.innerHTML = "Adjusted Beginning Value: " + formatCurrency(adjustedBeginningValue) + "" +
"Time-Weighted Rate of Return (TWRR):
" + (twrr * 100).toFixed(2) + "%";
}
function formatCurrency(amount) {
return "$" + amount.toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,');
}
.calculator-container {
font-family: sans-serif;
max-width: 800px;
margin: 20px auto;
padding: 20px;
border: 1px solid #ddd;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.calculator-container h2 {
text-align: center;
color: #333;
margin-bottom: 25px;
}
.calculator-inputs {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 15px;
margin-bottom: 25px;
padding: 15px;
background-color: #f9f9f9;
border-radius: 5px;
}
.input-group {
display: flex;
flex-direction: column;
}
.input-group label {
margin-bottom: 8px;
font-weight: bold;
color: #555;
}
.input-group input[type="number"] {
padding: 10px;
border: 1px solid #ccc;
border-radius: 4px;
font-size: 1rem;
box-sizing: border-box; /* Ensures padding and border are included in the element's total width and height */
}
.input-group input[type="number"]:focus {
outline: none;
border-color: #007bff;
box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.25);
}
.calculator-inputs button {
grid-column: 1 / -1; /* Span all columns for the button */
padding: 12px 20px;
background-color: #007bff;
color: white;
border: none;
border-radius: 5px;
font-size: 1.1rem;
cursor: pointer;
transition: background-color 0.2s ease;
}
.calculator-inputs button:hover {
background-color: #0056b3;
}
.calculator-results {
margin-top: 25px;
padding: 15px;
background-color: #eef2f7;
border-radius: 5px;
text-align: center;
}
.calculator-results h3 {
margin-top: 0;
color: #333;
}
#result p {
margin: 8px 0;
font-size: 1.1rem;
}
#result strong {
color: #28a745; /* Green for positive results */
}
.calculator-explanation {
margin-top: 30px;
padding: 15px;
border-top: 1px solid #eee;
color: #666;
font-size: 0.95rem;
line-height: 1.6;
}
.calculator-explanation h3 {
color: #333;
margin-bottom: 15px;
}
.calculator-explanation p {
margin-bottom: 15px;
}
.calculator-explanation code {
background-color: #e9ecef;
padding: 3px 6px;
border-radius: 3px;
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
}