;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 | ||||
| to identify your profit and loss transactions with \f[C]--pnl\f[R]. | ||||
| .PP | ||||
| It will compute and display the internalized rate of return (IRR) and | ||||
| time-weighted rate of return (TWR) for your investments for the time | ||||
| period requested. | ||||
| This command will compute and display the internalized rate of return | ||||
| (IRR) and time-weighted rate of return (TWR) for your investments for | ||||
| the time period requested. | ||||
| Both rates of return are annualized before display, regardless of the | ||||
| length of reporting interval. | ||||
| .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 | ||||
| .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 | ||||
| .PP | ||||
| stats | ||||
|  | ||||
| @ -3798,13 +3798,238 @@ your investments or withdrawals. | ||||
| account name) to select your investments with '--inv', and another query | ||||
| to identify your profit and loss transactions with '--pnl'. | ||||
| 
 | ||||
|    It will compute and display the internalized rate of return (IRR) and | ||||
| time-weighted rate of return (TWR) for your investments for the time | ||||
| period requested.  Both rates of return are annualized before display, | ||||
| regardless of the length of reporting interval. | ||||
|    This command will compute and display the internalized rate of return | ||||
| (IRR) and time-weighted rate of return (TWR) for your investments for | ||||
| the time period requested.  Both rates of return are annualized before | ||||
| display, regardless of the length of reporting interval. | ||||
| 
 | ||||
|    An example: | ||||
| https://github.com/simonmichael/hledger/blob/master/examples/roi-unrealised.ledger | ||||
|    Note, in some cases this report can fail, for these reasons: | ||||
| 
 | ||||
|    * 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 | ||||
| @ -4290,30 +4515,30 @@ Node: rewrite vs print --auto133861 | ||||
| Ref: #rewrite-vs.-print---auto134040 | ||||
| Node: roi134596 | ||||
| Ref: #roi134694 | ||||
| Node: stats135805 | ||||
| Ref: #stats135904 | ||||
| Node: tags136692 | ||||
| Ref: #tags136790 | ||||
| Node: test137309 | ||||
| Ref: #test137417 | ||||
| Node: Add-on commands138164 | ||||
| Ref: #add-on-commands138281 | ||||
| Node: ui139624 | ||||
| Ref: #ui139712 | ||||
| Node: web139766 | ||||
| Ref: #web139869 | ||||
| Node: iadd139985 | ||||
| Ref: #iadd140096 | ||||
| Node: interest140178 | ||||
| Ref: #interest140285 | ||||
| Node: ENVIRONMENT140525 | ||||
| Ref: #environment140637 | ||||
| Node: FILES141622 | ||||
| Ref: #files-1141725 | ||||
| Node: LIMITATIONS141938 | ||||
| Ref: #limitations142057 | ||||
| Node: TROUBLESHOOTING142799 | ||||
| Ref: #troubleshooting142912 | ||||
| Node: stats146904 | ||||
| Ref: #stats147003 | ||||
| Node: tags147791 | ||||
| Ref: #tags147889 | ||||
| Node: test148408 | ||||
| Ref: #test148516 | ||||
| Node: Add-on commands149263 | ||||
| Ref: #add-on-commands149380 | ||||
| Node: ui150723 | ||||
| Ref: #ui150811 | ||||
| Node: web150865 | ||||
| Ref: #web150968 | ||||
| Node: iadd151084 | ||||
| Ref: #iadd151195 | ||||
| Node: interest151277 | ||||
| Ref: #interest151384 | ||||
| Node: ENVIRONMENT151624 | ||||
| Ref: #environment151736 | ||||
| Node: FILES152721 | ||||
| Ref: #files-1152824 | ||||
| Node: LIMITATIONS153037 | ||||
| Ref: #limitations153156 | ||||
| Node: TROUBLESHOOTING153898 | ||||
| Ref: #troubleshooting154011 | ||||
|  | ||||
| End Tag Table | ||||
| 
 | ||||
|  | ||||
| @ -3230,20 +3230,247 @@ COMMANDS | ||||
|        count name) to select your investments with --inv, and another query to | ||||
|        identify your profit and loss transactions with --pnl. | ||||
| 
 | ||||
