hoostus / portfolio-returns

Beancount portfolio returns generator
Other
38 stars 6 forks source link

Beancount Returns Calculator

This will calculator money-weighted and time-weighted returns for a portfolio for beancount, the double-entry plaintext accounting software.

Table of Contents

Quick Usage

python returns.py
    --account Assets:US:Vanguard
    --account Assets:US:Fidelity
    --internal Income:CapitalGainsDistribution
    --internal Income:Dividends
    --year 2018
    portfolio.bean

Dependencies

Introduction

This script will determine the rate of return for a portfolio held without beancount. You can specify which accounts & which timeframes you are interested in. We calculate "money-weighted returns", which means taking into account the timing & value of cashflows. In particular, this means you -- the user -- need to tell us which beancount accounts are real cashflows in & out of the account. See below for more on this.

Time-weighted Returns

Warning. Time-weighted returns are not implemented.

The time-weighted rate of return is the geometric mean of a series of equal-length holding periods.

Time-weighted rates of return do not take into account the impact of cash flows into and out of the portfolio.

Time-weighted rates of return attempt to remove the impact of cash flows when calculating the return. This makes it ideal for calculating the performance of broad market indices or the impact of a fund manager on the performance of an investment. Time-weighting is important in this context as fund managers do not control the timing of cash flows into and out of their fund – investors control that – so it is not reasonable to include that effect when evaluating the performance of the fund manager.

To calculate the time-weighted return we calculate the holding period return (HPR) of each day during the full time period and then find the geometric mean across all of the HPRs.

The formula for a single holding period return is: HPR = ((MV1 - MV0 + D1 - CF1)/MV0)

Money-weighted Returns

The money-weighted rate of return is the Internal Rate of Return (IRR or, in spreadsheets, XIRR).

Money-weighted returns take into account the timing & size of cash flows into and out of the portfolio, in addition to the performance of the underlying portfolio itself. Money-weighted returns can change significantly depending on the timing of large cash flows in & out of the portfolio.

The money-weighted return does not split the time period up into equal-length sub-periods. Instead it searches (via mathematical optimization techniques) for the discount rate that equals the cost of the investment plus all of the cash flows generated.

For the vast majority of investors a money-weighted rate of return is the most appropriate method of measuring the performance of your portfolio as you control inflows and outflows of the investment portfolio.

Illustrated Example of the Difference

If you don't buy any new shares, sell any shares, and all dividends are reinvested, then the money-weighted return and the time-weighted return will be the same over a given time period.

Since most people will be buying or selling shares, in practice they will differ.

Imagine you invest like:

  1. On January 1st you buy 100 shares of FOO at $100.
  2. On January 2nd you buy 100 more shares of FOO, this time at $500 each for $50,000.
  3. On January 3rd you sell 100 shares of FOO, this time at $50 each for $5,000.
  4. On January 4th, you do nothing. The price of FOO returns to $100.

The time-weighted return is 0%, since it ignores the impact of cash flows and just sees that the starting value (100 shares @ $100) is exactly the same as the ending value (100 shares @ $100).

Date Total Amount Shares Share price Holding Period Return
Jan 1 $10,000 100 $100 n/a
Jan 2 $100,000 200 $500 (100,000-10,000-50,000)/10,000 = 400%
Jan 3 $5,000 100 $50 (5,000-100,000+5,000)/100,000 = -90%
Jan 4 $10,000 100 $100 (10,000-5,000)/5,000 = 100%

The geometric mean of the Holding Period Returns is

=((1 + 4.00) * (1 - .90) * (1 + 1.00)) - 1
=0

Since you bought some shares for $50,000 and sold them for $5,000 you don't feel like the return was 0%, though.

The money-weighted return for the same investment is -52%.

External vs. internal cashflows

When calculating money-weighted returns we need to distinguish "real", or external, cashflows from "apparent", or internal, cashflows.

Imagine that your portfolio pays you a dividend but your account is set to automatically reinvest dividends. Even though there is an apparent cashflow between accounts nothing has actually changed; from the rate of return perspective it is as if the money never left your portfolio.

So we need to know which accounts to ignore when looking for cashflows. In practice, this is limited to three kinds of things:

Note on capital gains

There is a difference between a "capital gains distribution" and a "capital gain".

A "capital gains distribution" is when the fund family gives you money. This should be treated as a dividend, as an "internal cashflow". It is generated by the internal operation of the fund.

A "capital gain" is what happens when you sell a fund. This is an external cashflow.

Even though they are identical for tax purposes, they are different for the purposes of rate of return calculations. You need to ensure they going to two separate accounts in beancount.

Multi-currency issues

TBD. I have no idea if this works at all with multiple-currencies....

Parameters in more detail

TODOs & Bugs