Home Measuring Private Investment Returns
Post
Cancel

Measuring Private Investment Returns

This post is about methodologies to measure private investment return (python code included). Reference for this post can be found in INSEAD case studies. Full python code can be found in my GitHub repo. And full case note from INSEAD can be found in this link. CASE_NOTE

Introduction

In the world of private equity (PE), measuring the performance of investments is not only crucial for assessing current financial health but also for strategic decision-making for future investments. This blog post explores why measuring private investment return is important, delves into the methodology, strengths, and weaknesses of five common methods (IRR, Modified IRR, LN PME, KS PME, Direct Alpha), and concludes with our recommendations for investors.

Major characteristics of private invetment is iliquid market and exotic structure. Methodologies introduced in this post will incorporate infrequent cash flow schedule which makes DCF based methodology difficult, and exotic investment structure which makes researchers to difficult to proxy private investment using public market data.

Why Measuring Private Investment Return is Important

Measuring the return on private investments provides investors with insights into the financial health and performance of their investments relative to the market. It helps in making informed decisions about where to allocate resources and how to strategize for future investments. By evaluating performance, investors can identify top-performing funds, assess fund managers’ effectiveness, and compare returns across different asset classes. This measurement is critical not only for maximizing returns but also for understanding the risks associated with private equity investments.

Full Code

You can see full code in here CODE

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
## Internal Rate of Return (IRR)
The IRR is a popular metric in the PE industry, representing the discount rate that brings the net present value (NPV) of a series of cash flows to zero. It considers the size and timing of the fund's cash flows. However, IRR assumes reinvested capital at the same rate, potentially overstating performance for early successful exits due to unrealistic reinvestment opportunities. Below figure illustrates the concept of IRR in excel format. 
![Exhibit1](/assets/post_image/finance/private_invest/exhibit_1_IRR.png)

