Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Yearly ROI gives "Ratio has zero denominator", when the stock account is initially empty and the transaction has an expense or a revenue. #1833

Closed
ghost opened this issue Mar 9, 2022 · 1 comment · Fixed by #1906
Labels
A-BUG Something wrong, confusing or sub-standard in the software, docs, or user experience. roi

Comments

@ghost
Copy link

ghost commented Mar 9, 2022

hledger on macOS, installed via homebrew; latest version from brew

$> hledger --version
hledger 1.24.1, mac-x86_64

I want to track stock purchases together with potential trading fees.

Minimum example:

decimal-mark ,

commodity € 1.000,00
commodity 1.000,000 STOCK
D € 1.000,00

P 2022-01-31 STOCK € 100,00

2022/02/01 Transfer Cash
    assets:clearing account  € 101,00
    equity:etf

2022/02/01 Purchase STOCK
    assets:stocks  1 STOCK @@ € 100,00
    assets:clearing account
    expenses:fees  € 1,00

P 2022-02-28 STOCK € 101,00

Using the roi-command for the yearly ROI results in:

$> hledger -f test.journal roi --inv assets:stocks --pnl "expenses:|revenues:" -V -Y
hledger: Ratio has zero denominator

The monthly one works, though:

$> hledger -f test.journal roi --inv assets:stocks --pnl "expenses:|revenues:" -V -M --cashflow

IRR cash flow for 2022-02-01 - 2022-02-28
+------------++-----------+
|            ||    Amount |
+============++===========+
| 2022-02-01 || € -101,00 |
| 2022-03-01 ||  € 101,00 |
+------------++-----------+


TWR cash flow for 2022-02-01 - 2022-02-28
+------------++-----------------+--------------++---------+----------+------------+-------++------------------+
|            || Portfolio value | Unit balance ||     Pnl | Cashflow | Unit price | Units || New Unit Balance |
+============++=================+==============++=========+==========+============+=======++==================+
| 2022-02-01 ||               0 |            0 ||       0 | € 101,00 |        100 |  1.01 ||             1.01 |
| 2022-02-01 ||               0 |         1.01 || € -1,00 |        0 |      -0.99 |     0 ||             1.01 |
| 2022-02-28 ||             101 |         1.01 ||       0 |        0 |      -0.99 |     0 ||             1.01 |
+------------++-----------------+--------------++---------+----------+------------+-------++------------------+
Final unit price: € 101,00/1.01 units = 100
Total TWR: 0.00%.
Period: 0.08 years.
Annualized TWR: 0.00%

+---++------------+------------++---------------+----------+-------------+-----++-------+-------+
|   ||      Begin |        End || Value (begin) | Cashflow | Value (end) | PnL ||   IRR |   TWR |
+===++============+============++===============+==========+=============+=====++=======+=======+
| 1 || 2022-02-01 | 2022-02-28 ||             0 | € 101,00 |    € 101,00 |   0 || 0.00% | 0.00% |
+---++------------+------------++---------------+----------+-------------+-----++-------+-------+

I identified the issue to be caused by the assets:stocks account being empty and having expenses right in the first transaction.
Splitting the purchase as follows, makes the yearly ROI work:

2022/02/01 Purchase STOCK
    assets:stocks  1 STOCK @@ € 100,00
    assets:clearing account

2022/02/02 Purchase STOCK Fees
    assets:clearing account
    expenses:fees  € 1,00
    assets:stocks  0 STOCK

Note, that the expense has to happen on the next day. Putting it on the same day or before the purchase still results in the error.

Furthermore, the command works, if the account isn't initially empty. The following works:

decimal-mark ,

commodity € 1.000,00
commodity 1.000,000 STOCK
D € 1.000,00

P 2022-01-31 STOCK € 100,00

2022/01/31 Init
    assets:stocks  = 1 STOCK
    equity

2022/02/01 Transfer
    assets:clearing account  € 101,00
    equity:etf

2022/02/01 Purchase STOCK
    assets:stocks  1 STOCK @@ € 100,00
    assets:clearing account
    expenses:fees  € 1,00

P 2022-02-28 STOCK € 101,00
$> hledger -f test.journal roi --inv assets:stocks --pnl "expenses:|revenues:" -V -Y
+---++------------+------------++---------------+----------+-------------+-----++-------+--------+
|   ||      Begin |        End || Value (begin) | Cashflow | Value (end) | PnL ||   IRR |    TWR |
+===++============+============++===============+==========+=============+=====++=======+========+
| 1 || 2022-01-01 | 2022-12-31 ||             0 | € 202,00 |    € 202,00 |   0 || 0.00% | -0.50% |
+---++------------+------------++---------------+----------+-------------+-----++-------+--------+

The init-amount doesn't even have to be positive. Negative amounts work, too. Only the zero causes an issue here.

When looking at the cashflow with --cashflow, it seems, that the expense is always considered first and the actual cashflow last:

$> hledger -f test.journal roi --inv assets:stocks --pnl "expenses:|revenues:" -V -Y --cashflow

IRR cash flow for 2022-01-01 - 2022-12-31
+------------++-----------+
|            ||    Amount |
+============++===========+
| 2022-01-31 || € -101,00 |
| 2022-02-01 || € -101,00 |
| 2023-01-01 ||  € 202,00 |
+------------++-----------+


TWR cash flow for 2022-01-01 - 2022-12-31
+------------++-----------------+--------------++---------+----------+------------+-------++------------------+
|            || Portfolio value | Unit balance ||     Pnl | Cashflow | Unit price | Units || New Unit Balance |
+============++=================+==============++=========+==========+============+=======++==================+
| 2022-01-31 ||               0 |            0 ||       0 | € 101,00 |        100 |  1.01 ||             1.01 |
| 2022-02-01 ||             101 |         1.01 || € -1,00 |        0 |      99.01 |     0 ||             1.01 |
| 2022-02-01 ||             101 |         1.01 ||       0 | € 101,00 |      99.01 |  1.02 ||             2.03 |
| 2022-02-28 ||             202 |         2.03 ||       0 |        0 |      99.01 |     0 ||             2.03 |
+------------++-----------------+--------------++---------+----------+------------+-------++------------------+
Final unit price: € 202,00/2.03 units = 99.50
Total TWR: -0.50%.
Period: 1.00 years.
Annualized TWR: -0.50%

+---++------------+------------++---------------+----------+-------------+-----++-------+--------+
|   ||      Begin |        End || Value (begin) | Cashflow | Value (end) | PnL ||   IRR |    TWR |
+===++============+============++===============+==========+=============+=====++=======+========+
| 1 || 2022-01-01 | 2022-12-31 ||             0 | € 202,00 |    € 202,00 |   0 || 0.00% | -0.50% |
+---++------------+------------++---------------+----------+-------------+-----++-------+--------+

As stated in the title, it also happens when there's a revenue instead of or in addition to an expense.

@ghost ghost added the A-BUG Something wrong, confusing or sub-standard in the software, docs, or user experience. label Mar 9, 2022
@simonmichael
Copy link
Owner

Thanks @chvp!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-BUG Something wrong, confusing or sub-standard in the software, docs, or user experience. roi
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant