Forum Discussion
Rolling XIRR Calculation
Hello there,
I am trying to build a rolling IRR calculation for an investment return report. No mater what I try, I cannot seem to get PBI to return a value for my formula. Can anyone help.
ROLLING IRR = CALCULATE(
XIRR('INVESTMENT RETURNS','INVESTMENT RETURNS'[FREE CASHFLOW FOR PERIOD],'INVESTMENT RETURNS'[DATE])
,FILTER('INVESTMENT RETURNS',EARLIER('INVESTMENT RETURNS'[Index])>='INVESTMENT RETURNS'[Index]))There are six rows in my test table as follows:
| Index | FREE CASHFLOW FOR PERIOD | DATE |
| 42 | - 7,531,293.00 | 30/06/2013 |
| 43 | 859,425.00 | 30/06/2014 |
| 44 | 901,305.00 | 30/06/2015 |
| 45 | 951,189.00 | 30/06/2016 |
| 46 | 7,742,641.00 | 30/06/2017 |
| 47 | 1,498,289.00 | 30/06/2018 |
Any help would be greatly appreciated.
Hi v-ljerr-msft,
Thank you very much for your help!
The formula works great, although I have made a few tweaks to include:
- a terminal value (from the [equity repayment/(investment) on sale] column) to be calculated at the end of each period and calculated in the XIRR calc (i.e. if I sold the investment now, what would my XIRR be), and
- a check to ensure that there is at least one positive cashflow (another requirement of the XIRR formula along with the first periof being negative).
see my code as follows fyi....
ROLLING XIRR = VAR countpos = CALCULATE( COUNT('INVESTMENT RETURNS'[totalcashflow]), FILTER(ALL('INVESTMENT RETURNS'), 'INVESTMENT RETURNS'[totalcashflow]>0 && EARLIER ('INVESTMENT RETURNS'[Index] ) >= 'INVESTMENT RETURNS'[Index] && 'INVESTMENT RETURNS'[Name] = EARLIER ( 'INVESTMENT RETURNS'[Name] ) ) ) VAR minIndex = CALCULATE ( MIN ( 'INVESTMENT RETURNS'[Index] ), FILTER ( ALL ( 'INVESTMENT RETURNS' ), 'INVESTMENT RETURNS'[Name] = EARLIER ( 'INVESTMENT RETURNS'[Name] ) ) ) VAR firstValue = CALCULATE ( MIN ( 'INVESTMENT RETURNS'[FREE CASHFLOW FOR PERIOD (excl. sale)] ), FILTER ( ALL ( 'INVESTMENT RETURNS' ), 'INVESTMENT RETURNS'[Name] = EARLIER ( 'INVESTMENT RETURNS'[Name] ) && 'INVESTMENT RETURNS'[Index] = minIndex ) ) RETURN IF ( 'INVESTMENT RETURNS'[Index] > minIndex && firstValue < 0 && countpos >= 1 , XIRR ( UNION( SUMMARIZE( FILTER(ALL ( 'INVESTMENT RETURNS' ), EARLIER ('INVESTMENT RETURNS'[Index] ) >= 'INVESTMENT RETURNS'[Index] && 'INVESTMENT RETURNS'[Name] = EARLIER ( 'INVESTMENT RETURNS'[Name] )) ,'INVESTMENT RETURNS'[Index], "DATE1",MAX('INVESTMENT RETURNS'[DATE]), "CASHFLOW",MAX('INVESTMENT RETURNS'[FREE CASHFLOW FOR PERIOD (excl. sale)]) ), SUMMARIZE( FILTER(ALL ( 'INVESTMENT RETURNS' ), EARLIER ('INVESTMENT RETURNS'[Index] ) = 'INVESTMENT RETURNS'[Index] ), 'INVESTMENT RETURNS'[Index], "DATE1",MAX('INVESTMENT RETURNS'[DATE]), "CASHFLOW",MAX('INVESTMENT RETURNS'[EQUITY REPAYMENT/(INVESTMENT) ON SALE]) ) ), [CASHFLOW], [DATE1] ) )Thanks again for all your help. Much appreciated.
MJ
16 Replies
- v-ljerr-msftMicrosoft Employee
Hi mjfigg,
Based on my test, you should be able to use the formula below to build a rolling IRR in your scenario. :smileyhappy:
ROLLING IRR = VAR minIndex = CALCULATE ( MIN ( 'INVESTMENT RETURNS'[Index] ), ALL ( 'INVESTMENT RETURNS' ) ) RETURN IF ( 'INVESTMENT RETURNS'[Index] > minIndex, CALCULATE ( XIRR ( 'INVESTMENT RETURNS', 'INVESTMENT RETURNS'[FREE CASHFLOW FOR PERIOD], 'INVESTMENT RETURNS'[DATE] ), FILTER ( 'INVESTMENT RETURNS', EARLIER ( 'INVESTMENT RETURNS'[Index] ) >= 'INVESTMENT RETURNS'[Index] ) ) )Regards
- mjfiggFrequent Visitor
Hey there!
Thanks, the code worked great. However, I just realised that I will actually need another filter on the table for company name, as there will be multiple companies that an XIRR will need to be calculated for. See updated data below. Could you still help me?
Name Index FREE CASHFLOW FOR PERIOD DATE Company A 42 -7,531,293.00 30/06/2013 Company A 43 859,425.00 30/06/2014 Company A 44 901,305.00 30/06/2015 Company A 45 951,189.00 30/06/2016 Company A 46 7,742,641.00 30/06/2017 Company A 47 1,498,289.00 30/06/2018 Company B 48 -8401918 30/06/2014 Company B 49 949747 30/06/2015 Company B 50 942388 30/06/2016 Company B 51 943756 30/06/2017 Company B 52 1049089 30/06/2018 - v-ljerr-msftMicrosoft Employee
Hi mjfigg,
Sure! The formula below should work in this new scenario. :smileyhappy:
ROLLING IRR = VAR minIndex = CALCULATE ( MIN ( 'INVESTMENT RETURNS'[Index] ), FILTER ( ALL ( 'INVESTMENT RETURNS' ), 'INVESTMENT RETURNS'[Name] = EARLIER ( 'INVESTMENT RETURNS'[Name] ) ) ) RETURN IF ( 'INVESTMENT RETURNS'[Index] > minIndex, CALCULATE ( XIRR ( 'INVESTMENT RETURNS', 'INVESTMENT RETURNS'[FREE CASHFLOW FOR PERIOD], 'INVESTMENT RETURNS'[DATE] ), FILTER ( 'INVESTMENT RETURNS', EARLIER ( 'INVESTMENT RETURNS'[Index] ) >= 'INVESTMENT RETURNS'[Index] && 'INVESTMENT RETURNS'[Name] = EARLIER ( 'INVESTMENT RETURNS'[Name] ) ) ) )Regards