Giter Club home page Giter Club logo

beangrow's Introduction

Compute Returns

This directory contains code which computes investment returns on a variety of assets, as recorded by Beancount, fed directly from a Beancount file.

See this document for details: https://docs.google.com/document/d/1nPsMIunLnDvdsg6TSsd0PZb7jngojNpFlqnaX36WRp8/

Scripts

There are three related scripts:

  • configure.py: This attempts to automatically infer and generate configuration to compute returns from an existing Beancount ledger.

  • compute_returns.py: This extracts data for each of the investments defined in the configuration and computes the returns and generates output for each requested returns report.

  • download_prices.py: The compute_returns.py script outputs a list of missing (or inadequately dated) price directives to properly do its job as a side-product. This script can read that file and fetch those missing dates, which you can insert in your ledger and then rerun compute_returns.py for a more precise calculation.

beangrow's People

Contributors

andreasgerstmayr avatar blais avatar erpreciso avatar francocalvo avatar marcobuster avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

beangrow's Issues

Configure.py ignores closed accounts

simple.beancount

option "operating_currency" "USD"
plugin "beancount.plugins.check_commodity"
plugin "beancount.plugins.implicit_prices"

2005-01-01 commodity USD
2005-01-01 commodity AAA
2005-01-01 commodity BBB

2019-01-01 open Assets:Investments:Cash     USD
2019-01-01 open Income:Investments:Gains    USD
2019-01-01 open Assets:Investments:AAA      AAA
2019-01-01 open Assets:Investments:BBB      BBB

2019-01-01 * "Buy AAA"
  Assets:Investments:AAA                    100 AAA {100 USD}
  Assets:Investments:Cash                -10000 USD

2019-01-01 * "Buy BBB"
  Assets:Investments:BBB                    100 BBB {200 USD}
  Assets:Investments:Cash                -20000 USD

2020-01-01 * "Sell AAA"
  Assets:Investments:AAA                   -100 AAA {100 USD} @200
  Income:Investments:Gains               -10000 USD
  Assets:Investments:Cash                 20000 USD

2020-01-01 * "Sell BBB"
  Assets:Investments:BBB                   -100 BBB {200 USD} @400
  Income:Investments:Gains               -20000 USD
  Assets:Investments:Cash                 40000 USD

2019-07-01 price AAA                        150 USD
2019-07-01 price BBB                        300 USD

After running python beangrow/configure.py -v simple.beancount > conf-simple we get following conf-simple (everything is as expected)

investments {
  investment {
    currency: "AAA"
    asset_account: "Assets:Investments:AAA"
    cash_accounts: "Assets:Investments:Cash"
  }
  investment {
    currency: "BBB"
    asset_account: "Assets:Investments:BBB"
    cash_accounts: "Assets:Investments:Cash"
  }
}
groups {
  group {
    name: "currency.AAA"
    investment: "Assets:Investments:AAA"
  }
  group {
    name: "currency.BBB"
    investment: "Assets:Investments:BBB"
  }
}

But if we close account AAA (after we sold investment)

option "operating_currency" "USD"
plugin "beancount.plugins.check_commodity"
plugin "beancount.plugins.implicit_prices"

2005-01-01 commodity USD
2005-01-01 commodity AAA
2005-01-01 commodity BBB

2019-01-01 open Assets:Investments:Cash     USD
2019-01-01 open Income:Investments:Gains    USD
2019-01-01 open Assets:Investments:AAA      AAA
2020-01-01 close Assets:Investments:AAA
2019-01-01 open Assets:Investments:BBB      BBB

2019-01-01 * "Buy AAA"
  Assets:Investments:AAA                    100 AAA {100 USD}
  Assets:Investments:Cash                -10000 USD

2019-01-01 * "Buy BBB"
  Assets:Investments:BBB                    100 BBB {200 USD}
  Assets:Investments:Cash                -20000 USD

2020-01-01 * "Sell AAA"
  Assets:Investments:AAA                   -100 AAA {100 USD} @200
  Income:Investments:Gains               -10000 USD
  Assets:Investments:Cash                 20000 USD

