;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