Reputation: 11
My data table is:
My input is the left table consisting investment data of multiple account for multiple years. I want to calculate XIRR for each year for each account.
The rights table is the typical output that I want. However, I am not able to figure out how this can be done with the help of Excel Formula. Or by VBA. can anyone help?
Example:
Stackoverflow not allowing image to be uploaded due to not having reputation like 10 or something.
Upvotes: 1
Views: 705
Reputation: 3145
Here's one approach. This approach requires that the data are sorted by account and by year. The strategy is (1) find the correct first row of data for each combination of Acc#+YEAR; (2) extract the data from that row to the end of the table; (3) filter out the data that is not associated with that Acc#+YEAR; and (4) calculate XIRR.
To determine the first row of data for each Account/Year combination, you can make a unique tag by concatenating the two together. I made a helper table that has the first rows:
using this formula (CTRL-SHIFT-ENTER):
=MATCH($F5&"_"&G$4,Account&"_"&Year,0)
where $F5 is a cell with an Acc#, G$4 is a cell with a YEAR##, Account is the column of account names, and Year is the column of years. I used an underscore to delimit account names and years; you can probably skip this if your account names and years do not collide with each other.
Now XIRR can be calculated. Here's the result:
Here's the formula (again CTRL-SHIFT-ENTER):
=XIRR(IF(OFFSET($A$2,G5,0,23-G5+1,1)=$K5,IF(OFFSET($B$2,G5,0,23-G5+1,1)=L$4,OFFSET($D$2,G5,0,23-G5+1,1),0),0),OFFSET($C$2,G5,0,23-G5+1,1))
I've used OFFSET
to extract sub-arrays that start at the "first rows" (calculated above) and end at the bottom of the data table. (Note these sub-arrays still contain data from multiple accounts/years, so we'll filter in a later step.) In OFFSET($A$2,G5,0,23-G5+1,1)
$A$2
is the cell above the account names;G5
rows from the top of the date (G5
is one of the first rows from the helper table);0
columns;23-G5+1
rows (23 should be replaced by the total rows you have); and1
column of data.The other OFFSET
s work the same, except on columns B (YEAR), C (Date) and D (Amount).
The next step is filtering out unwanted data from wrong Acc# or YEAR. This is done using the two nested IF
statements. The basic logic is, replace Amount
with 0
whenever we have the wrong Acc# or YEAR:
=XIRR(IF(Account=TheAcct,IF(YEAR=TheYear,Amount,0),0),Date)
This works because zero-cash flows don't affect the XIRR calculation.
Instead of the filtering step you could also calculate a last row for each Acc+YEAR. Then you would end up with a formula like:
=XIRR(OFFSET(Amount,FirstRow,0,LastRow-FirstRow+1,0),OFFSET(Date,FirstRow,0,LastRow-FirstRow+1,0))
Hope that helps.
Upvotes: 1