|        It  will  compute and display the internalized rate of return (IRR) and | ||||
|        time-weighted rate of return (TWR) for your investments  for  the  time | ||||
|        period  requested.  Both rates of return are annualized before display, | ||||
|        regardless of the length of reporting interval. | ||||
|        This  command  will compute and display the internalized rate of return | ||||
|        (IRR) and time-weighted rate of return (TWR) for your  investments  for | ||||
|        the  time period requested.  Both rates of return are annualized before | ||||
|        display, regardless of the length of reporting interval. | ||||
| 
 | ||||
|        An  example:  https://github.com/simonmichael/hledger/blob/master/exam- | ||||
|        ples/roi-unrealised.ledger | ||||
|        Note, in some cases this report can fail, for these reasons: | ||||
| 
 | ||||
|        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 | ||||
|        Show some journal statistics. | ||||
| 
 | ||||
|        The  stats  command displays summary information for the whole journal, | ||||
|        or a matched part of it.  With a reporting interval, it shows a  report | ||||
|        The stats command displays summary information for the  whole  journal, | ||||
|        or  a matched part of it.  With a reporting interval, it shows a report | ||||
|        for each report period. | ||||
| 
 | ||||
|        Example: | ||||
| @ -3261,35 +3488,35 @@ COMMANDS | ||||
|               Commodities              : 1 ($) | ||||
|               Market prices            : 12 ($) | ||||
| 
 | ||||
|        This  command also supports output destination and output format selec- | ||||
|        This command also supports output destination and output format  selec- | ||||
|        tion. | ||||
| 
 | ||||
|    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) | ||||
|        are shown.  With QUERY arguments, only transactions matching the  query | ||||
|        are  shown.  With QUERY arguments, only transactions matching the query | ||||
|        are considered. | ||||
| 
 | ||||
|        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. | ||||
| 
 | ||||
|        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. | ||||
| 
 | ||||
|    test | ||||
|        test | ||||
|        Run built-in unit tests. | ||||
| 
 | ||||
|        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 | ||||
|        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 | ||||
|        be non-zero. | ||||
| 
 | ||||
|        This  is  mainly used by hledger developers, but you can also use it to | ||||
|        sanity-check the installed hledger executable on  your  platform.   All | ||||
|        tests  are  expected to pass - if you ever see a failure, please report | ||||
|        This is mainly used by hledger developers, but you can also use  it  to | ||||
|        sanity-check  the  installed  hledger executable on your platform.  All | ||||
|        tests are expected to pass - if you ever see a failure,  please  report | ||||
|        as a bug! | ||||
| 
 | ||||
|        This command also accepts tasty test runner options, written after a -- | ||||
| @ -3298,35 +3525,35 @@ COMMANDS | ||||
| 
 | ||||
|               $ 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). | ||||
| 
 | ||||
|    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 | ||||
|        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). | ||||
| 
 | ||||
|        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, | ||||
| 
 | ||||
|        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. | ||||
| 
 | ||||
|        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; | ||||
|        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; | ||||
|          you must use hledger web -- --serve --port 9000. | ||||
| 
 | ||||
|        o You can always run add-ons directly if preferred: hledger-web --serve | ||||
|          --port 9000. | ||||
| 
 | ||||
|        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 | ||||
|        scripts  have  a  big  advantage:  they  can  use the same hledger (and | ||||
|        haskell) library functions that built-in commands do, for  command-line | ||||
|        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 | ||||
|        scripts have a big advantage:  they  can  use  the  same  hledger  (and | ||||
|        haskell)  library functions that built-in commands do, for command-line | ||||
|        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: | ||||
| 
 | ||||
|    ui | ||||
| @ -3345,20 +3572,20 @@ COMMANDS | ||||
|        hledger-interest generates interest transactions for an account accord- | ||||
|        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. | ||||
| 
 | ||||
| ENVIRONMENT | ||||
|        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). | ||||
| 
 | ||||
|        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- | ||||
|        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- | ||||
|        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 | ||||
|        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- | ||||
|        vironment.plist file containing | ||||
| 
 | ||||