Below code is 
```python
import os
import sys
from datetime import datetime

import numpy as np
import numpy_financial as npf
from scipy.optimize import newton

def days_between(d1, d2):
    """Calculate the number of days between two dates."""
    d1 = datetime.strptime(d1, "%Y-%m-%d")
    d2 = datetime.strptime(d2, "%Y-%m-%d")
    return abs((d2 - d1).days)

def npv(rate, cashflows, days):
    """Calculate the net present value of cashflows at irregular intervals. (actual/360)"""
    total_value = 0
    for i, cashflow in enumerate(cashflows):
        total_value += cashflow / ((1 + rate) ** (days[i] / 360))
    return total_value

def irr(cashflows, dates):
    """Calculate the internal rate of return for irregular interval cashflows."""
    # Calculate days between cashflows
    start_date = dates[0]
    days_diff = [days_between(start_date, date) for date in dates]
    
    # Define a function to find the root
    func = lambda r: npv(r, cashflows, days_diff)
    
    # Use Newton's method to find the IRR
    # Starting with an initial guess of 10%
    # To guarantee convergence, please use bisection method
    irr_result = newton(func, 0.1)  
    return irr_result

dates = ['2018-01-01', '2019-12-31', '2020-12-31']
cashflows = [-100, -20, 150]

irr_result = irr(cashflows, dates)
irr_result

Modified Internal Rate of Return (MIRR)

MIRR addresses the reinvestment assumption of IRR, assuming cash flows are reinvested at a more realistic return rate and taking into account the cost of uncalled capital. This method provides a more accurate measure of performance, adjusting for extreme performance cases in both directions. Below figure illustrates the concept of IRR in excel format. Exhibit2

Below code is

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import os
import sys
from datetime import datetime

import numpy as np
import numpy_financial as npf
from scipy.optimize import newton

def calculate_days(dates):
    """Calculate days between each date and the first date."""
    start_date = datetime.strptime(dates[0], "%Y-%m-%d")
    days = [(datetime.strptime(date, "%Y-%m-%d") - start_date).days for date in dates]
    return days

def objective_function(rate, pv_negative, fv_positive, days):
    """
    Objective function for the Newton method, calculating the NPV of modified cash flows at 'rate'.
    """
    npv = npf.npv(rate, [pv_negative] + [0]*(len(days)-2) + [fv_positive])
    return npv

def mirr_newton(cashflows, cost_of_capital, reinvestment_rate, dates):
    """
    Calculate MIRR using the Newton method, considering cost of capital and reinvestment rate.
    """
    days = calculate_days(dates)
    years = [day / 360 for day in days]  # Convert days to years for each cash flow
    
    # Separate positive and negative cash flows
    positive_cashflows = np.array(cashflows)
    positive_cashflows[positive_cashflows < 0] = 0
    negative_cashflows = np.array(cashflows)
    negative_cashflows[negative_cashflows > 0] = 0
    
    # Calculate the Present Value (PV) of negative cashflows at the financing rate
    pv_negative = npf.npv(cost_of_capital, negative_cashflows)
    
    # Calculate the Future Value (FV) of positive cashflows at the reinvestment rate
    fv_positive = npf.fv(reinvestment_rate, max(years), 0, -sum(positive_cashflows))
    
    # Use the Newton method to solve for MIRR
    mirr_result = newton(func=objective_function, x0=0.1, args=(pv_negative, fv_positive, days))
    
    return mirr_result

# Using the updated parameters for calculation
cost_of_capital = 0.08
reinvestment_rate = 0.12
dates = ['2018-01-01', '2019-12-31', '2020-12-31', '2021-12-31']
cashflows = [-100, -20, 50, 100]

Long Nickels Public Market Equivalent (LNPME)

LN PME compares a PE fund’s performance with a benchmark public index by creating a theoretical investment in the index using the fund’s cash flows. This method allows for direct comparison between PE and public market returns, albeit with potential shortcomings in cases of high distributions. Below figure illustrates the concept of IRR in excel format. Exhibit3

Below code is

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import os
import sys
from datetime import datetime

import numpy as np
import numpy_financial as npf
from scipy.optimize import newton

def calculate_ln_pme(cf_dates, cf_schedule, index_values):
         
    PME_NAV_list = []
    PME_NAV_val = 0
    contribution, distrubution = 0,0
    for i in range(0, len(cf_dates)):
        if cf_schedule[i] < 0:
            contribution = contribution -(cf_schedule[i]/index_values[i]) 
        elif cf_schedule[i] > 0:
            distrubution = distrubution - (cf_schedule[i] / index_values[i])
    
        NAV_value = index_values[i] * (contribution + distrubution)
        PME_NAV_list.append(NAV_value)
    
    final_PME_NAV = PME_NAV_list[-1]

    # Final PME NAV calculation with the last NAV included
    adj_PME_NAV = cf_schedule
    adj_PME_NAV[-1] = final_PME_NAV

    # Calculate IRR of adjusted cash flows
    pme_irr = npf.irr(adj_PME_NAV)
    return final_PME_NAV, pme_irr

# Given data
cf_dates = ['2018-01-01', '2018-12-31', '2019-12-31']
cf_schedule = [-25, 15, 0] # Including the final NAV as a distribution
index_values = [100, 115, 130]

last_NAV = 20

# Calculate LN PME
final_pme_nav_value, ln_pme_irr_value = calculate_ln_pme(cf_dates, cf_schedule, index_values)

print(final_pme_nav_value, ln_pme_irr_value)

Kaplan Schoar Public Market Equivalent (KS PME)

KS PME measures the wealth multiple effect of investing in a PE fund versus an index, adjusting cash flows based on index performance. This method highlights the relative performance of a PE fund to the public market, though it overlooks cash flow timing. Below figure illustrates the concept of IRR in excel format. Exhibit4

Below code is

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import os
import sys
from datetime import datetime

import numpy as np
import numpy_financial as npf

def calculate_ks_pme(cf_dates, cf_schedule, index_values):
         
    PME_NAV_list = []
    PME_NAV_val = 0
    contribution, distrubution = 0,0


    index_return = []
    for i in range(len(index_values)):
        index_return.append((index_values[-1] / index_values[i]) - 1)
    
    adj_fv_list = []
    for i in range(len(cf_schedule)-1):
        adj_fv_list.append(cf_schedule[i] * (1 + index_return[i]))

    adj_fv_list.append(cf_schedule[-1])

    dist_nav = 0
    contribute = 0

    for i in range(len(adj_fv_list)):
        if adj_fv_list[i] < 0:
            contribute = contribute - adj_fv_list[i]
        else:
            dist_nav = dist_nav + adj_fv_list[i]


    return dist_nav / contribute

# Given data
cf_dates = ['2018-01-01', '2018-12-31', '2019-12-31']
cf_schedule = [-25, 15, 20] # Including the final NAV as a distribution
index_values = [100, 115, 130]

last_NAV = 20

# Calculate LN PME
ks_pme_irr = calculate_ks_pme(cf_dates, cf_schedule, index_values)

print(ks_pme_irr)

Direct Alpha

Direct Alpha quantifies the out/underperformance of a PE fund by calculating the IRR of compounded cash flows plus fund NAV. This method offers a precise rate of return of outperformance, addressing some of the limitations of PME methodologies. Below figure illustrates the concept of IRR in excel format. Exhibit5

Below code is

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import os
import sys
from datetime import datetime

import numpy as np
import numpy_financial as npf

def calculate_ks_pme(cf_dates, cf_schedule, index_values):
         
    PME_NAV_list = []
    PME_NAV_val = 0
    contribution, distrubution = 0,0


    index_return = []
    for i in range(len(index_values)):
        index_return.append((index_values[-1] / index_values[i]) - 1)
    
    adj_fv_list = []
    for i in range(len(cf_schedule)-1):
        adj_fv_list.append(cf_schedule[i] * (1 + index_return[i]))

    adj_fv_list.append(cf_schedule[-1])

    alpha = npf.irr(adj_fv_list)

    return alpha

# Given data
cf_dates = ['2018-01-01', '2018-12-31', '2019-12-31']
cf_schedule = [-25, 15, 20] # Including the final NAV as a distribution
index_values = [100, 115, 130]

last_NAV = 20

# Calculate LN PME
ks_pme_irr = calculate_ks_pme(cf_dates, cf_schedule, index_values)

print(ks_pme_irr)

Conclusion

Conclusion and Recommendations Investors in private equity face unique challenges in measuring and comparing returns due to the irregular timing and size of cash flows. While traditional metrics like IRR and MoM provide a starting point, more nuanced methodologies like MIRR, LN PME, KS PME, and Direct Alpha offer a more comprehensive view that accounts for the complexities of private equity investments. We recommend investors use a combination of these methods to gain a well-rounded understanding of their investment performance relative to the broader market.

As the PE market evolves, so too should the tools and methodologies we use to measure performance. It’s up to limited partners and investors to advocate for and adopt these more sophisticated measures, ensuring a deeper understanding and more effective management of their investments.

Understanding and accurately measuring investment returns is paramount in the dynamic landscape of private equity. By leveraging a combination of traditional and modern methodologies, investors can navigate this complex market with greater insight and precision.

This post is licensed under CC BY 4.0 by the author.