2020-01-01 * "Sell BBB"
  Assets:Investments:BBB                   -100 BBB {200 USD} @400
  Income:Investments:Gains               -20000 USD
  Assets:Investments:Cash                 40000 USD

2019-07-01 price AAA                        150 USD
2019-07-01 price BBB                        300 USD

after running python beangrow/configure.py -v simple.beancount > conf-simple we get following conf-simple (account AAA is ignored)

investments {
  investment {
    currency: "BBB"
    asset_account: "Assets:Investments:BBB"
    cash_accounts: "Assets:Investments:Cash"
  }
}
groups {
  group {
    name: "currency.BBB"
    investment: "Assets:Investments:BBB"
  }
}

KeyError in 'beangrow/reports.py', line 459

I get the following error:

Traceback (most recent call last):
  File "../Git/beangrow/beangrow/compute_returns.py", line 105, in <module>
    main()
  File "../Git/beangrow/beangrow/compute_returns.py", line 86, in main
    pricer = reports.generate_reports(account_data_map, config,
  File "/mnt/f/Git/beangrow/beangrow/reports.py", line 459, in generate_reports
    adlist = [account_data_map[name] for name in report.investment]
  File "/mnt/f/Git/beangrow/beangrow/reports.py", line 459, in <listcomp>
    adlist = [account_data_map[name] for name in report.investment]
KeyError: 'ACCOUNT_NAME'

I can't exclude the possibility that this is something wrong with my configuration. I am happy to share the config file and my .beancount files in private.

release on pypi?

do you have intentions to release this module on pypi?

thanks

In-kind transfer issue

@redstreet

I have a case that doesn't produce the desired output: a transfer out of an account, in-kind. This gets categorized as an ASSET_OTHERASSET. I'm not sure I understand the reasoning for why this category cashflows out the cost basis of the other asset. Shouldn't it be outflowing the market value instead?

More generally, in-kind transfers (in or out) don't seem to work correctly for this reason. They only work if both source and target accounts are considered together in a group.


Source:
--------------------------------------------------------------------------------------------
option "operating_currency" "USD"
plugin "beancount.plugins.implicit_prices"

2005-01-01 commodity USD
2005-01-01 commodity HOOL

2000-01-01 open Assets:Brokerage:USD
2000-01-01 open Assets:Brokerage:HOOL "STRICT"
2000-01-01 open Assets:Zero-Sum-Accounts:Transfers "STRICT"

2020-01-01 * "Buy"
  Assets:Brokerage:HOOL 1000 HOOL {1 USD}
  Assets:Brokerage:USD

2020-10-01 price HOOL 1.1 USD

2020-10-02 * "Transfer out, in kind"
  Assets:Brokerage:HOOL   -1000 HOOL {1 USD}
  Assets:Zero-Sum-Accounts:Transfers  1000 HOOL {1 USD}

Config:
--------------------------------------------------------------------------------------------
investments {
  investment {
    currency: "HOOL"
    asset_account: "Assets:Brokerage:HOOL"
    cash_accounts: "Assets:Brokerage:USD"
    dividend_accounts: "Income:Dividends:Brokerage:HOOL"
  }
}
groups {
  group {
    name: "currency.HOOL"
    investment: "Assets:Brokerage:HOOL"
  }
}

Results:
--------------------------------------------------------------------------------------------

Desired (meaningful) output: 12% CAGR

Actual output: 0.00% (since the cashflow is -1000 for the buy, and +1000 for the transfer).

Protobuf TypeError: Descriptors cannot be created directly.

Hi, I encountered this issue:

Starting Fava on http://127.0.0.1:5000
Exception on /accounting/editor/ [GET]
Traceback (most recent call last):
  File "/usr/lib/python3.12/site-packages/flask/app.py", line 2190, in wsgi_app
    response = self.full_dispatch_request()
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/flask/app.py", line 1486, in full_dispatch_request
    rv = self.handle_user_exception(e)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/flask/app.py", line 1482, in full_dispatch_request
    rv = self.preprocess_request()
         ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/flask/app.py", line 1969, in preprocess_request
    url_func(request.endpoint, request.view_args)
  File "/usr/lib/python3.12/site-packages/fava/application.py", line 230, in _pull_beancount_file
    fava_app.config["LEDGERS"] = _ledger_slugs_dict(
                                 ^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/fava/application.py", line 107, in _ledger_slugs_dict
    for ledger in ledgers:
  File "/usr/lib/python3.12/site-packages/fava/application.py", line 231, in <genexpr>
    FavaLedger(filepath)
  File "/usr/lib/python3.12/site-packages/fava/core/__init__.py", line 265, in __init__
    self.load_file()
  File "/usr/lib/python3.12/site-packages/fava/core/__init__.py", line 292, in load_file
    self.extensions.load_file()
  File "/usr/lib/python3.12/site-packages/fava/core/extensions.py", line 42, in load_file
    extensions, errors = find_extensions(
                         ^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/fava/ext/__init__.py", line 137, in find_extensions
    module = importlib.import_module(name)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/importlib/__init__.py", line 90, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<frozen importlib._bootstrap>", line 1387, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1360, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1331, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 935, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 995, in exec_module
  File "<frozen importlib._bootstrap>", line 488, in _call_with_frames_removed
  File "/usr/lib/python3.12/site-packages/fava_portfolio_returns/__init__.py", line 19, in <module>
    from beangrow import investments  # type: ignore
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/beangrow/investments.py", line 38, in <module>
    from beangrow.config_pb2 import Config
  File "/usr/lib/python3.12/site-packages/beangrow/config_pb2.py", line 36, in <module>
    _descriptor.FieldDescriptor(
  File "/usr/lib/python3.12/site-packages/google/protobuf/descriptor.py", line 621, in __new__
    _message.Message._CheckCalledFromGeneratedFile()
TypeError: Descriptors cannot be created directly.
If this call came from a _pb2.py file, your generated code is out of date and must be regenerated with protoc >= 3.19.0.
If you cannot immediately regenerate your protos, some other possible workarounds are:
 1. Downgrade the protobuf package to 3.20.x or lower.
 2. Set PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python (but this will use pure-Python parsing and will be much slower).

More information: https://developers.google.com/protocol-buffers/docs/news/2022-05-06#python-updates
^CKeyboard interrupt received: stopping Fava

I already try to rebuild the beangrow and fava_portfolio_returns, but without success.
I had to comment out the fava_portfolio_returns plugin to access Fava.

On my system I have:

protobuf 27.1-2
    Protocol Buffers - Google's data interchange format
protobuf-c 1.5.0-3
    Protocol Buffers implementation in C
python-protobuf 27.1-2
    Python 3 bindings for Google Protocol Buffers

ValueError: cannot find context for 'fork'. (Windows)

Windows 10
Python 3.8.3

Running python beangrow/compute_returns.py b.beancount conf-returns out results in error:

Traceback (most recent call last):
  File "beangrow/compute_returns.py", line 105, in <module>
    main()
  File "beangrow/compute_returns.py", line 86, in main
    pricer = reports.generate_reports(account_data_map, config,
  File "R:\b\b-office\beangrow\reports.py", line 459, in generate_reports
    multiprocessing.set_start_method('fork')
  File "C:\Users\Btycoon\AppData\Local\Programs\Python\Python38\lib\multiprocessing\context.py", line 247, in set_start_method
    self._actual_context = self.get_context(method)
  File "C:\Users\Btycoon\AppData\Local\Programs\Python\Python38\lib\multiprocessing\context.py", line 239, in get_context
    return super().get_context(method)
  File "C:\Users\Btycoon\AppData\Local\Programs\Python\Python38\lib\multiprocessing\context.py", line 193, in get_context
    raise ValueError('cannot find context for %r' % method) from None
ValueError: cannot find context for 'fork'

Apparently caused by https://stackoverflow.com/a/46021480

Temporary fixed it by adjusting reports.py
multiprocessing.set_start_method('fork') changed to
multiprocessing.set_start_method('spawn')
(solution taken from here woven-planet/l5kit#129 (comment))

Returns: Falling commodity prices results in error

Input:

plugin "beancount.plugins.auto_accounts"
plugin "beancount.plugins.implicit_prices"

2005-01-01 commodity ABCD

2019-12-01 * "Buy"
  Assets:Investments  100 ABCD {45 USD}
  Assets:Bank

2020-01-01 price ABCD 35 USD

Config:

investments {
  investment {
    currency: "ABCD"
    asset_account: "Assets:Investments"
    cash_accounts: "Assets:Bank"
  }
}


groups {
  group {
    name: "test"
    investment: "Assets:Investments"
    }
}

Expected: negative returns rate. Observed:

beanlabs/returns/returns.py:63: RuntimeWarning: invalid value encountered in power
return np.sum(cash_flows / (1. + irr) ** years)

and 20.0% for the returns for 2019 (in index.html), showing that the solver (np.sum() call) failed.

Works fine if the price remains the same or goes up. Example:

2020-01-01 price ABCD 50 USD

[Question] Some Dividend transactions not being recognized

I'm running into a strange situation where some dividend transactions are not being recognized.

I have the following:

    investment {
        currency: "FXNAX"
        asset_account: "Assets:US:Fidelity:HSA:FXNAX"
        dividend_accounts: "Income:US:Fidelity:HSA:Dividends:FXNAX"
        cash_accounts: "Assets:US:Fidelity:HSA:Cash"
    }

    investment {
        currency: "VTI"
        asset_account: "Assets:US:Vanguard:Roth:VTI"
        dividend_accounts: "Income:US:Vanguard:Roth:Dividends:VTI"
        cash_accounts: "Assets:US:Vanguard:Roth:Cash"
    }

The tnxs look like this:

2023-02-28 * "INCOME - DIV - DIVIDEND RECEIVED"
  Assets:US:Fidelity:HSA:Cash                        41.71 USD
  Income:US:Fidelity:HSA:Dividends:FXNAX            -41.71 USD

2023-09-26 * "REINVEST - DIV - DIVIDEND REINVESTMENT"
  Assets:US:Vanguard:Roth:VTI                  0.817 VTI {212.9008 USD}
  Income:US:Vanguard:Roth:Dividends:VTI      -173.94 USD

In the HSA case, the dividend goes to cash and then is reinvested from cash. However in the Roth case, the dividend is automatically reinvested. I am importing these tnxs via OFX files from the brokerage websites. Beangrow/fava-portflio-returns shows the HSA dividends without any issue. However, the dividends from Vanguard Roth don't show up. Is there a way to handle this scenario? It would be a pain for me to manually change all the dividends -> cash and then from cash -> security purchase. Thanks.

returns of -100.0% for short durations / large return numbers

simple.beancount

option "operating_currency" "USD"
plugin "beancount.plugins.check_commodity"
plugin "beancount.plugins.implicit_prices"

2005-01-01 commodity USD
2005-01-01 commodity AAA

2019-01-01 open Assets:Investments:Cash     USD
2019-01-01 open Expenses:Investing:Fees     USD
2019-01-01 open Income:Investments:Gains    USD
2019-01-01 open Assets:Investments:AAA      AAA

2019-03-18 * "Buy AAA"
  Assets:Investments:AAA                    250 AAA {39.75 USD, 2019-03-18}
  Assets:Investments:Cash              -9937.50 USD

2019-03-20 * "Sell AAA"
  Assets:Investments:AAA                   -250 AAA {39.75 USD, 2019-03-18} @ 41.95 USD
  Expenses:Investing:Fees                  0.23 USD
  Income:Investments:Gains                 -550 USD
  Assets:Investments:Cash              10487.27 USD

conf-simple

investments {
  investment {
    currency: "AAA"
    asset_account: "Assets:Investments:AAA"
    cash_accounts: "Assets:Investments:Cash"
  }
}
groups {
  group {
    name: "currency.AAA"
    investment: "Assets:Investments:AAA"
  }
}

result
1_preFix
2019's return shown as 20%, X_years_ago returns shown as = -100%

result with fix of issue 4 of #4 (comment)
2_afterFix
all returns shown as -100%

The correct return is ~1852657.75%

I am not sure

  • if script crashes/fails to calculate the number
  • or if it simply can't display the number in return table cause it is such a large number

And though such a large return number is meaningless and not sustainable current outputs are deceptive, i think displaying order of magnitude 10^6% will be more appropriate.
(similarly if it's -1852657.75% then -10^6%)

Commodity Definition for base currency confuses compute_returns.py

In my beancount file I have this;

1999-12-31 commodity USD
  export: "CASH"
  name: "United States Dollar"

It causes configure.py to produce

  investment {
    currency: "USD"
    asset_account: "Assets:Coinbase:USD"
    cash_accounts: "Assets::Checking"
  }

This in turn confuses compute returns.py during generate_price_pages because it causes a CurrencyPair to exist ('USD', 'USD'):

$ beangrow/beangrow/compute_returns.py xxxxx.beancount config beangrow_output

Traceback (most recent call last):
  File "beangrow/beangrow/compute_returns.py", line 105, in <module>
    main()
  File "beangrow/beangrow/compute_returns.py", line 94, in main
    reports.generate_price_pages(account_data_map,
  File "xxxxx/beangrow/beangrow/reports.py", line 529, in generate_price_pages
    all_prices = prices.get_all_prices(price_map, base_quote)
  File "/usr/local/lib/python3.8/dist-packages/beancount/core/prices.py", line 197, in get_all_prices
    return _lookup_price_and_inverse(price_map, base_quote)
  File "/usr/local/lib/python3.8/dist-packages/beancount/core/prices.py", line 172, in _lookup_price_and_inverse
    return price_map[base_quote]
KeyError: ('USD', 'USD')

compute_returns.py particially ignores -e END_DATE directive

simple.beancount

plugin "beancount.plugins.auto_accounts"
plugin "beancount.plugins.implicit_prices"

2005-01-01 commodity AAA

2021-07-12 * "Buy; AAA"
  Assets:Investing:CSchwab:AAA            579 AAA {68.82 USD, 2021-07-12}
  Assets:Investing:CSchwab:Cash     -39846.78 USD

2021-08-01 price AAA                    61.32 USD
2021-09-01 price AAA                    64.56 USD

conf-simple

investments {
  investment {
    currency: "AAA"
    asset_account: "Assets:Investing:CSchwab:AAA"
    cash_accounts: "Assets:Investing:CSchwab:Cash"
  }
}
groups {
  group {
    name: "AAA"
    investment: "Assets:Investing:CSchwab:AAA"
  }
}

executing compute_returns.py -e 2021-09-01 simple.beancount conf-simple simple we get
e-2019-09-01
Top left box returns (-36.70) and Cash flows date (2021-09-01) are using cut off date as expected.

But last year return (2021) and rolling returns are calculating using date on which command is executed, which is not intuitive.

Plus it makes beangrow require price points counted from day of execution of command which are shown in prices.beancount (2021-09-15, 2021-06-15, etc) which you need to put into your beancount file. And this DAY part of date will always vary. (unless you can always run your command on same day each month) It makes things a bit untidy.

If one makes the rule that his beancount should contain prices for commodities on 1st of each month
2021-07-01, 2021-08-01, 2021-0901, etc then by having fully functional -e 2021-XX-01 you will not see new dates in prices.beancount and won't need to update your main beancount file.

Crash due to complex rate of return when investment value goes down.

When the price goes down post investment, beangrow crashes with complex type error (sum of real and complex).

An investment that has the price drop after acquisition results in a complex rate of return that cannot be summed.

Removing the 9.00 USD Price on line 22 stops the crash.

Output:

INFO    : Reading ledger: bug.bean
INFO    : Processing account: Assets:US:Investments:XYZ
INFO    : Writing details file: bug-returns/investments/Assets_US_Investments_XYZ.org
INFO    : Writing returns dir for currency.XYZ: bug-returns/groups/currency.XYZ
DEBUG   : top of Axes not in the figure, so title not moved
DEBUG   : top of Axes not in the figure, so title not moved
Traceback (most recent call last):
  File ".../scm/gh/beangrow/beangrow/compute_returns.py", line 105, in <module>
    main()
  File ".../scm/gh/beangrow/beangrow/compute_returns.py", line 86, in main
    pricer = reports.generate_reports(account_data_map, config,
  File ".../scm/gh/beangrow/beangrow/reports.py", line 551, in generate_reports
    func()
  File ".../scm/gh/beangrow/beangrow/reports.py", line 218, in write_returns_html
    plots = plot_flows(
  File ".../scm/gh/beangrow/beangrow/reports.py", line 415, in plot_flows
    gamounts[-remaining_days:] += gflow
numpy.core._exceptions._UFuncOutputCastingError: Cannot cast ufunc 'add' output from dtype('complex128') to dtype('float64') with casting rule 'same_kind'

Version:

Beancount 2.3.4 (git:0003608e; 2021-12-05)

==> bug.bean <==

; -*- mode: beancount; fill-column: 9999; -*-

2000-01-01 commodity USD
2000-01-01 commodity XYZ

2000-01-01 open Equity:Opening-Balances
2000-01-01 open Assets:US:Investments:XYZ XYZ
2000-01-01 open Assets:US:Investments:Cash USD

2022-02-07 price XYZ               9.950 USD

2022-01-01 * "Opening"
  Equity:Opening-Balances     -10,000.00 USD
  Assets:US:Investments:Cash  10,000.000 USD

2022-02-10 * " Make Investment"
  Assets:US:Investments:XYZ         1000 XYZ { 10.00 USD, 2022-02-10 }
  Assets:US:Investments:Cash  -10,000.00 USD
  closing: TRUE

; Change this to > 10.00 USD and it will not crash.
2022-02-14 price XYZ                9.00 USD

2022-02-28 price XYZ               11.00 USD

==> bug.conf <==

investments {
  investment {
    currency: "XYZ"
    asset_account: "Assets:US:Investments:XYZ"
    cash_accounts: "Assets:US:Investments:Cash"
  }
}
groups {
  group {
    name: "currency.XYZ"
    investment: "Assets:US:Investments:XYZ"
  }
}

Bean Report Print output:

; - bean-report bug.bean print
2000-01-01 open Equity:Opening-Balances
2000-01-01 open Assets:US:Investments:XYZ                       XYZ
2000-01-01 open Assets:US:Investments:Cash                      USD

2000-01-01 commodity USD

2000-01-01 commodity XYZ

2022-01-01 * "Opening"
  Equity:Opening-Balances     -10000.00 USD
  Assets:US:Investments:Cash  10000.000 USD

2022-02-07 price XYZ                                 9.950 USD

2022-02-10 * " Make Investment"
  Assets:US:Investments:XYZ        1000 XYZ {10.00 USD, 2022-02-10}
  Assets:US:Investments:Cash  -10000.00 USD
    closing: TRUE

2022-02-14 price XYZ                                  9.00 USD
2022-02-28 price XYZ                                 11.00 USD

SVG doesn't display

For some reason the SVG files do not load in the browser via index.html for any of the group reports. I have tried Chrome, Edge, and Internet Explorer. I can open the SVG files individually in all 3 of those browsers with no issue, but they stubbornly don't want to load via the html. I'm on a Windows machine if that matters.

Returns: add new option to make verification easier: --configured-accounts-only

From this doc: After building a basic config file and perhaps making a few simple changes to your ledger, compute_returns.py spits out numbers. How can the correctness of these numbers be verified?

Something that has been tripping me up a lot: an underspecified config. For example:

investment {
  currency "ABCD"
  asset_account: "Assets:Investments:ABCD"
  cash_accounts: "Assets:BankOrange"
  dividend_accounts: "Income:Diidends:ABCD"   ; <-- spelling error causes silent underspecification, and incorrect results
  dividend_accounts: "Income:Interest:ABCD"   ; <-- If I forget to include this line, postings with it are silently ignored
}

The problem is, these are all silent failures unless one examines investments/*.org in the output, of which I have tons, too many to manually inspect.

A --configured-accounts-only would work only if all accounts found in all relevant postings are specified in the config. It could further list all the unspecified accounts. Even better, it could auto-generate a new config with them with a comment for the user to complete specifying them.

get_commodity_directives or get_commodity_map

I tried to use "compute_returns.py" as suggested by the official manual "Beancount - Calculating Portfolio Returns", but failed due to empty return of "get_commodity_directives" in "investments.py". I checked online docs but find only the "get_commodity_map" function which is suggested to appear in getters.py, but it is not the case in the getters.py in my beancount directory. Any suggestion?

License

Hi Martin,
could you please add a license to this repository?

Thanks!

Contributing Dietz method

Hey!
I've been playing with the code for a while.

First, I packaged it with Poetry and Nix. It should be easy to release it to PyPi.
Secondly, using most of the logic from the current code, I changed the compute_irr for compute_dietz. There are some changes around the code on how the truncate works, but otherwise it's pretty much unchanged.

Would you be interested in a PR for any of those things? It would be cool to have both the time and money weighted performance. It would also allow to add benchmarking.

Error message in Beancount 2.3.3

Martin,

When i try to run the code, i'm getting the below error message in Beancount 2.3.3... I can send you the ledger file privately, if you mail me.

$:~/beancount/beangrow-master/beangrow$ python compute_returns.py ~prabu/beancount/prabu/prabu2021_02_20.beancount config.pbtxt return_reports
/home/prabu/beancount/beangrow-master/beangrow/returns.py:63: RuntimeWarning: invalid value encountered in power
return np.sum(cash_flows / (1. + irr) ** years)
/home/prabu/beancount/beangrow-master/beangrow/returns.py:63: RuntimeWarning: invalid value encountered in power
return np.sum(cash_flows / (1. + irr) ** years)
/home/prabu/beancount/beangrow-master/beangrow/returns.py:63: RuntimeWarning: invalid value encountered in power
return np.sum(cash_flows / (1. + irr) ** years)
Traceback (most recent call last):
File "compute_returns.py", line 105, in
main()
File "compute_returns.py", line 100, in main
reports.write_price_directives(path.join(output_prices, "prices.beancount"),
File "/home/prabu/beancount/beangrow-master/beangrow/reports.py", line 406, in write_price_directives
days_late = (required_date - actual_date).days
TypeError: unsupported operand type(s) for -: 'datetime.date' and 'NoneType'

Here is the verbose output
prabu@homepc-lm:~/beancount/beangrow-master/beangrow$ python compute_returns.py ~prabu/beancount/prabu/prabu2021_02_20.beancount config.pbtxt return_reports -v
INFO : Reading ledger: /home/prabu/beancount/prabu/prabu2021_02_20.beancount
INFO : Processing account: Assets:TH:Investment:KGI:INTUCH-R
INFO : Processing account: Assets:US:Investment:ETrade:BP
INFO : Processing account: Assets:US:Investment:ETrade:CVX
INFO : Processing account: Assets:US:Investment:ETrade:EQIX
INFO : Processing account: Assets:US:Investment:ETrade:IXC
INFO : Processing account: Assets:US:Investment:ETrade:TOT
INFO : Processing account: Assets:US:Investment:ETrade:RDS-B
INFO : Processing account: Assets:US:Investment:ETrade:XLE
INFO : Processing account: Assets:US:Investment:ETrade:XOM
INFO : Writing details file: return_reports/investments/Assets_TH_Investment_KGI_INTUCH-R.org
INFO : Writing details file: return_reports/investments/Assets_US_Investment_ETrade_BP.org
INFO : Writing details file: return_reports/investments/Assets_US_Investment_ETrade_CVX.org
INFO : Writing details file: return_reports/investments/Assets_US_Investment_ETrade_EQIX.org
INFO : Writing details file: return_reports/investments/Assets_US_Investment_ETrade_IXC.org
INFO : Writing details file: return_reports/investments/Assets_US_Investment_ETrade_TOT.org
INFO : Writing details file: return_reports/investments/Assets_US_Investment_ETrade_RDS-B.org
INFO : Writing details file: return_reports/investments/Assets_US_Investment_ETrade_XLE.org
INFO : Writing details file: return_reports/investments/Assets_US_Investment_ETrade_XOM.org
INFO : Writing returns dir for strategy:GlobalEnergy: return_reports/groups/strategy:GlobalEnergy
DEBUG : top of axes not in the figure, so title not moved
DEBUG : top of axes not in the figure, so title not moved
/home/prabu/beancount/beangrow-master/beangrow/returns.py:63: RuntimeWarning: invalid value encountered in power
return np.sum(cash_flows / (1. + irr) ** years)
INFO : Writing returns dir for strategy:GlobalEnergy: return_reports/groups/strategy:GlobalEnergy.org
INFO : Writing returns dir for currency.EQIX: return_reports/groups/currency.EQIX
DEBUG : top of axes not in the figure, so title not moved
DEBUG : top of axes not in the figure, so title not moved
/home/prabu/beancount/beangrow-master/beangrow/returns.py:63: RuntimeWarning: invalid value encountered in power
return np.sum(cash_flows / (1. + irr) ** years)
INFO : Writing returns dir for currency.EQIX: return_reports/groups/currency.EQIX.org
INFO : Writing returns dir for Thailand.Intuch: return_reports/groups/Thailand.Intuch
DEBUG : top of axes not in the figure, so title not moved
DEBUG : top of axes not in the figure, so title not moved
/home/prabu/beancount/beangrow-master/beangrow/returns.py:63: RuntimeWarning: invalid value encountered in power
return np.sum(cash_flows / (1. + irr) ** years)
INFO : Writing returns dir for Thailand.Intuch: return_reports/groups/Thailand.Intuch.org
INFO : Producing price page for ('BP', 'USD')
INFO : Producing price page for ('CVX', 'USD')
INFO : Producing price page for ('EQIX', 'USD')
INFO : Producing price page for ('INTUCH-R', 'THB')
INFO : Producing price page for ('IXC', 'USD')
INFO : Producing price page for ('RDS-B', 'USD')
INFO : Producing price page for ('TOT', 'USD')
INFO : Producing price page for ('XLE', 'USD')
INFO : Producing price page for ('XOM', 'USD')
Traceback (most recent call last):
File "compute_returns.py", line 105, in
main()
File "compute_returns.py", line 100, in main
reports.write_price_directives(path.join(output_prices, "prices.beancount"),
File "/home/prabu/beancount/beangrow-master/beangrow/reports.py", line 406, in write_price_directives
days_late = (required_date - actual_date).days
TypeError: unsupported operand type(s) for -: 'datetime.date' and 'NoneType'

Returns: In-kind transfers are not supported

plugin "beancount.plugins.auto_accounts"
plugin "beancount.plugins.implicit_prices"
2005-01-01 commodity ABCD

2019-12-01 * "Buy"
  Assets:Investments  100 ABCD {45 USD}
  Assets:Bank

2020-02-20 * "Transfer"
  Assets:Investments  -50 ABCD {45 USD}
  Assets:Bank          50 ABCD {45 USD}
investments {
  investment {
    currency: "ABCD"
    asset_account: "Assets:Investments"
    cash_accounts: "Assets:Bank"
  }
}


groups {
  group {
    name: "test"
    investment: "Assets:Investments"
    }
}

Expected: transfer out in-kind should cause a positive cashflow. It is similar to a sale. Observed:

Traceback (most recent call last):
  File "beanlabs/beanlabs/returns/compute_returns.py", line 105, in <module>
    main()
  File "beanlabs/beanlabs/returns/compute_returns.py", line 82, in main
    path.join(args.output, "investments"))
  File "beanlabs/beanlabs/returns/investments.py", line 555, in extract
    for aconfig in config.investments.investment]
  File "beanlabs/beanlabs/returns/investments.py", line 555, in <listcomp>
    for aconfig in config.investments.investment]
  File "beanlabs/beanlabs/returns/investments.py", line 376, in process_account_entries
    flows_general = produce_cash_flows_general(entry, account)
  File "beanlabs/beanlabs/returns/investments.py", line 178, in produce_cash_flows_general
    assert not posting.cost
AssertionError

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.