| @ -3368,21 +3595,21 @@ ENVIRONMENT | ||||
| 
 | ||||
|        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. | ||||
| 
 | ||||
|        NO_COLOR  If  this variable exists with any value, hledger will not use | ||||
|        ANSI  color   codes   in   terminal   output.    This   overrides   the | ||||
|        NO_COLOR If this variable exists with any value, hledger will  not  use | ||||
|        ANSI   color   codes   in   terminal   output.    This   overrides  the | ||||
|        --color/--colour option. | ||||
| 
 | ||||
| FILES | ||||
|        Reads  data from one or more files in hledger journal, timeclock, time- | ||||
|        dot,  or  CSV  format  specified   with   -f,   or   $LEDGER_FILE,   or | ||||
|        $HOME/.hledger.journal           (on          windows,          perhaps | ||||
|        Reads data from one or more files in hledger journal, timeclock,  time- | ||||
|        dot,   or   CSV   format   specified   with  -f,  or  $LEDGER_FILE,  or | ||||
|        $HOME/.hledger.journal          (on          windows,           perhaps | ||||
|        C:/Users/USER/.hledger.journal). | ||||
| 
 | ||||
| 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. | ||||
| 
 | ||||
|        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 | ||||
|        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. | ||||
| 
 | ||||
|        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. | ||||
| 
 | ||||
| TROUBLESHOOTING | ||||
|        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 | ||||
|        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 | ||||
|        tracker): | ||||
| 
 | ||||
|        Successfully installed, but "No command 'hledger' found" | ||||
|        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. | ||||
| 
 | ||||
|        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 | ||||
|        variable.   The command env | grep LEDGER_FILE should show it.  You may | ||||
|        LEDGER_FILE  should  be  a  real environment variable, not just a shell | ||||
|        variable.  The command env | grep LEDGER_FILE should show it.  You  may | ||||
|        need to use export.  Here's an explanation. | ||||
| 
 | ||||
|        Getting errors like "Illegal byte sequence" or "Invalid  or  incomplete | ||||
|        multibyte  or wide character" or "commitAndReleaseBuffer: invalid argu- | ||||
|        Getting  errors  like "Illegal byte sequence" or "Invalid or incomplete | ||||
|        multibyte or wide character" or "commitAndReleaseBuffer: invalid  argu- | ||||
|        ment (invalid character)" | ||||
|        Programs compiled with GHC (hledger, haskell build tools, etc.) need to | ||||
|        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. | ||||
| 
 | ||||
|        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. | ||||
| 
 | ||||
|        Here's an example of setting LANG temporarily, on Ubuntu GNU/Linux: | ||||
| @ -3442,8 +3669,8 @@ TROUBLESHOOTING | ||||
|               POSIX | ||||
|               $ 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 | ||||
|        listed  by  locale  -a, you might need to install it.  Eg on Ubuntu/De- | ||||
|        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- | ||||
|        bian: | ||||
| 
 | ||||
|               $ apt-get install language-pack-fr | ||||
| @ -3463,8 +3690,8 @@ TROUBLESHOOTING | ||||
|               $ echo "export LANG=en_US.utf8" >>~/.bash_profile | ||||
|               $ bash --login | ||||
| 
 | ||||
|        Exact spelling and capitalisation may be important.  Note  the  differ- | ||||
|        ence  on  MacOS  (UTF-8,  not  utf8).  Some platforms (eg ubuntu) allow | ||||
|        Exact  spelling  and capitalisation may be important.  Note the differ- | ||||
|        ence on MacOS (UTF-8, not utf8).   Some  platforms  (eg  ubuntu)  allow | ||||
|        variant spellings, but others (eg macos) require it to be exact: | ||||
| 
 | ||||
|               $ locale -a | grep -iE en_us.*utf | ||||
| @ -3474,7 +3701,7 @@ TROUBLESHOOTING | ||||
| 
 | ||||
| 
 | ||||
| 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) | ||||
| 
 | ||||
| 
 | ||||
| @ -3488,7 +3715,7 @@ COPYRIGHT | ||||
| 
 | ||||
| 
 | ||||
| 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- | ||||
|        dot(5), ledger(1) | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user