mirror of
https://github.com/simonmichael/hledger.git
synced 2024-09-20 02:37:12 +03:00
;update manuals
This commit is contained in:
parent
0295be5553
commit
b6c667c388
@ -4469,14 +4469,295 @@ At a minimum, you need to supply a query (which could be just an account
|
|||||||
name) to select your investments with \f[C]--inv\f[R], and another query
|
name) to select your investments with \f[C]--inv\f[R], and another query
|
||||||
to identify your profit and loss transactions with \f[C]--pnl\f[R].
|
to identify your profit and loss transactions with \f[C]--pnl\f[R].
|
||||||
.PP
|
.PP
|
||||||
It will compute and display the internalized rate of return (IRR) and
|
This command will compute and display the internalized rate of return
|
||||||
time-weighted rate of return (TWR) for your investments for the time
|
(IRR) and time-weighted rate of return (TWR) for your investments for
|
||||||
period requested.
|
the time period requested.
|
||||||
Both rates of return are annualized before display, regardless of the
|
Both rates of return are annualized before display, regardless of the
|
||||||
length of reporting interval.
|
length of reporting interval.
|
||||||
.PP
|
.PP
|
||||||
An example:
|
Note, in some cases this report can fail, for these reasons:
|
||||||
|
.IP \[bu] 2
|
||||||
|
Error (NotBracketed): No solution for Internal Rate of Return (IRR).
|
||||||
|
Possible causes: IRR is huge (>1000000%), balance of investment becomes
|
||||||
|
negative at some point in time.
|
||||||
|
.IP \[bu] 2
|
||||||
|
Error (SearchFailed): Failed to find solution for Internal Rate of
|
||||||
|
Return (IRR).
|
||||||
|
Either search does not converge to a solution, or converges too slowly.
|
||||||
|
.PP
|
||||||
|
Examples:
|
||||||
|
.IP \[bu] 2
|
||||||
|
Using roi to report unrealised gains:
|
||||||
https://github.com/simonmichael/hledger/blob/master/examples/roi-unrealised.ledger
|
https://github.com/simonmichael/hledger/blob/master/examples/roi-unrealised.ledger
|
||||||
|
.PP
|
||||||
|
More background:
|
||||||
|
.PP
|
||||||
|
\[dq]ROI\[dq] stands for \[dq]return on investment\[dq].
|
||||||
|
Traditionally this was computed as a difference between current value of
|
||||||
|
investment and its initial value, expressed in percentage of the initial
|
||||||
|
value.
|
||||||
|
.PP
|
||||||
|
However, this approach is only practical in simple cases, where
|
||||||
|
investments receives no in-flows or out-flows of money, and where rate
|
||||||
|
of growth is fixed over time.
|
||||||
|
For more complex scenarios you need different ways to compute rate of
|
||||||
|
return, and this command implements two of them: IRR and TWR.
|
||||||
|
.PP
|
||||||
|
Internal rate of return, or \[dq]IRR\[dq] (also called
|
||||||
|
\[dq]money-weighted rate of return\[dq]) takes into account effects of
|
||||||
|
in-flows and out-flows.
|
||||||
|
Naively, if you are withdrawing from your investment, your future gains
|
||||||
|
would be smaller (in absolute numbers), and will be a smaller percentage
|
||||||
|
of your initial investment, and if you are adding to your investment,
|
||||||
|
you will receive bigger absolute gains (but probably at the same rate of
|
||||||
|
return).
|
||||||
|
IRR is a way to compute rate of return for each period between in-flow
|
||||||
|
or out-flow of money, and then combine them in a way that gives you an
|
||||||
|
annual rate of return that investment is expected to generate.
|
||||||
|
.PP
|
||||||
|
As mentioned before, in-flows and out-flows would be any cash that you
|
||||||
|
personally put in or withdraw, and for the \[dq]roi\[dq] command, these
|
||||||
|
are transactions that involve account(s) matching \f[C]--inv\f[R]
|
||||||
|
argument and NOT involve account(s) matching \f[C]--pnl\f[R] argument.
|
||||||
|
.PP
|
||||||
|
Presumably, you will also record changes in the value of your
|
||||||
|
investment, and balance them against \[dq]profit and loss\[dq] (or
|
||||||
|
\[dq]unrealized gains\[dq]) account.
|
||||||
|
Note that in order for IRR to compute the precise effect of your
|
||||||
|
in-flows and out-flows on the rate of return, you will need to record
|
||||||
|
the value of your investement on or close to the days when in- or
|
||||||
|
out-flows occur.
|
||||||
|
.PP
|
||||||
|
Implementation of IRR in hledger should match the \f[C]XIRR\f[R] formula
|
||||||
|
in Excel.
|
||||||
|
.PP
|
||||||
|
Second way to compute rate of return that \f[C]roi\f[R] command
|
||||||
|
implements is called \[dq]time-weighted rate of return\[dq] or
|
||||||
|
\[dq]TWR\[dq].
|
||||||
|
Like IRR, it will also break the history of your investment into periods
|
||||||
|
between in-flows and out-flows to compute rate of return per each period
|
||||||
|
and then a compound rate of return.
|
||||||
|
However, internal workings of TWR are quite different.
|
||||||
|
.PP
|
||||||
|
In technical terms, IRR uses the same approach as computation of net
|
||||||
|
present value, and tries to find a discount rate that makes net present
|
||||||
|
value of all the cash flows of your investment to add up to zero.
|
||||||
|
This could be hard to wrap your head around, especially if you
|
||||||
|
haven\[aq]t done discounted cash flow analysis before.
|
||||||
|
.PP
|
||||||
|
TWR represents your investment as an imaginary \[dq]unit fund\[dq] where
|
||||||
|
in-flows/ out-flows lead to buying or selling \[dq]units\[dq] of your
|
||||||
|
investment and changes in its value change the value of \[dq]investment
|
||||||
|
unit\[dq].
|
||||||
|
Change in \[dq]unit price\[dq] over the reporting period gives you rate
|
||||||
|
of return of your investment.
|
||||||
|
.PP
|
||||||
|
References: * Explanation of rate of return * Explanation of IRR *
|
||||||
|
Explanation of TWR * Examples of computing IRR and TWR and discussion of
|
||||||
|
the limitations of both metrics
|
||||||
|
.PP
|
||||||
|
More examples:
|
||||||
|
.PP
|
||||||
|
Lets say that we found an investment in Snake Oil that is proising to
|
||||||
|
give us 10% annually:
|
||||||
|
.IP
|
||||||
|
.nf
|
||||||
|
\f[C]
|
||||||
|
2019-01-01 Investing in Snake Oil
|
||||||
|
assets:cash -$100
|
||||||
|
investment:snake oil
|
||||||
|
|
||||||
|
2019-12-24 Recording the growth of Snake Oil
|
||||||
|
investment:snake oil = $110
|
||||||
|
equity:unrealized gains
|
||||||
|
\f[R]
|
||||||
|
.fi
|
||||||
|
.PP
|
||||||
|
For now, basic computation of the rate of return, as well as IRR and
|
||||||
|
TWR, gives us the expected 10%:
|
||||||
|
.IP
|
||||||
|
.nf
|
||||||
|
\f[C]
|
||||||
|
$ hledger roi -Y --inv investment --pnl \[dq]unrealized\[dq]
|
||||||
|
+---++------------+------------++---------------+----------+-------------+-----++--------+--------+
|
||||||
|
| || Begin | End || Value (begin) | Cashflow | Value (end) | PnL || IRR | TWR |
|
||||||
|
+===++============+============++===============+==========+=============+=====++========+========+
|
||||||
|
| 1 || 2019-01-01 | 2019-12-31 || 0 | 100 | 110 | 10 || 10.00% | 10.00% |
|
||||||
|
+---++------------+------------++---------------+----------+-------------+-----++--------+--------+
|
||||||
|
\f[R]
|
||||||
|
.fi
|
||||||
|
.PP
|
||||||
|
However, lets say that shorty after investing in the Snake Oil we
|
||||||
|
started to have second thoughs, so we prompty withdrew $90, leaving only
|
||||||
|
$10 in.
|
||||||
|
Before Christmas, though, we started to get the \[dq]fear of mission
|
||||||
|
out\[dq], so we put the $90 back in.
|
||||||
|
So for most of the year, our investment was just $10 dollars, and it
|
||||||
|
gave us just $1 in growth:
|
||||||
|
.IP
|
||||||
|
.nf
|
||||||
|
\f[C]
|
||||||
|
2019-01-01 Investing in Snake Oil
|
||||||
|
assets:cash -$100
|
||||||
|
investment:snake oil
|
||||||
|
|
||||||
|
2019-01-02 Buyers remorse
|
||||||
|
assets:cash $90
|
||||||
|
investment:snake oil
|
||||||
|
|
||||||
|
2019-12-30 Fear of missing out
|
||||||
|
assets:cash -$90
|
||||||
|
investment:snake oil
|
||||||
|
|
||||||
|
2019-12-31 Recording the growth of Snake Oil
|
||||||
|
investment:snake oil = $101
|
||||||
|
equity:unrealized gains
|
||||||
|
\f[R]
|
||||||
|
.fi
|
||||||
|
.PP
|
||||||
|
Now IRR and TWR are drastically different:
|
||||||
|
.IP
|
||||||
|
.nf
|
||||||
|
\f[C]
|
||||||
|
$ hledger roi -Y --inv investment --pnl \[dq]unrealized\[dq]
|
||||||
|
+---++------------+------------++---------------+----------+-------------+-----++-------+-------+
|
||||||
|
| || Begin | End || Value (begin) | Cashflow | Value (end) | PnL || IRR | TWR |
|
||||||
|
+===++============+============++===============+==========+=============+=====++=======+=======+
|
||||||
|
| 1 || 2019-01-01 | 2019-12-31 || 0 | 100 | 101 | 1 || 9.32% | 1.00% |
|
||||||
|
+---++------------+------------++---------------+----------+-------------+-----++-------+-------+
|
||||||
|
\f[R]
|
||||||
|
.fi
|
||||||
|
.PP
|
||||||
|
Here, IRR tells us that we made close to 10% on the $10 dollars that we
|
||||||
|
had in the account most of the time.
|
||||||
|
And TWR is ...
|
||||||
|
just 1%?
|
||||||
|
Why?
|
||||||
|
.PP
|
||||||
|
Based on the transactions in our journal, TWR \[dq]think\[dq] that we
|
||||||
|
are buying back $90 worst of Snake Oil at the same price that it had at
|
||||||
|
the beginning of they year, and then after that our $100 investment gets
|
||||||
|
$1 increase in value, or 1% of $100.
|
||||||
|
Let\[aq]s take a closer look at what is happening here by asking for
|
||||||
|
quarterly reports instead of annual:
|
||||||
|
.IP
|
||||||
|
.nf
|
||||||
|
\f[C]
|
||||||
|
$ hledger roi -Q --inv investment --pnl \[dq]unrealized\[dq]
|
||||||
|
+---++------------+------------++---------------+----------+-------------+-----++--------+-------+
|
||||||
|
| || Begin | End || Value (begin) | Cashflow | Value (end) | PnL || IRR | TWR |
|
||||||
|
+===++============+============++===============+==========+=============+=====++========+=======+
|
||||||
|
| 1 || 2019-01-01 | 2019-03-31 || 0 | 10 | 10 | 0 || 0.00% | 0.00% |
|
||||||
|
| 2 || 2019-04-01 | 2019-06-30 || 10 | 0 | 10 | 0 || 0.00% | 0.00% |
|
||||||
|
| 3 || 2019-07-01 | 2019-09-30 || 10 | 0 | 10 | 0 || 0.00% | 0.00% |
|
||||||
|
| 4 || 2019-10-01 | 2019-12-31 || 10 | 90 | 101 | 1 || 37.80% | 4.03% |
|
||||||
|
+---++------------+------------++---------------+----------+-------------+-----++--------+-------+
|
||||||
|
\f[R]
|
||||||
|
.fi
|
||||||
|
.PP
|
||||||
|
Now both IRR and TWR are thrown off by the fact that all of the growth
|
||||||
|
for our investment happens in Q4 2019.
|
||||||
|
This happes because IRR computation is still yielding 9.32% and TWR is
|
||||||
|
still 1%, but this time these are rates for three month period instead
|
||||||
|
of twelve, so in order to get an annual rate they should be multiplied
|
||||||
|
by four!
|
||||||
|
.PP
|
||||||
|
Let\[aq]s try to keep a better record of how Snake Oil grew in value:
|
||||||
|
.IP
|
||||||
|
.nf
|
||||||
|
\f[C]
|
||||||
|
2019-01-01 Investing in Snake Oil
|
||||||
|
assets:cash -$100
|
||||||
|
investment:snake oil
|
||||||
|
|
||||||
|
2019-01-02 Buyers remorse
|
||||||
|
assets:cash $90
|
||||||
|
investment:snake oil
|
||||||
|
|
||||||
|
2019-02-28 Recording the growth of Snake Oil
|
||||||
|
investment:snake oil
|
||||||
|
equity:unrealized gains -$0.25
|
||||||
|
|
||||||
|
2019-06-30 Recording the growth of Snake Oil
|
||||||
|
investment:snake oil
|
||||||
|
equity:unrealized gains -$0.25
|
||||||
|
|
||||||
|
2019-09-30 Recording the growth of Snake Oil
|
||||||
|
investment:snake oil
|
||||||
|
equity:unrealized gains -$0.25
|
||||||
|
|
||||||
|
2019-12-30 Fear of missing out
|
||||||
|
assets:cash -$90
|
||||||
|
investment:snake oil
|
||||||
|
|
||||||
|
2019-12-31 Recording the growth of Snake Oil
|
||||||
|
investment:snake oil
|
||||||
|
equity:unrealized gains -$0.25
|
||||||
|
\f[R]
|
||||||
|
.fi
|
||||||
|
.PP
|
||||||
|
Would our quartery report look better now?
|
||||||
|
Almost:
|
||||||
|
.IP
|
||||||
|
.nf
|
||||||
|
\f[C]
|
||||||
|
$ hledger roi -Q --inv investment --pnl \[dq]unrealized\[dq]
|
||||||
|
+---++------------+------------++---------------+----------+-------------+------++--------+--------+
|
||||||
|
| || Begin | End || Value (begin) | Cashflow | Value (end) | PnL || IRR | TWR |
|
||||||
|
+===++============+============++===============+==========+=============+======++========+========+
|
||||||
|
| 1 || 2019-01-01 | 2019-03-31 || 0 | 10 | 10.25 | 0.25 || 9.53% | 10.53% |
|
||||||
|
| 2 || 2019-04-01 | 2019-06-30 || 10.25 | 0 | 10.50 | 0.25 || 10.15% | 10.15% |
|
||||||
|
| 3 || 2019-07-01 | 2019-09-30 || 10.50 | 0 | 10.75 | 0.25 || 9.79% | 9.78% |
|
||||||
|
| 4 || 2019-10-01 | 2019-12-31 || 10.75 | 90 | 101.00 | 0.25 || 8.05% | 1.00% |
|
||||||
|
+---++------------+------------++---------------+----------+-------------+------++--------+--------+
|
||||||
|
\f[R]
|
||||||
|
.fi
|
||||||
|
.PP
|
||||||
|
Something is still wrong with TWR computation for Q4, and if you have
|
||||||
|
been paying attention you know what it is already: big $90 buy-back is
|
||||||
|
recorded prior to the only transaction that captures the change of value
|
||||||
|
of Snake Oil that happened in this time period.
|
||||||
|
Lets combine transactions from 30th and 31st of Dec into one:
|
||||||
|
.IP
|
||||||
|
.nf
|
||||||
|
\f[C]
|
||||||
|
2019-12-30 Fear of missing out and growth of Snake Oil
|
||||||
|
assets:cash -$90
|
||||||
|
investment:snake oil
|
||||||
|
equity:unrealized gains -$0.25
|
||||||
|
\f[R]
|
||||||
|
.fi
|
||||||
|
.PP
|
||||||
|
Now growth of investment properly affects its price at the time of
|
||||||
|
buy-back:
|
||||||
|
.IP
|
||||||
|
.nf
|
||||||
|
\f[C]
|
||||||
|
$ hledger roi -Q --inv investment --pnl \[dq]unrealized\[dq]
|
||||||
|
+---++------------+------------++---------------+----------+-------------+------++--------+--------+
|
||||||
|
| || Begin | End || Value (begin) | Cashflow | Value (end) | PnL || IRR | TWR |
|
||||||
|
+===++============+============++===============+==========+=============+======++========+========+
|
||||||
|
| 1 || 2019-01-01 | 2019-03-31 || 0 | 10 | 10.25 | 0.25 || 9.53% | 10.53% |
|
||||||
|
| 2 || 2019-04-01 | 2019-06-30 || 10.25 | 0 | 10.50 | 0.25 || 10.15% | 10.15% |
|
||||||
|
| 3 || 2019-07-01 | 2019-09-30 || 10.50 | 0 | 10.75 | 0.25 || 9.79% | 9.78% |
|
||||||
|
| 4 || 2019-10-01 | 2019-12-31 || 10.75 | 90 | 101.00 | 0.25 || 8.05% | 9.57% |
|
||||||
|
+---++------------+------------++---------------+----------+-------------+------++--------+--------+
|
||||||
|
\f[R]
|
||||||
|
.fi
|
||||||
|
.PP
|
||||||
|
And for annual report, TWR now reports the exact profitability of our
|
||||||
|
investment:
|
||||||
|
.IP
|
||||||
|
.nf
|
||||||
|
\f[C]
|
||||||
|
$ hledger roi -Y --inv investment --pnl \[dq]unrealized\[dq]
|
||||||
|
+---++------------+------------++---------------+----------+-------------+------++-------+--------+
|
||||||
|
| || Begin | End || Value (begin) | Cashflow | Value (end) | PnL || IRR | TWR |
|
||||||
|
+===++============+============++===============+==========+=============+======++=======+========+
|
||||||
|
| 1 || 2019-01-01 | 2019-12-31 || 0 | 100 | 101.00 | 1.00 || 9.32% | 10.00% |
|
||||||
|
+---++------------+------------++---------------+----------+-------------+------++-------+--------+
|
||||||
|
\f[R]
|
||||||
|
.fi
|
||||||
.SS stats
|
.SS stats
|
||||||
.PP
|
.PP
|
||||||
stats
|
stats
|
||||||
|
@ -3798,13 +3798,238 @@ your investments or withdrawals.
|
|||||||
account name) to select your investments with '--inv', and another query
|
account name) to select your investments with '--inv', and another query
|
||||||
to identify your profit and loss transactions with '--pnl'.
|
to identify your profit and loss transactions with '--pnl'.
|
||||||
|
|
||||||
It will compute and display the internalized rate of return (IRR) and
|
This command will compute and display the internalized rate of return
|
||||||
time-weighted rate of return (TWR) for your investments for the time
|
(IRR) and time-weighted rate of return (TWR) for your investments for
|
||||||
period requested. Both rates of return are annualized before display,
|
the time period requested. Both rates of return are annualized before
|
||||||
regardless of the length of reporting interval.
|
display, regardless of the length of reporting interval.
|
||||||
|
|
||||||
An example:
|
Note, in some cases this report can fail, for these reasons:
|
||||||
https://github.com/simonmichael/hledger/blob/master/examples/roi-unrealised.ledger
|
|
||||||
|
* Error (NotBracketed): No solution for Internal Rate of Return
|
||||||
|
(IRR). Possible causes: IRR is huge (>1000000%), balance of
|
||||||
|
investment becomes negative at some point in time.
|
||||||
|
* Error (SearchFailed): Failed to find solution for Internal Rate of
|
||||||
|
Return (IRR). Either search does not converge to a solution, or
|
||||||
|
converges too slowly.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
* Using roi to report unrealised gains:
|
||||||
|
https://github.com/simonmichael/hledger/blob/master/examples/roi-unrealised.ledger
|
||||||
|
|
||||||
|
More background:
|
||||||
|
|
||||||
|
"ROI" stands for "return on investment". Traditionally this was
|
||||||
|
computed as a difference between current value of investment and its
|
||||||
|
initial value, expressed in percentage of the initial value.
|
||||||
|
|
||||||
|
However, this approach is only practical in simple cases, where
|
||||||
|
investments receives no in-flows or out-flows of money, and where rate
|
||||||
|
of growth is fixed over time. For more complex scenarios you need
|
||||||
|
different ways to compute rate of return, and this command implements
|
||||||
|
two of them: IRR and TWR.
|
||||||
|
|
||||||
|
Internal rate of return, or "IRR" (also called "money-weighted rate
|
||||||
|
of return") takes into account effects of in-flows and out-flows.
|
||||||
|
Naively, if you are withdrawing from your investment, your future gains
|
||||||
|
would be smaller (in absolute numbers), and will be a smaller percentage
|
||||||
|
of your initial investment, and if you are adding to your investment,
|
||||||
|
you will receive bigger absolute gains (but probably at the same rate of
|
||||||
|
return). IRR is a way to compute rate of return for each period between
|
||||||
|
in-flow or out-flow of money, and then combine them in a way that gives
|
||||||
|
you an annual rate of return that investment is expected to generate.
|
||||||
|
|
||||||
|
As mentioned before, in-flows and out-flows would be any cash that
|
||||||
|
you personally put in or withdraw, and for the "roi" command, these are
|
||||||
|
transactions that involve account(s) matching '--inv' argument and NOT
|
||||||
|
involve account(s) matching '--pnl' argument.
|
||||||
|
|
||||||
|
Presumably, you will also record changes in the value of your
|
||||||
|
investment, and balance them against "profit and loss" (or "unrealized
|
||||||
|
gains") account. Note that in order for IRR to compute the precise
|
||||||
|
effect of your in-flows and out-flows on the rate of return, you will
|
||||||
|
need to record the value of your investement on or close to the days
|
||||||
|
when in- or out-flows occur.
|
||||||
|
|
||||||
|
Implementation of IRR in hledger should match the 'XIRR' formula in
|
||||||
|
Excel.
|
||||||
|
|
||||||
|
Second way to compute rate of return that 'roi' command implements is
|
||||||
|
called "time-weighted rate of return" or "TWR". Like IRR, it will also
|
||||||
|
break the history of your investment into periods between in-flows and
|
||||||
|
out-flows to compute rate of return per each period and then a compound
|
||||||
|
rate of return. However, internal workings of TWR are quite different.
|
||||||
|
|
||||||
|
In technical terms, IRR uses the same approach as computation of net
|
||||||
|
present value, and tries to find a discount rate that makes net present
|
||||||
|
value of all the cash flows of your investment to add up to zero. This
|
||||||
|
could be hard to wrap your head around, especially if you haven't done
|
||||||
|
discounted cash flow analysis before.
|
||||||
|
|
||||||
|
TWR represents your investment as an imaginary "unit fund" where
|
||||||
|
in-flows/ out-flows lead to buying or selling "units" of your investment
|
||||||
|
and changes in its value change the value of "investment unit". Change
|
||||||
|
in "unit price" over the reporting period gives you rate of return of
|
||||||
|
your investment.
|
||||||
|
|
||||||
|
References: * Explanation of rate of return * Explanation of IRR *
|
||||||
|
Explanation of TWR * Examples of computing IRR and TWR and discussion of
|
||||||
|
the limitations of both metrics
|
||||||
|
|
||||||
|
More examples:
|
||||||
|
|
||||||
|
Lets say that we found an investment in Snake Oil that is proising to
|
||||||
|
give us 10% annually:
|
||||||
|
|
||||||
|
2019-01-01 Investing in Snake Oil
|
||||||
|
assets:cash -$100
|
||||||
|
investment:snake oil
|
||||||
|
|
||||||
|
2019-12-24 Recording the growth of Snake Oil
|
||||||
|
investment:snake oil = $110
|
||||||
|
equity:unrealized gains
|
||||||
|
|
||||||
|
For now, basic computation of the rate of return, as well as IRR and
|
||||||
|
TWR, gives us the expected 10%:
|
||||||
|
|
||||||
|
$ hledger roi -Y --inv investment --pnl "unrealized"
|
||||||
|
+---++------------+------------++---------------+----------+-------------+-----++--------+--------+
|
||||||
|
| || Begin | End || Value (begin) | Cashflow | Value (end) | PnL || IRR | TWR |
|
||||||
|
+===++============+============++===============+==========+=============+=====++========+========+
|
||||||
|
| 1 || 2019-01-01 | 2019-12-31 || 0 | 100 | 110 | 10 || 10.00% | 10.00% |
|
||||||
|
+---++------------+------------++---------------+----------+-------------+-----++--------+--------+
|
||||||
|
|
||||||
|
However, lets say that shorty after investing in the Snake Oil we
|
||||||
|
started to have second thoughs, so we prompty withdrew $90, leaving only
|
||||||
|
$10 in. Before Christmas, though, we started to get the "fear of
|
||||||
|
mission out", so we put the $90 back in. So for most of the year, our
|
||||||
|
investment was just $10 dollars, and it gave us just $1 in growth:
|
||||||
|
|
||||||
|
2019-01-01 Investing in Snake Oil
|
||||||
|
assets:cash -$100
|
||||||
|
investment:snake oil
|
||||||
|
|
||||||
|
2019-01-02 Buyers remorse
|
||||||
|
assets:cash $90
|
||||||
|
investment:snake oil
|
||||||
|
|
||||||
|
2019-12-30 Fear of missing out
|
||||||
|
assets:cash -$90
|
||||||
|
investment:snake oil
|
||||||
|
|
||||||
|
2019-12-31 Recording the growth of Snake Oil
|
||||||
|
investment:snake oil = $101
|
||||||
|
equity:unrealized gains
|
||||||
|
|
||||||
|
Now IRR and TWR are drastically different:
|
||||||
|
|
||||||
|
$ hledger roi -Y --inv investment --pnl "unrealized"
|
||||||
|
+---++------------+------------++---------------+----------+-------------+-----++-------+-------+
|
||||||
|
| || Begin | End || Value (begin) | Cashflow | Value (end) | PnL || IRR | TWR |
|
||||||
|
+===++============+============++===============+==========+=============+=====++=======+=======+
|
||||||
|
| 1 || 2019-01-01 | 2019-12-31 || 0 | 100 | 101 | 1 || 9.32% | 1.00% |
|
||||||
|
+---++------------+------------++---------------+----------+-------------+-----++-------+-------+
|
||||||
|
|
||||||
|
Here, IRR tells us that we made close to 10% on the $10 dollars that
|
||||||
|
we had in the account most of the time. And TWR is ... just 1%? Why?
|
||||||
|
|
||||||
|
Based on the transactions in our journal, TWR "think" that we are
|
||||||
|
buying back $90 worst of Snake Oil at the same price that it had at the
|
||||||
|
beginning of they year, and then after that our $100 investment gets $1
|
||||||
|
increase in value, or 1% of $100. Let's take a closer look at what is
|
||||||
|
happening here by asking for quarterly reports instead of annual:
|
||||||
|
|
||||||
|
$ hledger roi -Q --inv investment --pnl "unrealized"
|
||||||
|
+---++------------+------------++---------------+----------+-------------+-----++--------+-------+
|
||||||
|
| || Begin | End || Value (begin) | Cashflow | Value (end) | PnL || IRR | TWR |
|
||||||
|
+===++============+============++===============+==========+=============+=====++========+=======+
|
||||||
|
| 1 || 2019-01-01 | 2019-03-31 || 0 | 10 | 10 | 0 || 0.00% | 0.00% |
|
||||||
|
| 2 || 2019-04-01 | 2019-06-30 || 10 | 0 | 10 | 0 || 0.00% | 0.00% |
|
||||||
|
| 3 || 2019-07-01 | 2019-09-30 || 10 | 0 | 10 | 0 || 0.00% | 0.00% |
|
||||||
|
| 4 || 2019-10-01 | 2019-12-31 || 10 | 90 | 101 | 1 || 37.80% | 4.03% |
|
||||||
|
+---++------------+------------++---------------+----------+-------------+-----++--------+-------+
|
||||||
|
|
||||||
|
Now both IRR and TWR are thrown off by the fact that all of the
|
||||||
|
growth for our investment happens in Q4 2019. This happes because IRR
|
||||||
|
computation is still yielding 9.32% and TWR is still 1%, but this time
|
||||||
|
these are rates for three month period instead of twelve, so in order to
|
||||||
|
get an annual rate they should be multiplied by four!
|
||||||
|
|
||||||
|
Let's try to keep a better record of how Snake Oil grew in value:
|
||||||
|
|
||||||
|
2019-01-01 Investing in Snake Oil
|
||||||
|
assets:cash -$100
|
||||||
|
investment:snake oil
|
||||||
|
|
||||||
|
2019-01-02 Buyers remorse
|
||||||
|
assets:cash $90
|
||||||
|
investment:snake oil
|
||||||
|
|
||||||
|
2019-02-28 Recording the growth of Snake Oil
|
||||||
|
investment:snake oil
|
||||||
|
equity:unrealized gains -$0.25
|
||||||
|
|
||||||
|
2019-06-30 Recording the growth of Snake Oil
|
||||||
|
investment:snake oil
|
||||||
|
equity:unrealized gains -$0.25
|
||||||
|
|
||||||
|
2019-09-30 Recording the growth of Snake Oil
|
||||||
|
investment:snake oil
|
||||||
|
equity:unrealized gains -$0.25
|
||||||
|
|
||||||
|
2019-12-30 Fear of missing out
|
||||||
|
assets:cash -$90
|
||||||
|
investment:snake oil
|
||||||
|
|
||||||
|
2019-12-31 Recording the growth of Snake Oil
|
||||||
|
investment:snake oil
|
||||||
|
equity:unrealized gains -$0.25
|
||||||
|
|
||||||
|
Would our quartery report look better now? Almost:
|
||||||
|
|
||||||
|
$ hledger roi -Q --inv investment --pnl "unrealized"
|
||||||
|
+---++------------+------------++---------------+----------+-------------+------++--------+--------+
|
||||||
|
| || Begin | End || Value (begin) | Cashflow | Value (end) | PnL || IRR | TWR |
|
||||||
|
+===++============+============++===============+==========+=============+======++========+========+
|
||||||
|
| 1 || 2019-01-01 | 2019-03-31 || 0 | 10 | 10.25 | 0.25 || 9.53% | 10.53% |
|
||||||
|
| 2 || 2019-04-01 | 2019-06-30 || 10.25 | 0 | 10.50 | 0.25 || 10.15% | 10.15% |
|
||||||
|
| 3 || 2019-07-01 | 2019-09-30 || 10.50 | 0 | 10.75 | 0.25 || 9.79% | 9.78% |
|
||||||
|
| 4 || 2019-10-01 | 2019-12-31 || 10.75 | 90 | 101.00 | 0.25 || 8.05% | 1.00% |
|
||||||
|
+---++------------+------------++---------------+----------+-------------+------++--------+--------+
|
||||||
|
|
||||||
|
Something is still wrong with TWR computation for Q4, and if you have
|
||||||
|
been paying attention you know what it is already: big $90 buy-back is
|
||||||
|
recorded prior to the only transaction that captures the change of value
|
||||||
|
of Snake Oil that happened in this time period. Lets combine
|
||||||
|
transactions from 30th and 31st of Dec into one:
|
||||||
|
|
||||||
|
2019-12-30 Fear of missing out and growth of Snake Oil
|
||||||
|
assets:cash -$90
|
||||||
|
investment:snake oil
|
||||||
|
equity:unrealized gains -$0.25
|
||||||
|
|
||||||
|
Now growth of investment properly affects its price at the time of
|
||||||
|
buy-back:
|
||||||
|
|
||||||
|
$ hledger roi -Q --inv investment --pnl "unrealized"
|
||||||
|
+---++------------+------------++---------------+----------+-------------+------++--------+--------+
|
||||||
|
| || Begin | End || Value (begin) | Cashflow | Value (end) | PnL || IRR | TWR |
|
||||||
|
+===++============+============++===============+==========+=============+======++========+========+
|
||||||
|
| 1 || 2019-01-01 | 2019-03-31 || 0 | 10 | 10.25 | 0.25 || 9.53% | 10.53% |
|
||||||
|
| 2 || 2019-04-01 | 2019-06-30 || 10.25 | 0 | 10.50 | 0.25 || 10.15% | 10.15% |
|
||||||
|
| 3 || 2019-07-01 | 2019-09-30 || 10.50 | 0 | 10.75 | 0.25 || 9.79% | 9.78% |
|
||||||
|
| 4 || 2019-10-01 | 2019-12-31 || 10.75 | 90 | 101.00 | 0.25 || 8.05% | 9.57% |
|
||||||
|
+---++------------+------------++---------------+----------+-------------+------++--------+--------+
|
||||||
|
|
||||||
|
And for annual report, TWR now reports the exact profitability of our
|
||||||
|
investment:
|
||||||
|
|
||||||
|
$ hledger roi -Y --inv investment --pnl "unrealized"
|
||||||
|
+---++------------+------------++---------------+----------+-------------+------++-------+--------+
|
||||||
|
| || Begin | End || Value (begin) | Cashflow | Value (end) | PnL || IRR | TWR |
|
||||||
|
+===++============+============++===============+==========+=============+======++=======+========+
|
||||||
|
| 1 || 2019-01-01 | 2019-12-31 || 0 | 100 | 101.00 | 1.00 || 9.32% | 10.00% |
|
||||||
|
+---++------------+------------++---------------+----------+-------------+------++-------+--------+
|
||||||
|
|
||||||
|
|
||||||
File: hledger.info, Node: stats, Next: tags, Prev: roi, Up: COMMANDS
|
File: hledger.info, Node: stats, Next: tags, Prev: roi, Up: COMMANDS
|
||||||
@ -4290,30 +4515,30 @@ Node: rewrite vs print --auto133861
|
|||||||
Ref: #rewrite-vs.-print---auto134040
|
Ref: #rewrite-vs.-print---auto134040
|
||||||
Node: roi134596
|
Node: roi134596
|
||||||
Ref: #roi134694
|
Ref: #roi134694
|
||||||
Node: stats135805
|
Node: stats146904
|
||||||
Ref: #stats135904
|
Ref: #stats147003
|
||||||
Node: tags136692
|
Node: tags147791
|
||||||
Ref: #tags136790
|
Ref: #tags147889
|
||||||
Node: test137309
|
Node: test148408
|
||||||
Ref: #test137417
|
Ref: #test148516
|
||||||
Node: Add-on commands138164
|
Node: Add-on commands149263
|
||||||
Ref: #add-on-commands138281
|
Ref: #add-on-commands149380
|
||||||
Node: ui139624
|
Node: ui150723
|
||||||
Ref: #ui139712
|
Ref: #ui150811
|
||||||
Node: web139766
|
Node: web150865
|
||||||
Ref: #web139869
|
Ref: #web150968
|
||||||
Node: iadd139985
|
Node: iadd151084
|
||||||
Ref: #iadd140096
|
Ref: #iadd151195
|
||||||
Node: interest140178
|
Node: interest151277
|
||||||
Ref: #interest140285
|
Ref: #interest151384
|
||||||
Node: ENVIRONMENT140525
|
Node: ENVIRONMENT151624
|
||||||
Ref: #environment140637
|
Ref: #environment151736
|
||||||
Node: FILES141622
|
Node: FILES152721
|
||||||
Ref: #files-1141725
|
Ref: #files-1152824
|
||||||
Node: LIMITATIONS141938
|
Node: LIMITATIONS153037
|
||||||
Ref: #limitations142057
|
Ref: #limitations153156
|
||||||
Node: TROUBLESHOOTING142799
|
Node: TROUBLESHOOTING153898
|
||||||
Ref: #troubleshooting142912
|
Ref: #troubleshooting154011
|
||||||
|
|
||||||
End Tag Table
|
End Tag Table
|
||||||
|
|
||||||
|
@ -3230,20 +3230,247 @@ COMMANDS
|
|||||||
count name) to select your investments with --inv, and another query to
|
count name) to select your investments with --inv, and another query to
|
||||||
identify your profit and loss transactions with --pnl.
|
identify your profit and loss transactions with --pnl.
|
||||||
|
|
||||||
It will compute and display the internalized rate of return (IRR) and
|
This command will compute and display the internalized rate of return
|
||||||
time-weighted rate of return (TWR) for your investments for the time
|
(IRR) and time-weighted rate of return (TWR) for your investments for
|
||||||
period requested. Both rates of return are annualized before display,
|
the time period requested. Both rates of return are annualized before
|
||||||
regardless of the length of reporting interval.
|
display, regardless of the length of reporting interval.
|
||||||
|
|
||||||
An example: https://github.com/simonmichael/hledger/blob/master/exam-
|
Note, in some cases this report can fail, for these reasons:
|
||||||
ples/roi-unrealised.ledger
|
|
||||||
|
o Error (NotBracketed): No solution for Internal Rate of Return (IRR).
|
||||||
|
Possible causes: IRR is huge (>1000000%), balance of investment be-
|
||||||
|
comes negative at some point in time.
|
||||||
|
|
||||||
|
o Error (SearchFailed): Failed to find solution for Internal Rate of
|
||||||
|
Return (IRR). Either search does not converge to a solution, or con-
|
||||||
|
verges too slowly.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
o Using roi to report unrealised gains: https://github.com/simon-
|
||||||
|
michael/hledger/blob/master/examples/roi-unrealised.ledger
|
||||||
|
|
||||||
|
More background:
|
||||||
|
|
||||||
|
"ROI" stands for "return on investment". Traditionally this was com-
|
||||||
|
puted as a difference between current value of investment and its ini-
|
||||||
|
tial value, expressed in percentage of the initial value.
|
||||||
|
|
||||||
|
However, this approach is only practical in simple cases, where invest-
|
||||||
|
ments receives no in-flows or out-flows of money, and where rate of
|
||||||
|
growth is fixed over time. For more complex scenarios you need differ-
|
||||||
|
ent ways to compute rate of return, and this command implements two of
|
||||||
|
them: IRR and TWR.
|
||||||
|
|
||||||
|
Internal rate of return, or "IRR" (also called "money-weighted rate of
|
||||||
|
return") takes into account effects of in-flows and out-flows.
|
||||||
|
Naively, if you are withdrawing from your investment, your future gains
|
||||||
|
would be smaller (in absolute numbers), and will be a smaller percent-
|
||||||
|
age of your initial investment, and if you are adding to your invest-
|
||||||
|
ment, you will receive bigger absolute gains (but probably at the same
|
||||||
|
rate of return). IRR is a way to compute rate of return for each pe-
|
||||||
|
riod between in-flow or out-flow of money, and then combine them in a
|
||||||
|
way that gives you an annual rate of return that investment is expected
|
||||||
|
to generate.
|
||||||
|
|
||||||
|
As mentioned before, in-flows and out-flows would be any cash that you
|
||||||
|
personally put in or withdraw, and for the "roi" command, these are
|
||||||
|
transactions that involve account(s) matching --inv argument and NOT
|
||||||
|
involve account(s) matching --pnl argument.
|
||||||
|
|
||||||
|
Presumably, you will also record changes in the value of your invest-
|
||||||
|
ment, and balance them against "profit and loss" (or "unrealized
|
||||||
|
gains") account. Note that in order for IRR to compute the precise ef-
|
||||||
|
fect of your in-flows and out-flows on the rate of return, you will
|
||||||
|
need to record the value of your investement on or close to the days
|
||||||
|
when in- or out-flows occur.
|
||||||
|
|
||||||
|
Implementation of IRR in hledger should match the XIRR formula in Ex-
|
||||||
|
cel.
|
||||||
|
|
||||||
|
Second way to compute rate of return that roi command implements is
|
||||||
|
called "time-weighted rate of return" or "TWR". Like IRR, it will also
|
||||||
|
break the history of your investment into periods between in-flows and
|
||||||
|
out-flows to compute rate of return per each period and then a compound
|
||||||
|
rate of return. However, internal workings of TWR are quite different.
|
||||||
|
|
||||||
|
In technical terms, IRR uses the same approach as computation of net
|
||||||
|
present value, and tries to find a discount rate that makes net present
|
||||||
|
value of all the cash flows of your investment to add up to zero. This
|
||||||
|
could be hard to wrap your head around, especially if you haven't done
|
||||||
|
discounted cash flow analysis before.
|
||||||
|
|
||||||
|
TWR represents your investment as an imaginary "unit fund" where in-
|
||||||
|
flows/ out-flows lead to buying or selling "units" of your investment
|
||||||
|
and changes in its value change the value of "investment unit". Change
|
||||||
|
in "unit price" over the reporting period gives you rate of return of
|
||||||
|
your investment.
|
||||||
|
|
||||||
|
References: * Explanation of rate of return * Explanation of IRR * Ex-
|
||||||
|
planation of TWR * Examples of computing IRR and TWR and discussion of
|
||||||
|
the limitations of both metrics
|
||||||
|
|
||||||
|
More examples:
|
||||||
|
|
||||||
|
Lets say that we found an investment in Snake Oil that is proising to
|
||||||
|
give us 10% annually:
|
||||||
|
|
||||||
|
2019-01-01 Investing in Snake Oil
|
||||||
|
assets:cash -$100
|
||||||
|
investment:snake oil
|
||||||
|
|
||||||
|
2019-12-24 Recording the growth of Snake Oil
|
||||||
|
investment:snake oil = $110
|
||||||
|
equity:unrealized gains
|
||||||
|
|
||||||
|
For now, basic computation of the rate of return, as well as IRR and
|
||||||
|
TWR, gives us the expected 10%:
|
||||||
|
|
||||||
|
$ hledger roi -Y --inv investment --pnl "unrealized"
|
||||||
|
+---++------------+------------++---------------+----------+-------------+-----++--------+--------+
|
||||||
|
| || Begin | End || Value (begin) | Cashflow | Value (end) | PnL || IRR | TWR |
|
||||||
|
+===++============+============++===============+==========+=============+=====++========+========+
|
||||||
|
| 1 || 2019-01-01 | 2019-12-31 || 0 | 100 | 110 | 10 || 10.00% | 10.00% |
|
||||||
|
+---++------------+------------++---------------+----------+-------------+-----++--------+--------+
|
||||||
|
|
||||||
|
However, lets say that shorty after investing in the Snake Oil we
|
||||||
|
started to have second thoughs, so we prompty withdrew $90, leaving
|
||||||
|
only $10 in. Before Christmas, though, we started to get the "fear of
|
||||||
|
mission out", so we put the $90 back in. So for most of the year, our
|
||||||
|
investment was just $10 dollars, and it gave us just $1 in growth:
|
||||||
|
|
||||||
|
2019-01-01 Investing in Snake Oil
|
||||||
|
assets:cash -$100
|
||||||
|
investment:snake oil
|
||||||
|
|
||||||
|
2019-01-02 Buyers remorse
|
||||||
|
assets:cash $90
|
||||||
|
investment:snake oil
|
||||||
|
|
||||||
|
2019-12-30 Fear of missing out
|
||||||
|
assets:cash -$90
|
||||||
|
investment:snake oil
|
||||||
|
|
||||||
|
2019-12-31 Recording the growth of Snake Oil
|
||||||
|
investment:snake oil = $101
|
||||||
|
equity:unrealized gains
|
||||||
|
|
||||||
|
Now IRR and TWR are drastically different:
|
||||||
|
|
||||||
|
$ hledger roi -Y --inv investment --pnl "unrealized"
|
||||||
|
+---++------------+------------++---------------+----------+-------------+-----++-------+-------+
|
||||||
|
| || Begin | End || Value (begin) | Cashflow | Value (end) | PnL || IRR | TWR |
|
||||||
|
+===++============+============++===============+==========+=============+=====++=======+=======+
|
||||||
|
| 1 || 2019-01-01 | 2019-12-31 || 0 | 100 | 101 | 1 || 9.32% | 1.00% |
|
||||||
|
+---++------------+------------++---------------+----------+-------------+-----++-------+-------+
|
||||||
|
|
||||||
|
Here, IRR tells us that we made close to 10% on the $10 dollars that we
|
||||||
|
had in the account most of the time. And TWR is ... just 1%? Why?
|
||||||
|
|
||||||
|
Based on the transactions in our journal, TWR "think" that we are buy-
|
||||||
|
ing back $90 worst of Snake Oil at the same price that it had at the
|
||||||
|
beginning of they year, and then after that our $100 investment gets $1
|
||||||
|
increase in value, or 1% of $100. Let's take a closer look at what is
|
||||||
|
happening here by asking for quarterly reports instead of annual:
|
||||||
|
|
||||||
|
$ hledger roi -Q --inv investment --pnl "unrealized"
|
||||||
|
+---++------------+------------++---------------+----------+-------------+-----++--------+-------+
|
||||||
|
| || Begin | End || Value (begin) | Cashflow | Value (end) | PnL || IRR | TWR |
|
||||||
|
+===++============+============++===============+==========+=============+=====++========+=======+
|
||||||
|
| 1 || 2019-01-01 | 2019-03-31 || 0 | 10 | 10 | 0 || 0.00% | 0.00% |
|
||||||
|
| 2 || 2019-04-01 | 2019-06-30 || 10 | 0 | 10 | 0 || 0.00% | 0.00% |
|
||||||
|
| 3 || 2019-07-01 | 2019-09-30 || 10 | 0 | 10 | 0 || 0.00% | 0.00% |
|
||||||
|
| 4 || 2019-10-01 | 2019-12-31 || 10 | 90 | 101 | 1 || 37.80% | 4.03% |
|
||||||
|
+---++------------+------------++---------------+----------+-------------+-----++--------+-------+
|
||||||
|
|
||||||
|
Now both IRR and TWR are thrown off by the fact that all of the growth
|
||||||
|
for our investment happens in Q4 2019. This happes because IRR compu-
|
||||||
|
tation is still yielding 9.32% and TWR is still 1%, but this time these
|
||||||
|
are rates for three month period instead of twelve, so in order to get
|
||||||
|
an annual rate they should be multiplied by four!
|
||||||
|
|
||||||
|
Let's try to keep a better record of how Snake Oil grew in value:
|
||||||
|
|
||||||
|
2019-01-01 Investing in Snake Oil
|
||||||
|
assets:cash -$100
|
||||||
|
investment:snake oil
|
||||||
|
|
||||||
|
2019-01-02 Buyers remorse
|
||||||
|
assets:cash $90
|
||||||
|
investment:snake oil
|
||||||
|
|
||||||
|
2019-02-28 Recording the growth of Snake Oil
|
||||||
|
investment:snake oil
|
||||||
|
equity:unrealized gains -$0.25
|
||||||
|
|
||||||
|
2019-06-30 Recording the growth of Snake Oil
|
||||||
|
investment:snake oil
|
||||||
|
equity:unrealized gains -$0.25
|
||||||
|
|
||||||
|
2019-09-30 Recording the growth of Snake Oil
|
||||||
|
investment:snake oil
|
||||||
|
equity:unrealized gains -$0.25
|
||||||
|
|
||||||
|
2019-12-30 Fear of missing out
|
||||||
|
assets:cash -$90
|
||||||
|
investment:snake oil
|
||||||
|
|
||||||
|
2019-12-31 Recording the growth of Snake Oil
|
||||||
|
investment:snake oil
|
||||||
|
equity:unrealized gains -$0.25
|
||||||
|
|
||||||
|
Would our quartery report look better now? Almost:
|
||||||
|
|
||||||
|
$ hledger roi -Q --inv investment --pnl "unrealized"
|
||||||
|
+---++------------+------------++---------------+----------+-------------+------++--------+--------+
|
||||||
|
| || Begin | End || Value (begin) | Cashflow | Value (end) | PnL || IRR | TWR |
|
||||||
|
+===++============+============++===============+==========+=============+======++========+========+
|
||||||
|
| 1 || 2019-01-01 | 2019-03-31 || 0 | 10 | 10.25 | 0.25 || 9.53% | 10.53% |
|
||||||
|
| 2 || 2019-04-01 | 2019-06-30 || 10.25 | 0 | 10.50 | 0.25 || 10.15% | 10.15% |
|
||||||
|
| 3 || 2019-07-01 | 2019-09-30 || 10.50 | 0 | 10.75 | 0.25 || 9.79% | 9.78% |
|
||||||
|
| 4 || 2019-10-01 | 2019-12-31 || 10.75 | 90 | 101.00 | 0.25 || 8.05% | 1.00% |
|
||||||
|
+---++------------+------------++---------------+----------+-------------+------++--------+--------+
|
||||||
|
|
||||||
|
Something is still wrong with TWR computation for Q4, and if you have
|
||||||
|
been paying attention you know what it is already: big $90 buy-back is
|
||||||
|
recorded prior to the only transaction that captures the change of
|
||||||
|
value of Snake Oil that happened in this time period. Lets combine
|
||||||
|
transactions from 30th and 31st of Dec into one:
|
||||||
|
|
||||||
|
2019-12-30 Fear of missing out and growth of Snake Oil
|
||||||
|
assets:cash -$90
|
||||||
|
investment:snake oil
|
||||||
|
equity:unrealized gains -$0.25
|
||||||
|
|
||||||
|
Now growth of investment properly affects its price at the time of buy-
|
||||||
|
back:
|
||||||
|
|
||||||
|
$ hledger roi -Q --inv investment --pnl "unrealized"
|
||||||
|
+---++------------+------------++---------------+----------+-------------+------++--------+--------+
|
||||||
|
| || Begin | End || Value (begin) | Cashflow | Value (end) | PnL || IRR | TWR |
|
||||||
|
+===++============+============++===============+==========+=============+======++========+========+
|
||||||
|
| 1 || 2019-01-01 | 2019-03-31 || 0 | 10 | 10.25 | 0.25 || 9.53% | 10.53% |
|
||||||
|
| 2 || 2019-04-01 | 2019-06-30 || 10.25 | 0 | 10.50 | 0.25 || 10.15% | 10.15% |
|
||||||
|
| 3 || 2019-07-01 | 2019-09-30 || 10.50 | 0 | 10.75 | 0.25 || 9.79% | 9.78% |
|
||||||
|
| 4 || 2019-10-01 | 2019-12-31 || 10.75 | 90 | 101.00 | 0.25 || 8.05% | 9.57% |
|
||||||
|
+---++------------+------------++---------------+----------+-------------+------++--------+--------+
|
||||||
|
|
||||||
|
And for annual report, TWR now reports the exact profitability of our
|
||||||
|
investment:
|
||||||
|
|
||||||
|
$ hledger roi -Y --inv investment --pnl "unrealized"
|
||||||
|
+---++------------+------------++---------------+----------+-------------+------++-------+--------+
|
||||||
|
| || Begin | End || Value (begin) | Cashflow | Value (end) | PnL || IRR | TWR |
|
||||||
|
+===++============+============++===============+==========+=============+======++=======+========+
|
||||||
|
| 1 || 2019-01-01 | 2019-12-31 || 0 | 100 | 101.00 | 1.00 || 9.32% | 10.00% |
|
||||||
|
+---++------------+------------++---------------+----------+-------------+------++-------+--------+
|
||||||
|
|
||||||
stats
|
stats
|
||||||
stats
|
stats
|
||||||
Show some journal statistics.
|
Show some journal statistics.
|
||||||
|
|
||||||
The stats command displays summary information for the whole journal,
|
The stats command displays summary information for the whole journal,
|
||||||
or a matched part of it. With a reporting interval, it shows a report
|
or a matched part of it. With a reporting interval, it shows a report
|
||||||
for each report period.
|
for each report period.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
@ -3261,35 +3488,35 @@ COMMANDS
|
|||||||
Commodities : 1 ($)
|
Commodities : 1 ($)
|
||||||
Market prices : 12 ($)
|
Market prices : 12 ($)
|
||||||
|
|
||||||
This command also supports output destination and output format selec-
|
This command also supports output destination and output format selec-
|
||||||
tion.
|
tion.
|
||||||
|
|
||||||
tags
|
tags
|
||||||
tags
|
tags
|
||||||
List the unique tag names used in the journal. With a TAGREGEX argu-
|
List the unique tag names used in the journal. With a TAGREGEX argu-
|
||||||
ment, only tag names matching the regular expression (case insensitive)
|
ment, only tag names matching the regular expression (case insensitive)
|
||||||
are shown. With QUERY arguments, only transactions matching the query
|
are shown. With QUERY arguments, only transactions matching the query
|
||||||
are considered.
|
are considered.
|
||||||
|
|
||||||
With the --values flag, the tags' unique values are listed instead.
|
With the --values flag, the tags' unique values are listed instead.
|
||||||
|
|
||||||
With --parsed flag, all tags or values are shown in the order they are
|
With --parsed flag, all tags or values are shown in the order they are
|
||||||
parsed from the input data, including duplicates.
|
parsed from the input data, including duplicates.
|
||||||
|
|
||||||
With -E/--empty, any blank/empty values will also be shown, otherwise
|
With -E/--empty, any blank/empty values will also be shown, otherwise
|
||||||
they are omitted.
|
they are omitted.
|
||||||
|
|
||||||
test
|
test
|
||||||
test
|
test
|
||||||
Run built-in unit tests.
|
Run built-in unit tests.
|
||||||
|
|
||||||
This command runs the unit tests built in to hledger and hledger-lib,
|
This command runs the unit tests built in to hledger and hledger-lib,
|
||||||
printing the results on stdout. If any test fails, the exit code will
|
printing the results on stdout. If any test fails, the exit code will
|
||||||
be non-zero.
|
be non-zero.
|
||||||
|
|
||||||
This is mainly used by hledger developers, but you can also use it to
|
This is mainly used by hledger developers, but you can also use it to
|
||||||
sanity-check the installed hledger executable on your platform. All
|
sanity-check the installed hledger executable on your platform. All
|
||||||
tests are expected to pass - if you ever see a failure, please report
|
tests are expected to pass - if you ever see a failure, please report
|
||||||
as a bug!
|
as a bug!
|
||||||
|
|
||||||
This command also accepts tasty test runner options, written after a --
|
This command also accepts tasty test runner options, written after a --
|
||||||
@ -3298,35 +3525,35 @@ COMMANDS
|
|||||||
|
|
||||||
$ hledger test -- -pData.Amount --color=never
|
$ hledger test -- -pData.Amount --color=never
|
||||||
|
|
||||||
For help on these, see https://github.com/feuerbach/tasty#options (--
|
For help on these, see https://github.com/feuerbach/tasty#options (--
|
||||||
--help currently doesn't show them).
|
--help currently doesn't show them).
|
||||||
|
|
||||||
Add-on commands
|
Add-on commands
|
||||||
hledger also searches for external add-on commands, and will include
|
hledger also searches for external add-on commands, and will include
|
||||||
these in the commands list. These are programs or scripts in your PATH
|
these in the commands list. These are programs or scripts in your PATH
|
||||||
whose name starts with hledger- and ends with a recognised file exten-
|
whose name starts with hledger- and ends with a recognised file exten-
|
||||||
sion (currently: no extension, bat,com,exe, hs,lhs,pl,py,rb,rkt,sh).
|
sion (currently: no extension, bat,com,exe, hs,lhs,pl,py,rb,rkt,sh).
|
||||||
|
|
||||||
Add-ons can be invoked like any hledger command, but there are a few
|
Add-ons can be invoked like any hledger command, but there are a few
|
||||||
things to be aware of. Eg if the hledger-web add-on is installed,
|
things to be aware of. Eg if the hledger-web add-on is installed,
|
||||||
|
|
||||||
o hledger -h web shows hledger's help, while hledger web -h shows
|
o hledger -h web shows hledger's help, while hledger web -h shows
|
||||||
hledger-web's help.
|
hledger-web's help.
|
||||||
|
|
||||||
o Flags specific to the add-on must have a preceding -- to hide them
|
o Flags specific to the add-on must have a preceding -- to hide them
|
||||||
from hledger. So hledger web --serve --port 9000 will be rejected;
|
from hledger. So hledger web --serve --port 9000 will be rejected;
|
||||||
you must use hledger web -- --serve --port 9000.
|
you must use hledger web -- --serve --port 9000.
|
||||||
|
|
||||||
o You can always run add-ons directly if preferred: hledger-web --serve
|
o You can always run add-ons directly if preferred: hledger-web --serve
|
||||||
--port 9000.
|
--port 9000.
|
||||||
|
|
||||||
Add-ons are a relatively easy way to add local features or experiment
|
Add-ons are a relatively easy way to add local features or experiment
|
||||||
with new ideas. They can be written in any language, but haskell
|
with new ideas. They can be written in any language, but haskell
|
||||||
scripts have a big advantage: they can use the same hledger (and
|
scripts have a big advantage: they can use the same hledger (and
|
||||||
haskell) library functions that built-in commands do, for command-line
|
haskell) library functions that built-in commands do, for command-line
|
||||||
options, journal parsing, reporting, etc.
|
options, journal parsing, reporting, etc.
|
||||||
|
|
||||||
Two important add-ons are the hledger-ui and hledger-web user inter-
|
Two important add-ons are the hledger-ui and hledger-web user inter-
|
||||||
faces. These are maintained and released along with hledger:
|
faces. These are maintained and released along with hledger:
|
||||||
|
|
||||||
ui
|
ui
|
||||||
@ -3345,20 +3572,20 @@ COMMANDS
|
|||||||
hledger-interest generates interest transactions for an account accord-
|
hledger-interest generates interest transactions for an account accord-
|
||||||
ing to various schemes.
|
ing to various schemes.
|
||||||
|
|
||||||
A few more experimental or old add-ons can be found in hledger's bin/
|
A few more experimental or old add-ons can be found in hledger's bin/
|
||||||
directory. These are typically prototypes and not guaranteed to work.
|
directory. These are typically prototypes and not guaranteed to work.
|
||||||
|
|
||||||
ENVIRONMENT
|
ENVIRONMENT
|
||||||
LEDGER_FILE The journal file path when not specified with -f. Default:
|
LEDGER_FILE The journal file path when not specified with -f. Default:
|
||||||
~/.hledger.journal (on windows, perhaps C:/Users/USER/.hledger.jour-
|
~/.hledger.journal (on windows, perhaps C:/Users/USER/.hledger.jour-
|
||||||
nal).
|
nal).
|
||||||
|
|
||||||
A typical value is ~/DIR/YYYY.journal, where DIR is a version-con-
|
A typical value is ~/DIR/YYYY.journal, where DIR is a version-con-
|
||||||
trolled finance directory and YYYY is the current year. Or ~/DIR/cur-
|
trolled finance directory and YYYY is the current year. Or ~/DIR/cur-
|
||||||
rent.journal, where current.journal is a symbolic link to YYYY.journal.
|
rent.journal, where current.journal is a symbolic link to YYYY.journal.
|
||||||
|
|
||||||
On Mac computers, you can set this and other environment variables in a
|
On Mac computers, you can set this and other environment variables in a
|
||||||
more thorough way that also affects applications started from the GUI
|
more thorough way that also affects applications started from the GUI
|
||||||
(say, an Emacs dock icon). Eg on MacOS Catalina I have a ~/.MacOSX/en-
|
(say, an Emacs dock icon). Eg on MacOS Catalina I have a ~/.MacOSX/en-
|
||||||
vironment.plist file containing
|
vironment.plist file containing
|
||||||
|
|
||||||
@ -3368,21 +3595,21 @@ ENVIRONMENT
|
|||||||
|
|
||||||
To see the effect you may need to killall Dock, or reboot.
|
To see the effect you may need to killall Dock, or reboot.
|
||||||
|
|
||||||
COLUMNS The screen width used by the register command. Default: the
|
COLUMNS The screen width used by the register command. Default: the
|
||||||
full terminal width.
|
full terminal width.
|
||||||
|
|
||||||
NO_COLOR If this variable exists with any value, hledger will not use
|
NO_COLOR If this variable exists with any value, hledger will not use
|
||||||
ANSI color codes in terminal output. This overrides the
|
ANSI color codes in terminal output. This overrides the
|
||||||
--color/--colour option.
|
--color/--colour option.
|
||||||
|
|
||||||
FILES
|
FILES
|
||||||
Reads data from one or more files in hledger journal, timeclock, time-
|
Reads data from one or more files in hledger journal, timeclock, time-
|
||||||
dot, or CSV format specified with -f, or $LEDGER_FILE, or
|
dot, or CSV format specified with -f, or $LEDGER_FILE, or
|
||||||
$HOME/.hledger.journal (on windows, perhaps
|
$HOME/.hledger.journal (on windows, perhaps
|
||||||
C:/Users/USER/.hledger.journal).
|
C:/Users/USER/.hledger.journal).
|
||||||
|
|
||||||
LIMITATIONS
|
LIMITATIONS
|
||||||
The need to precede addon command options with -- when invoked from
|
The need to precede addon command options with -- when invoked from
|
||||||
hledger is awkward.
|
hledger is awkward.
|
||||||
|
|
||||||
When input data contains non-ascii characters, a suitable system locale
|
When input data contains non-ascii characters, a suitable system locale
|
||||||
@ -3398,36 +3625,36 @@ LIMITATIONS
|
|||||||
In a Cygwin/MSYS/Mintty window, the tab key is not supported in hledger
|
In a Cygwin/MSYS/Mintty window, the tab key is not supported in hledger
|
||||||
add.
|
add.
|
||||||
|
|
||||||
Not all of Ledger's journal file syntax is supported. See file format
|
Not all of Ledger's journal file syntax is supported. See file format
|
||||||
differences.
|
differences.
|
||||||
|
|
||||||
On large data files, hledger is slower and uses more memory than
|
On large data files, hledger is slower and uses more memory than
|
||||||
Ledger.
|
Ledger.
|
||||||
|
|
||||||
TROUBLESHOOTING
|
TROUBLESHOOTING
|
||||||
Here are some issues you might encounter when you run hledger (and re-
|
Here are some issues you might encounter when you run hledger (and re-
|
||||||
member you can also seek help from the IRC channel, mail list or bug
|
member you can also seek help from the IRC channel, mail list or bug
|
||||||
tracker):
|
tracker):
|
||||||
|
|
||||||
Successfully installed, but "No command 'hledger' found"
|
Successfully installed, but "No command 'hledger' found"
|
||||||
stack and cabal install binaries into a special directory, which should
|
stack and cabal install binaries into a special directory, which should
|
||||||
be added to your PATH environment variable. Eg on unix-like systems,
|
be added to your PATH environment variable. Eg on unix-like systems,
|
||||||
that is ~/.local/bin and ~/.cabal/bin respectively.
|
that is ~/.local/bin and ~/.cabal/bin respectively.
|
||||||
|
|
||||||
I set a custom LEDGER_FILE, but hledger is still using the default file
|
I set a custom LEDGER_FILE, but hledger is still using the default file
|
||||||
LEDGER_FILE should be a real environment variable, not just a shell
|
LEDGER_FILE should be a real environment variable, not just a shell
|
||||||
variable. The command env | grep LEDGER_FILE should show it. You may
|
variable. The command env | grep LEDGER_FILE should show it. You may
|
||||||
need to use export. Here's an explanation.
|
need to use export. Here's an explanation.
|
||||||
|
|
||||||
Getting errors like "Illegal byte sequence" or "Invalid or incomplete
|
Getting errors like "Illegal byte sequence" or "Invalid or incomplete
|
||||||
multibyte or wide character" or "commitAndReleaseBuffer: invalid argu-
|
multibyte or wide character" or "commitAndReleaseBuffer: invalid argu-
|
||||||
ment (invalid character)"
|
ment (invalid character)"
|
||||||
Programs compiled with GHC (hledger, haskell build tools, etc.) need to
|
Programs compiled with GHC (hledger, haskell build tools, etc.) need to
|
||||||
have a UTF-8-aware locale configured in the environment, otherwise they
|
have a UTF-8-aware locale configured in the environment, otherwise they
|
||||||
will fail with these kinds of errors when they encounter non-ascii
|
will fail with these kinds of errors when they encounter non-ascii
|
||||||
characters.
|
characters.
|
||||||
|
|
||||||
To fix it, set the LANG environment variable to some locale which sup-
|
To fix it, set the LANG environment variable to some locale which sup-
|
||||||
ports UTF-8. The locale you choose must be installed on your system.
|
ports UTF-8. The locale you choose must be installed on your system.
|
||||||
|
|
||||||
Here's an example of setting LANG temporarily, on Ubuntu GNU/Linux:
|
Here's an example of setting LANG temporarily, on Ubuntu GNU/Linux:
|
||||||
@ -3442,8 +3669,8 @@ TROUBLESHOOTING
|
|||||||
POSIX
|
POSIX
|
||||||
$ LANG=en_US.utf8 hledger -f my.journal print # ensure it is used for this command
|
$ LANG=en_US.utf8 hledger -f my.journal print # ensure it is used for this command
|
||||||
|
|
||||||
If available, C.UTF-8 will also work. If your preferred locale isn't
|
If available, C.UTF-8 will also work. If your preferred locale isn't
|
||||||
listed by locale -a, you might need to install it. Eg on Ubuntu/De-
|
listed by locale -a, you might need to install it. Eg on Ubuntu/De-
|
||||||
bian:
|
bian:
|
||||||
|
|
||||||
$ apt-get install language-pack-fr
|
$ apt-get install language-pack-fr
|
||||||
@ -3463,8 +3690,8 @@ TROUBLESHOOTING
|
|||||||
$ echo "export LANG=en_US.utf8" >>~/.bash_profile
|
$ echo "export LANG=en_US.utf8" >>~/.bash_profile
|
||||||
$ bash --login
|
$ bash --login
|
||||||
|
|
||||||
Exact spelling and capitalisation may be important. Note the differ-
|
Exact spelling and capitalisation may be important. Note the differ-
|
||||||
ence on MacOS (UTF-8, not utf8). Some platforms (eg ubuntu) allow
|
ence on MacOS (UTF-8, not utf8). Some platforms (eg ubuntu) allow
|
||||||
variant spellings, but others (eg macos) require it to be exact:
|
variant spellings, but others (eg macos) require it to be exact:
|
||||||
|
|
||||||
$ locale -a | grep -iE en_us.*utf
|
$ locale -a | grep -iE en_us.*utf
|
||||||
@ -3474,7 +3701,7 @@ TROUBLESHOOTING
|
|||||||
|
|
||||||
|
|
||||||
REPORTING BUGS
|
REPORTING BUGS
|
||||||
Report bugs at http://bugs.hledger.org (or on the #hledger IRC channel
|
Report bugs at http://bugs.hledger.org (or on the #hledger IRC channel
|
||||||
or hledger mail list)
|
or hledger mail list)
|
||||||
|
|
||||||
|
|
||||||
@ -3488,7 +3715,7 @@ COPYRIGHT
|
|||||||
|
|
||||||
|
|
||||||
SEE ALSO
|
SEE ALSO
|
||||||
hledger(1), hledger-ui(1), hledger-web(1), hledger-api(1),
|
hledger(1), hledger-ui(1), hledger-web(1), hledger-api(1),
|
||||||
hledger_csv(5), hledger_journal(5), hledger_timeclock(5), hledger_time-
|
hledger_csv(5), hledger_journal(5), hledger_timeclock(5), hledger_time-
|
||||||
dot(5), ledger(1)
|
dot(5), ledger(1)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user