The ultimate Fabric, Power BI, SQL, and AI community-led learning event. Save €200 with code FABCOMM.
Get registeredCompete to become Power BI Data Viz World Champion! First round ends August 18th. Get started.
I want to calculate the return of single securities, entire portfolios and multiple portfolios using the method called Modified Dietz.
The Modified Dietz formula is the total result divided by the weighted capital. The weighted capital is calculated by adding the start value to the sum of time weighted cashflows.
The method is explained in depth here: https://en.wikipedia.org/wiki/Modified_Dietz_method
I have cleaned up my database and only left what is necessary to illustrate my challenge. I have two tables, Result and Calendar. In the Result table I have the columns
I have erased all instruments except the stock Norwegian Air Shuttle (NAS) listed on Oslo Stock Exchange. In my example I try to calculate the return from the 8. June 2021 to the 7. July 2021.
There are 3 cashflows during this period. Each need to be weighted for how long into the period they occur. The first cashflow happens on the first day and gets a weight of 30/30=1. The last one happens on the 2. July when there is 6 days left in the period and gets a weight of 6/30= 0,2.
This is my measure that is not working.
Return MD =
VAR Start_Date = FIRSTDATE('Calendar'[Date])
VAR End_Date = LASTDATE('Calendar'[Date])
VAR Start_Value = CALCULATE(SUM(Result[ValueStart]), Result[MeasureDate] = Start_Date)
VAR C = DATEDIFF(Start_Date, End_Date, DAY)+1
VAR Di = SUMX(Result, DATEDIFF(Result[MeasureDate], End_Date, DAY)+1)
VAR Wi = Di/C
VAR SumWixFi = SUMX(Result, [Cashflow]*Wi)
RETURN
DIVIDE(SUM(Result[Result]), Start_Value+SumWixFi)
By analyzing the calculation step by step and creating a measure for every variable, everything is correct until I try to sum up the products of the cashflows and the weights. This step: SUMX(Result, [Cashflow]*Wi)
This gives the total sum of cashflows multiplied by the sum of weights. Apparantley there is something about the use of DATEDIFF that I do not understand.
Thanks, you put me on the right path. When I understood that it was the calculation of Di that was bad I could concentrate on this one. Prevousily I had been experimenting with SUMMARIZE on the MeasureDate but I did not get it right then. I gave it another go now and I got the correct results.
I ended up with this formula:
Return MD =
VAR Start_Date = FIRSTDATE('Calendar'[Date])
VAR End_Date = LASTDATE('Calendar'[Date])
VAR Start_Value = CALCULATE(SUM(Result[ValueStart]), Result[MeasureDate] = Start_Date)
VAR C = DATEDIFF(Start_Date, End_Date, DAY)+1
VAR Dietz_Table = SUMMARIZE(Result, Result[MeasureDate], Result[SecuritySeq], "Di", SUMX(Result, DATEDIFF(Result[MeasureDate], End_Date, DAY)+1), "Fi", SUM(Result[Cashflow]))
VAR WixFi = SUMX(Dietz_Table, [Di]/C*[Fi])
RETURN
DIVIDE(SUM(Result[Result]), Start_Value+WixFi)
First I summarize on the MeasureDate and then on the SecuritySeq. This is because if I do not summarize on the SecuritySeq it will not work when there are several securities in the portfolio, which there always are.
Hi,
You appear to have made the somewhat common mistake of assuming that the result of your measure when applied to all dates within the filter context should be equal to the sum of the individual results of the measure for each of those dates.
In fact, the measure is giving the perfectly correct (and consistent) result. This is how it would breakdown with respect to the 'total' row:
Sum WixFi =
VAR Start_Date = 08/06/2021
VAR End_Date = 07/07/2021
VAR Start_Value = 1095000
VAR C = 30
VAR Di = 465
VAR Wi = 465/30
RETURN
SUMX(Result, [Cashflow]*Wi)
which is [(1064795)+(-572540)+(281597)]*(465/30), i.e. 11994706
Regards
User | Count |
---|---|
16 | |
8 | |
7 | |
6 | |
6 |
User | Count |
---|---|
26 | |
13 | |
12 | |
8 | |
8 |