Skip to content

Latest commit

 

History

History
4404 lines (2912 loc) · 167 KB

File metadata and controls

4404 lines (2912 loc) · 167 KB

-*- mode: org -*- beancount: TODO

Event

  • Should we validate that the query is legit before we even run it? I think so. Compile after parsing.

Booking

,-------------------------------------------------------------------------------- Quandry: booking has to be moved from a validation-only stage, because the looser interpolation will allow algorithms to select the lots, which in turn decides which cost basis is used to balance the transaction. This is unfortunate, because it was nice to separate this stage entirely.

At the same time, post-parsing transaction generation (e.g., by plugins) is allowed… which means that we need to be able to book after parsing, after running the plugins.

This implies that we need to support some sort of incomplete, intermediate state for postings.

Balancing incomplete postings now also has to occur in a second stage, not at parsing time (balance_incomplete_postings()), at least some of the time, because the interpolation may depend on the automatic lot selection.

This creates some interesting and difficult changes. `--------------------------------------------------------------------------------

  • Parsing will now always return incomplete entries, and all the tests have to be adapted to reflect this new fact.
    • Remove booking hacks everywhere; only the loader should perform booking.
    • Remove the beancount.ops.documents plugin, or perhaps make the loader operate in a raw mode, e.g. not running any plugins.

    egrep –include=’*.py’ -srn ‘parse_(string|file)’ /home/blais/p/beancount/src/python/beancount

  • Write test for beancount.parser.booking.
  • Merge beancount.core.interpolate into booking.
  • Merge beancount.ops.validation.validate_inventory_booking() into booking.
  • This causes a problem because a tag is parsed in ‘#9.95’: 10 AAPL {45.23#9.95 USD}
  • (Annoyance) Make interpolation.balance_incomplete_postings() return a new object and not work destructively. No reason not to.
  • (Annoyance) All functions that return an (entries, errors, options_map) triple really should return (entries, options_map, errors), in this order.
  • Create a b.c.data.transactions_only() function to this common type of filtering and grep/replace everywhere. This is just too common not to create a utility.

Requirements for Shipping 2.0

File Cleanup

  • Remove plugins from ops, remove algorithms from core:

    (Also remove “documents” option and move that as input to this plugin.) b.ops.documents -> b.plugins.documents (not sure if breaks)

    b.core.getters -> b.ops.getters (does it add deps?) b.core.realization -> b.ops.realization (does it add deps?)

  • Define a C extension module to implement D(). This function should catch useless errors from the cdecimal library: Declined: [<class ‘decimal.ConversionSyntax’>] and always provide the input string so we can debug WTF happened.

Explicit Tolerance

  • Make the printer support explicit tolerance syntax. This is crucial for round-trip.

Metadata and Experiment Flags Registry

  • Create a registry of all metadata fields being used in the system, with

    documentation for each, so that it does not end up becoming a mess.

  • Ditto for experiment flags. These should be documented in a single place as well. This is all easy.

    Also: Fail if the experiment flag is not a supported one.

  • Document experiments as well, and how to list the available ones (bean-doctor should be able to do this from the registry).

Priorities

Notes

  • Move out the price fetch to src/python/beanprice module, should be independent from LedgerHub and it should just work, remove script.
  • Complete documenting taxes (this is a great time for it)
  • Implement CSV output for bean-query (redstreet)
  • Implement queries on metadata fields (for portfolio analysis aggregations)
  • Implement the dashboard on the example file, take the code out of my private code stash and share.
  • Convert example file to use beancount.plugins.ira_contribs plugin.
  • Change name of IRAUSD to 401KUSD or USD401K
  • Complete double-entry introduction document & presentation
  • Fetch missing prices for my ledger file and recompute returns.
  • Returns calculation should spit out missing prices. Automate returns calculation.
  • Write a wash sales calculation code that can input from either a Beancount input file or a spreadsheet.
  • Limbo accounts: Start a document on handling limbo accounts, summarize all info from emails.
  • Complete text-statements to text for bean-report and ELI, complete with –date on those reports.
  • Export “net worth over time” project.

(booking)

  • Change booking to always have lot-date and list trades automatically.
  • Report trades, all bookings should be findable after the fact using a link. This can be added without doing full booking.

(query)

  • Implement implitict GROUP BY and BALANCES … WHERE syntax
  • Implement output format options (esp. CSV for spreadsheets).

(documentation)

  • Slide: 4 methods: bean-web, bean-report, bean-query, write script + plugin

Establish Display Precision

  • Create a page in the web view that lists the various precision - by example - inferred in the global DisplayContext.
  • Make setting the precision from bean-example easier (provide a method to create that format and update without conversion on the DisplayContext itself).
  • In the DisplayContext, implement caching of the formatters created to increase speed, especially for printing a single entry repeatedly.
  • Implement reserved number of digits.
  • Add docstrings to DisplayContext.
  • Make the query_render routines use a DisplayContext object to compute their alignment.
  • In the EntryPrinter(), figure out the maximum width of accounts and set it up.
  • Add a “target num columns” instead of a “min_width_account” to the EntryPrinter and figure out the min_width_account automatically from it, depending on whether we’ve got render_weights on or not. Use hte longest possible number of integral digits required from the DisplayContext in order to make this tight.
  • Add an option for the DisplayContext to issue a warning if numbers are rendered through it that lose some precision.
  • Add “display_precision” input file option whereby the user can set the precision to be used by each currency.

Misc

  • bean-doctor context does not render all digits… it should render all the numbers as represented in memory. Don’t round those numbers.
  • Add a –auto-everything option to bean-check that automatically inserts a beancount.plugins.auto_accounts directive and more.
  • In the parser or in the validation, check that the price currency matches that of the cost currency, if both are specified!

    2011-01-25 * “Transfer of Assets, 3467.90 USD”

    • Assets:Investments:RothIRA:Vanguard:VTIVX 250.752 VTIVX {18.35 USD} @ 13.83 CAD
    • Assets:Investments:RothIRA:DodgeCox:DODGX -30.892 DODGX {148.93 USD} @ 112.26 USD
  • Add a special PYTHONPATH for ledgerhub binaries, to override Beancount to its custom version.
  • The ‘balances’ report should also support a WHERE clause as a nice shorthand. I would use that all the time myself if I could.
  • Add a query_env function to output the root type of an account, e.g. ‘Assets’.
  • Replace the portfolio script by a bean-query command that will use metadata on the commodities (!). This will simplify things a lot and be more flexible. These are really just aggregations of a different kind.
  • Create a function to identify whether a Position/Inventory is cash… use this to reproduce/replace the ‘cash’ report. Use the same rule from bean-report.
  • Complete converting price fetching script to use meta-data only and remove blais.prices. Also convert the example to declare commodities and the price fetching script should just work.
  • Fix the closing criterion for empty accounts.

    “I used to have it so that accounts closed before the beginning of the exercise (in the reports) would not appear. Accounts closed at the end of the period but with some activity within the period would appear (so you can click on them and see their journal). Opened accounts with a zero balance would, too. Closed before begin + no activity = no show.”

    2000-01-10 open Assets:Continuing 2000-01-10 open Assets:Empty 2000-01-10 open Assets:Terminated

    2000-01-10 open Equity:Whatever

    2014-03-10 * Assets:Continuing 110 USD Assets:Terminated 120 USD Assets:Empty 130 USD Equity:Whatever

    2014-03-30 * Assets:Terminated -120 USD Assets:Empty -130 USD Equity:Whatever

    2014-05-15 close Assets:Terminated

    2015-01-10 * Assets:Continuing 110 USD Equity:Whatever

  • Make prices required to always be positive, including with @@, and err on negative amounts for prices. This will match Ledger semantics and will remove one degree of freedom that wasn’t necessary.
  • Add the capability to issue warnings when the price database is queried for a specific date but the price point is too distant from the requested date.

    “One thing I want to do soon is to issue warnings when the price database is looked up and the price point is too far from the requested date, so that the user could go fill in the missing prices. I’d probably issue price entries with the approximated price (approximated with a distant date) and then feed that into another script that would fetch prices for those directives.”

  • (easy) Don’t render postings in the HTML interface by default. The detail can be made available via bean-query now, and users can click on /context link in order to get the full transaction detail. Journals should be summaries. Add an optional argument to turn it on/off, but it should be off by default.
  • (easy) Make b.w.web also ‘app.options_map’ instead of ‘app.options’.
  • (easy) Make all plugins accept a configuration parameter, unconditionally. The interface should be this regular.
  • Don’t install all the _test.py files, make sure they’re not installed, + add a lint check that ensures the non-test files are never importing any of othe test files.

(web)

  • Make the web interface not render postings anymore by default.
  • Rename /context to /entry
  • USEFUL. Issue warnings if the price date is too far from the requested market value date. This will help with returns, a lot. You should likely do this in the price_map object, in the lookup function, maybe, so that all modules benefit from the feature. You could ideally provide a date and a tolerancen, and somehow issue warnings automatically.
  • Fix FIXME in beancount.projects.returns, from DClemente issues.
  • In balance/aggregate reports, render the balances for parent accounts too.
  • Make bean-web and bean-query use the DisplayContext object in order to render all their numbers. Users are noticing, this is annoying.

Documentation / Ongoing

  • Write out the taxes section, you have all the details, no need to wait
  • Update the example file in order to include support for the commodities.
  • Make a single doc / single about the four tools that can be used to get information out of Beancount and make their sections short and link to a dedicated doc for each. The four-out structure of this document should be clear.
  • Start a doc on limbo accounts, including the email thread with mharris & redstreet0.
  • Write a script to automatically convert and upload the docs for the shell functions and what-not into a Google Docs that we can open with a web browser. Write a script to spit it out in a nice format and upload.
  • Document the @@ and {{}} syntaxes (see Matthew Harris email), especially as they replace to price.
  • As an aside, I see that the grammar supports @@ and {{}} syntaxes, but they don’t appear to be documented in the language manual.

    Oh I hadn’t noticed… I will document those, thank you for reporting this oversight.

  • In the comparison doc: describe how Beancount has asset types
  • Comparison w/ Ledger doc: “balance sheet and closing of year”
  • A nice new Health Care section is nearly complete… complete it with DEDUC and COPAY legs explanation. Write an accompanying plugin to insert the deductible tracking and what-not.
  • Write document on converting between implementations
  • Complete “How Inventories Work?”
  • Complete intro document on double-entry bookkeepingk.”
  • Complete Design Doc
  • Change documentation script to try to download to ODT format and then batch format to ebook
  • You should have a dedicated section of your document that explains how market values are reported, that is, via the unrealized gains plugin. Also provide a market() function, to value holdings.
  • Finally bake a PDF of all GDocs documentation and add a link to it. Should be mobile-friendly.

Streamline Commands

  • I plan to remove bean-example and move that into a bean-doctor subcommand.
  • bean-sql is a bit of an experiment, I’m not sure we need it, but I want to keep the functionality.
  • Maybe bean-bake could be folded into bean-web.

Commodities

  • Because of the way we currently deal with stock splits, allow a list of commodity names on the commodity directive, so you can do this:

    1998-01-01 commodity CRA,CRA1 name: “Celera Corporation” asset-class: “Stock” ticker: “CRA” quote: USD

Query Language

http://furius.ca/beancount/doc/proposal-query

  • Render to CSV as soon as possible, this makes it possible to export.
  • Add dot-syntax to be able to run inequalities against the balance, e.g. balance.number < 1000 USD, or parse amounts, units(balance) < 1000 USD. Some users have inferred that this would work, so it’s probably intuitive to others too.
  • Create tests for all the realistic test cases Use cases:
  • Use the display_context in the BQL rendering routines instead of using the display precision mode in the displayed numbers only.
  • This should fail (it doesn’t):

    SELECT DISTINCT account GROUP BY account, account_sortkey(account) ORDER BY 2;

    I think you need to apply the ORDER-BY separately, and be able to ORDER-BY aggregate values.

  • The OPEN ON and CLOSE ON syntaxes get on my nerves. I need something simpler, maybe even something simpler for “just this year”. Maybe an auto-open at the first transaction that occurs after filtering, something like this:

    FROM year = 2014 CLAMPED

    where CLAMPED means (open + close + clear) operations.

  • Add tests for all environment functions
  • Optional: Support a ‘batch mode’ format to process multiple statements at once, reading the input files only once (needs support for redirection of output to files).
  • Write a documentation for the query language.
  • In docs: explain four ways to “get data out”: bean-web, bean-report, bean-query, write script.
  • Create a setvar for style (boxed, spaced, etc.)
  • Rename ‘change’ column to ‘position’, and support dotted attribute name syntax. It should map onto the Python syntax one-to-one.
  • Compute the special ‘balance’ row and produce journals with it.
  • Cache .format methods in renderers, they may be caching the formatting themselves. Time the difference, see if it matters, look at CPython implementation to find out.
  • The current number formatting code truncates numbers longer than the mode and should be rounding it. Make it round.
  • Another problem is that although the mode of the precision could be selected to be 2, if other currencies have a higher maximum, numbers with greater precision than that will render to more digits. This is not nice.
  • The insertion of unrealized value in this test query is the reason we have 14 digits of precision; this is not right, the unrealized entries should be generated with less precision, should be quantized to the mode of the precisions in the input file itself:

    select account, sum(units(change)) from close on 2015-01-01 where account ~ ‘ameritra’ group by 1 order by 1;

Time to write test for this, for the mode rounding.

  • Convert the amount renderer to use the display-context.
  • Render with custom routine, not beancount.reports.table
    • Find a way to pipe into treeify
    • Deal with rendering on multiple lines, e.g., for inventories with multiple positions
  • Implement set variables for format and verbosity and display precision and what-not
  • Support matching on other than Transactions instances.
  • You could apply an early limit only if sorting is not requested, stopping after the limit number of rows.
  • Implement and support the ResultSetEnvironment for nested select quereis. (Actually allow evaluating the SQL against generic rows of datasets.)
  • New columns and functions:
    • Add date() function to create dates from a dateutil string
    • Support simple mathematical operations, +, - , /.
    • Implement set operations, “in” for sets
    • Implement globbing matches
  • Flatten should parse closer to distinct keyword, as in SELECT FLATTEN …
  • Maybe add format keyword followed by the desired format instead of a set var (or add both)
  • Redirecting output should be done with > at the end of a statement
  • “types …” : print the inferred types of a statement, the targets, or maybe that’s just part of EXPLAIN? DESCRIBE? Describe prints all the columns and functions in each environments? Or is it HELP?
  • BALANCES should use and translate operating currencies to their own column, and it should just work automatically. It should pull the list of operating currencies and generate an appropriate list of SELECT targets.
  • Create an “AROUND(date, [numdays])” function that matches dates some number of days before or after. We should be able to use this to view transactions occurring near another transaction.
  • This causes an ugly error message: beancount> print from has_account ~ ‘Rent’;
  • That’s weird, why didn’t those get merged together, investigate:

    beancount> select cost_currency, sum(cost(change)) where account ~ ‘assets.*inv’ group by 1 ; ,-----+-----------------------------------. ----------------------------------------+

    CADXXXXX.XXXXXXX0000000000000000 CAD
    XXXXX.XXXXXXX0000000000000000 CAD
    USD

    `-----+-----------------------------------’

    This is probably due to lot-dates not being rendered.

  • You need to support “COUNT(*)”, it’s too common. r.Count(r.Wildcard()).
  • The shell should have a method for rendering the context before and after a particular transcation, and that transaction as well, in the middle. This should replace the “bean-doctor context” command.
  • As a special feature, add an option to support automatic aggregations, either implicitly with a set-var, or with the inclusion and support of “GROUP BY *”, or maybe “GROUP BY NATURAL” which is less misleading than “GROUP BY *”. Or perhaps just “GROUP” with the “BY …” bit being optional. I like that.

    Although MySQL treats it differently: “If you use a group function in a statement containing no GROUP BY clause, it is equivalent to grouping on all rows. For more information, see Section 12.17.3, “MySQL Handling of GROUP BY”.”

  • For the precision, create some sort of context object that will provide the precision to render any number by, indexed by commodity. This should be accumulated during rendering and then used for rendering.
  • Provide an option to split apart the commodity and the cost commodity into their own columns. This generic object should be working for text, and then could be simply reused by the CSV routines.
  • Add EXPLODE keyword to parser in order to allow the breaking out of the various columns of an Inventory or Position. This design is a good balance of being explicit and succint at the same time. The term ‘explode’ explains well what is meant to happen.

    SELECT account, EXPLODE sum(change) …

    will result in columns:

    account, change_number, change_currency, change_cost_number, change_cost_currency, change_lot_date, change_lot_label

  • Idea: support entry.<field> in the targets and where clauses. This would remove the need to have duplicated columns, would make the language simpler and more intuitive.
  • Idea: Another output data format for the reports/query language could be parseable Python format.
  • (query syntax) It would make sense to use full SQL for this, even if the aggregation method is an inventory.

    targets: units, cost, market, lots data-source: balances, journal, holdings restricts: … all the conditions that match transactions, with = … aggregations: by currency, by day, by month, by account (regexp), etc. other: filter display, pivot table (for by-month reports), max depth

    You would render these as a table.

  • Implement a “reload” command to avoid having to leave the shell after the file changes. Maybe we should even have an “autoreload” feature that just kicks in before a query, like the web interface.
  • Move bean-example to being just a doctor subcommand; we really don’t need to make that a first-class thing.
  • Support constants for flags, e.g. flags.conversion is equivalent to ‘C’. Add those to our existing unit tests.
  • Create test cases for all query_env, including evaluation. The list of tests is currently not exhaustive.

V2

  • I think we can do prety well like this:

    SELECT … FROM transactions|postings|balance|… WHERE ANY(…) ALL(…)

    I’m not sure where OPEN CLOSE and CLEAR all fit though.

Standalone Tools

  • Build a function and command-line tool that can injest either a table of results or a CSV file and infer that an entire column is of numbers and pairs of numbers and can accordingly split the column into multiple columns and put the currency in the header so you can import that up to a spreadsheet.
  • Build an ‘statement’ tool that will render a treeified balance sheet in two columns! Limit it to use the beginning of a line, and hard-code to use the five known categories (optionally changeable). It’s okay if the tool is a bit more limited than treeify. It should optionally do the treeification. It should also optionally sort the account names (or not).
    • Add a –title option to render at the top.

    (A two-column tool to convert one column into two columns (for text mode balance sheet and income statement). The equivalent UNIX tool does not exist. Select columns by regexp on prefix.

  • Build a simple ‘colrneg’ tool that just highlights numbers as green or red depending on if positive or negative.
  • ‘csv-pivot’: build this: a script that can accept a CSV file and render a CSV pivot table from it. The reason we need support is in order to carry out operations on columns of inventories. Maybe we should impleemnted some sort of swiss-knife tool that is able to parse inventories from columns and perform various operations on them, aggregations, etc. using Beancount’s Inventory() class. This could be a powerful tool! Make it possible to parse and create Inventory objects from cells.
  • Perhaps should build a version of treeify for internal usage that works on HTML columns, off of HTML text. Or BETTER: just a stateful tool that can transform an account’s name to indent it properly every time you feed it the full account name! This could be used by the routine that want to render columns as tree. Maybe ‘treeify’ should use that as well. That would make a lot of sense.

Deal with Rounding

http://furius.ca/beancount/doc/propostal-rounding

  • Check Vanguard rounding… do they maintain a higher precision internally?
  • Implement experimental precision check suggested by Nathan Grigg
  • Implement Equity:Rounding accumulation suggested by Nathan Grigg
  • Remove b.c.amount.DISPLAY_QUANTIZE if possible.
  • Make (SMALL_EPSILON) balance tolerance user-configurable before release.
  • Infer precision from numbers like this:

    >>> d = Decimal(‘1.2300’) >>> getcontext().power(10, -(len(str(d).split(‘.’)[-1])+1)) * 5 Decimal(‘0.00005’)

  • Maybe provide a way to make thhis tolerance settable by commodity. (See thread w/ Nathan on the mailing-list)
  • Doc: https://groups.google.com/d/msg/ledger-cli/m-TgILbfrwA/YjkmOM3LHXIJ

Alright, so here’s what I propose:

  • I could add an option for the user to insert the name of a rounding account.
  • This option would be empty by default, and the current behaviour would not change.
  • However, if you set an account for it, all transactions with an inexact balance will receive the balance amount (and perhaps have a new leg inserted on them automatically).

Would that be a reasonable compromise? With no account, you get 0.005 looseness (or whatever this becomes if inference is implemented). With an account, you get precise balances throughout, but no manual input is required.

  • Complete and merge sampled_quantization

Inventory Booking Proposal

http://furius.ca/beancount/doc/proposal-inventory

  • Make a temporary hack to disable strict checks on a per-account basis. This will keep us going against average cost until the full inventory proposal is implemented.

“The inventory booking proposal for average booking won’t be implemented in the next few weeks… I’m tempted to think that maybe I should provide a way to disable the strict balance checks in the interim. This way we could enter the transactions without matching lots strictly… at least all the data would be present and the balance checks would work. Would people think it’s a good idea? I would do this by extending the default value for the type of booking is intended to take place (as in the inventory proposal) and add a new value for it, i.e,. in addition to STRICT, FIFO, LIFO, AVERAGE, AVERAGE_ONLY, I would add NONE. I would use the proposed syntax extension for the Open directive, e.g.

2014-08-84 open Assets:US:Vanguard:VIIPX VIIPX “NONE”

This also means that you could setup all your accounts to remove all inventory booking, which results in a booking method similar to Ledger (no checks and no errors), by setting the default value for it, like this:

option “booking_method” “NONE”

This could appeal to those who would like less checks, like Ledger, or who are converting their Ledger ledgers to Beancount.

Down the road, the inventory booking would use that and implement all methods, but for now, only the balance check would consult that value and disable the check if the default booking method is “NONE”. I think I could easily hack that in in a few hours.”

  • Implement the proposal
  • (design) New inventory booking:
    1. for each posting, classify by currency
    2. for each posting at cost, classify whether position augmentation or reduction
    3. For position reductions, match against inventory
    4. Within currency groups, process interpolation, including those in position augmentations

    It should be possible to do something like this for cost basis adjustments: Assets:Account -10 MSFT {34 USD} Assets:Account 10 MSFT {USD} Income:PnL 400 USD

    (See doc on Smarter Elision for a better version of this)

  • Separate inventory booking to be implemented in a plugin. It should do three things:
    • Find matching lots and raise errors when not found
    • replace all partially specified lots to their fully specified versions (they matched lots). For augmenting lots, this means insert the date. For lot reductions, it means, find the matching lot and use that instead of the partially specified one.
    • Insert links on matching lots, so that trades can be identified a posteriori.

    This means, move beancount.ops.validation.validate_inventory_booking() to its own file and make it do the three steps above.

(avg cost idea)

  • Docs for inventory booking: Add {* 634.23 USD} idea for average cost booking: there should be an optional amount, and the star just means “before and after”. Add this to B docs.
  • PROBLEM: You need be able to provide the cost with both and addition and a reduction, e.g. -2 HOOL {* 650 USD} ;; Should be possible even if current avg cost if 600 USD 2 HOOL {* 650 USD} ;; Means “add at this cost and then convert to avg cost”

    This is nice! The “*” now always means “after applying this operation, convert to avg cost.”.

  • You should add tests to ensure that an Inventory() can never have positions created with a cost of the same cost_currency as the currency. This should be enforced in the Position object itself.
  • After it’s done, merge back branch ‘sanscost’, and we should be able to make this work using the total cost value on the lots.
  • Implement a report of Trades booked in the list of filtered transactions! Trades should be automatically identified by the booking process, with its own namespace of links. Then allow producing suitable reports for trades.
  • (reports) Bring back the trades report into the mainline version, using inventory reductions.
  • (reports) We really do need to report on position reduction as TRADES. This is an important report to generate! This should be done separately from the improved inventory booking method.

    This report needs to include the long-term vs. short-term nature of those trades! The right way to do this is to run a separate plug-in that will add appropriate #long-term and #short-term tags or meta-data to those transactions, based on their booking dates..

  • Add the acquisition date to each lot, so that short/long-term can be calculated for the lot. The goal is to enable the automatic calculation and reporting of long vs. short capital gains.

Removing Holdings

  • I think there’s a way to simplify holdings: you can probably remove the “Holding” type and replace that with a Posting, which really, is much like a Holding, it has an account and a position, and a price.... That would normalize Holding quite a bit, even if it means we end up adding a few unused slots to Posting. I’m happy to do that! Simplify simplify simplify… always.
  • Along with the new inventory, you can make Holding -> Position. This makes a lot of sense actually. Do do this!

(work on holdings)

  • Support output format “beancount” for holdings, use a single file instead of a holdings I/O file (merge holdings.csv + prices.beancount -> holdings.beancount) This would be much nicer.
  • Check holdings I/O by saving and reloading a list of holdings created from a set of entries (with sales, just to make sure).
  • In add_unrealized_gains(), convert to use our holdings aggregator.
  • Build a new category to portfolio to identify accountings holding “Uninvested Cash”, which should be cash available to invest now.

Sign Normalization

  • Allow sign normalization:
  • Add an option to the parser to allow signs to be entered with the “all positive” convention, and actually invert the signs right at the output of the parser. Balance errors should be enhanced to emphasize which of the postings should be increased or decreased, based on the sign of the balance error and the type of each account.
  • For display, in the shell, provide a SIGN(account) function that allows the user to multiply the inventory by, or a NORM(inventory, account) function that would do that itself on the inventory.

This whole thing should be a minor version. This would be a valuable feature IMO, allowing users to choose their favorite convention would be a plus.

  • Do support rendering options to invert the amounts of the minus accounts. This is an important feature.

Transfer Accounts

  • Transfer accounts should be a priority. You need to be able to support a single transaction that gets amortized over time.

Trading Accounts & Conversions

Performance

  • (validation/performance) Optimize the performance of validations and bring all the HARDCORE_VALIDATIONS in by default.
  • Maybe the builder should have a ‘filename’ state that only gets changed here and there instead of getting that fileloc argument passed in every time on every rule. Maybe we just always get the fileloc from the parser.c as in NUMBER. I think it might make the parser more efficient too… try it out, do timings, see how much it improves parsing performance.
  • See if you replace BUILD()’s PyObject_CallMethod to this how much faster it gets: “Note that if you only pass PyObject * args, PyObject_CallMethodObjArgs() is a faster alternative.” https://docs.python.org/3/c-api/object.html
  • (performance) Profile the web pages, if account_link() is high, provide an explicit cache for each unique view. (We had to remove this when we simplified the function using build_url for adding tests.)
  • (performance) Implement the stable hashing function in C and reinstall the validate_hash test.
  • (performance) Implement inventories in C and reinstall the validate_check_balances test.
  • (performance) Don’t pass in the FILE_LINE_ARGS on function calls, these should be part of the context of the parser, should be gettable only on demand.
  • Can I use Py_RETURN_NONE in order to incref and assign, in the lexer, instead of doing it in two steps?
  • Optimize the main update() routine that is called in display_context.

Dashboard

  • Create new project doc: Computing portfolio returns using Beancount
  • Bring in all the generic functions from experiments/returns/returns.py into core beancount. Bring in returns as a plugin.

(portfolio)

  • Move portfolio code our of experiments
  • Move ‘portfolio’ and other experiments to be its own library, under the main source tree, validated and all.
  • In holdings: create the concept of a “composition” which can be associated to any holding, based on the (account, currency, cost-currency), and which is a vector of proportions to be normalized and associated to the holding. You should then be able to compute the sum total of all compositions. This should be a generalized concept, with the following applications:
    • Liquidity (how easy is it to get money out of this account?)
    • Taxability (pre-tax, roth, after-tax, usually 0 or 100%)
    • Sector, industry exposures
    • Currency exposure
    • …

Plugins

  • Create a plugin that allows you to replace the date with some of the metadata fields, e.g. to create alternative date histories.

    “Note that if you really badly wanted alternative history, you could you could easily enter alternative dates as metadata (Beancount will recognize and parse a datetime.date type as a value for metadata) and you coudl write very simple plugin that converts all the transactions to use the alternative date where present in the metadata (or otherwise leave the date as is). You could even define yourself multiple different sets of alternative dates by using different metadata fields… you can go crazy if you like and create multiple versions of history that way. But that would be segregated to a plugin so I’m comfortable with it, do whatever you like in plugins, they’re perfect for experimentation.”

  • Create a verification plugin that verifies that the balance of an account does not go under some negative threshold below/above zero. This way you could check that account balances are of the expected size. (The plugin should accept transient negative balances within the day though, as those are order-dependent.)
  • Create a verification plugin that checks that there is a single currency in use per account. Check Open directives, also check actual usage.
  • Create a verification plugin that checks that all uses commodities have a corresponding commodity declaration. For those who like it airtight.
  • Put all verification plugins, including nounused and noduplicates under beancount.plugins.constraints.*.
  • Would it make sense for every plugin to provide a validation function? We could then move all the validation routines in their plugin file. I very much like this idea: it creates more isolation for routines and less dependencies. Open/Close, Balance checks, do seem to be able to fit in this category. Those functions should return only a single list of errors, no entries, and the calling function should perform a simple hash check to ensure that the mutable portion of the entries hasn’t been modified by the user-provided validation functions. ‘beancount.ops.documents’ could benefit from this split.
  • Idea for an additional check: a plugin that computes the weight using the “@ price” value on a posting held-at-cost, checked against the rest of postings minus income (gains) accounts.
  • Idea: a plugin that autopads all initial balance assertions! Do it for demos, will be very useful for making demos easier, not having to be so strict.
  • Deal with wash sales… complete doc, call MSSB to figure out if/how they adjust the cost basis of a future stock vesting event.
  • Idea: Write two plugins…
    • One that check that all the postings with a particular flag on them balance to zero.
    • One that forks out all postings with a particular flag to a separate transaction.

    This is from an email thread with redstreet0 in Jan 2015:

    I said: ”

    • Define yourself a special account under a common base, e.g. Equity:Extra:* for all those special accounts.
    • Write a plugin that will ensure that for all transactions that include at least one posting on an Equity:Extra account, the sum of all the weights of these postings is zero.
    • If you want to automatically fill in missing postings these accounts, you can also do that from a plugin.
    • Your plugin should be configurable with the root account you want to make special in that way, in this case “Equity:Extra”. See other plugins for how to pass in a configuration.
    • You can optionally filter out all those Equity:Extra:* postings in the reports using the FROM syntax. Otherwise the detail of the Equity:Extra accounts in the balance sheet will be pretty harmless anyhow, but you could remove it.

    Note that instead of identifying these special postings using a known root account, you could instead trigger that capability by using posting flags.

    (Also, note that if all you care about is the balanced virtual accounts, that’s entirely equivalent to a second transaction on the same date. I could be convinced to add that in, a special state for a subset of postings, as a “shadow transaction” whereby the parser splits the single transaction into two separate ones, perhaps adding a tag to the shadow one so that you can filter them out at will. That could be implemented as a plugin, BTW, separating postings that have a particular flag on them.)

    ”. This could be used to simulate balanced virtual postings.

  • Generalize the scope of Document directives so that they don’t just point to filenames, but can hold references to arbitrary document ids.
    • Rename the field from ‘filename’ to ‘document’
    • Make the verification of that field against a filename option, enabled by a plugin.
    • Notify bw3443 about this.

Basic Directives as Plugins

I recently teased out that many of the basic functions can be implemented as individual stages of transformations on the list of directives. This started out as a way to add plugins by adding a custom transformation stage, but now I see that if I can make the parser able to consume generic syntax that might allow extensions, and to allow these plugins to specify new directive types for extensions, I might be able to shove a lot of the existing functionality into nice isolated plugin modules. Even functionality as basic as Balance checks. I’m not going to to do this in the first release, but I want to set the stage for it.

Fix Unrealized Gains

  • IMPORTANT: Unrealized gains for opened periods should show only gains since the openings. In other words, unrealized gains should be realized marked-to-market at the time of open.
  • Unrealized gain when rendering for closed years does not appear. Perhaps we should insert the unrealized gains during close operation.

    Idea: close realized gains along with close(), so that they don’t show up for the latest year.

  • Unrealized gains should be modified so that they replace the book value of the positions that they adjust, and can be applied at multiple dates. Then, the realization should automatically occur both at the beginning and end of reporting periods.

Inter-Account Booking

http://furius.ca/beancount/doc/proposal-inter

  • Idea: option to search a lot from any account, not just the current account, and cause an automatic lot transfer. Must match shares in the current account, but the lot with the corresponding cost could come from any account.
  • Create new proposal doc: Inter account transfer

Better Errors & Errors as Directives

  • Enhance error reporting! Make all errors possibly hold on to a list of entries, not just one. Many, many errors will benefit from this.
  • The creation of exceptions should be made easier: each error class should inherit from a base class that is able to accept an optional list of entries, that would automatically render the fileloc of each of those entries, and that would use the fileloc of the first entry in order to render the location of the error. If no entries are specified, an OPTIONAL fileloc= parameter should be provided to specify where the error occurs. This will make creating errors a lot easier and nicer.

    As part of this, we should also somehow produce a list of all possible errors with a lavish description.

  • (architecture) Seriously consider merging entries and errors; errors are just a special type of entry, and they have dates, and they get rendered in journals. This could make a lot of sense.
  • Interesting idea: Maybe instead of returning errors, “errors” could simply become “Error” directives and be inserted into the flow, and picked up by the various rendering routines in different ways?!? I love this. One less thing to return. Hmmm ponder it seriously.
  • Refine ‘source’ attribute on all directives: For .source, instead of ‘<…>’ for the filename, we should use a scheme:…, like file://…, and plugin:beancount.... . This makes a lot more sense. The lineno still needs to be separate, we need that for sorting and prefer not to have it part of the string.

Pertaining to Old Reports

Include Directive

  • Support an include directive that is a URL, in order to fetch lists of prices updated remotely, or via crontab. This way the dashboard does not have to include code that fetches prices.

Payees & Subaccounts

  • Idea: Allow sub-account names to include a special character, e.g., ‘#’, (only one) that would indicate to the reporting facilities that, by default, the aggregation should be reported to the parent account. A “detail” or “verbose” switch could be used to trigger the detailing of subaccounts. For example,

    Expenses:Health:Medical:#Claims Expenses:Health:Medical:#PatientSavings Expenses:Health:Medical:#ClaimsPayments

    would be reported as

    Expenses:Health:Medical

    by default, but with the detailed switch, would be reported as

    Expenses:Health:Medical:Claims Expenses:Health:Medical:PatientSavings Expenses:Health:Medical:ClaimsPayments

    This could be used for various subaccounts actually. It’s a nice way to guide reporting that does not complexify the semantics.

  • Idea: in the query language, provide a special Account:Payee field, in order to play with the notion of payee-as-subacccount often discussed.

    could also provide a clean_payee() function, that would attempt to clean the ugly payee names!

Project: Auto-transfer Inference

  • IDEA: Using inference and a reasonable buffer amount, can I automatically figure out how much extra cash from checking can safely be transferred out for investing? i.e. sum up upcoming expenses (rent + cc) and expected salary payments, and calculate it automatically. Not obvious, but why not?

Project: List Unverified Postings

  • Idea! Allow the selection or reporting of all the postings since their balance check in each account. These postings can be called “unverified” and it should be possible to report just those. Maybe we can restrict further to the list of those without a ‘*’ flag, or maybe just those with a ‘!’ flag. “Show me all that’s unverified right now.”

Invariants

  • options[‘commodities’] is currently where the list of all commodities seen from the parser lives. The beancount.core.getters.get_commodities_map() routine uses this to automatically generate a full list of directives. An alternative would be to implement a plugin that enforces the generate of these post-parsing so that they are always guaranteed to live within the flow of entries. This would allow us to keep all the data in that list of entries and to avoid depending on the options to store that output.

    This should probably be combined with a similar step that similarly enforces all unopened accounts to have an Open directive as well.

Pending Removals / Remove Deprecated Things

  • Remove the exp-legacy-fixed-tolerances experiment flag.
  • Remove support for legacy, PIPE, Not needed.
  • Remove negative number warning and __ setting

Current / Misc / To Be Classified

(This is a grab bag of ideas. When I have a new idea coming to me, I don’t have time to think about where to put it, I just come here and jot it down. Every couple of months I clean this mess up and put it in the sections below. Please excuse the mess. Of course, I’ll clean it up before every release.)

  • Remove AttrDict… we can do away with a regular dict:

    grep -srn ‘meta.’ /home/blais/p/beancount/src/python/beancount | grep -E -v ‘meta.(get|copy|items|keys|values)’

    See issue #79.

  • An important option exists around the behavior of balance checks: Should balance checks bring their balance to the balance amount? In other words, should a balance check imply an automatic, on-demand Pad behavior on failure? This has an impact on following balance checks further in time. The current behavior is not to pad a failure, so if there are multiple balance checks, a single mistake before them would generate a number of errors. An equally valid behavior would be to trigger only a single error, isolating the periods between balance checks. Both semantics have advantages. You should provide an option to ustomize this behavior, the user should be able to choose. option “pad_failing_balances”.
  • Reconcile all usage of account regexps to beancount.core.account.ACCOUNT_RE throughout the code (grep –include=’*.py’ -srn A-Z ~/p/beancount/src/python/beancount).
  • What happens if you specify the same plugin twice, with different configuration strings?
  • Provide a way to save and easily render a query, from the input file. e.g.

    2015-09-23 query “cash” ‘SELECT CONVERT(SUM(position), “USD”) WHERE account ~ “Cash”’”

    Typing “cash” in the shell should run this query.

    Also, there should be an option to bean-query (or less likely, a dedicated command) to generate all the queries defined in an input file.

  • web: Don’t render the transaction detail anymore; instead, the full context should come up in a tooltip that is computed on-demand. Rendering the basic table should not have to render all the detail upfront, that is always overkill.
  • Highlight (e.g., in the color red) the postings to accounts that are in contra value, e.g. a positive Income, or a negative Expenses posting.
  • query: Provide a column for the “other accounts” of a selected posting’s transactions, so you can select that.
  • Great idea: Make the printer able to (1) output “incomplete” entries and (2) print out the entries in the order of (filename, line-no) in which they were parsed, to produce a file that is as close as possible to output. (bw3443 asked for this in order to make modifications to his input and push that back out to a file, this could be useful.)
  • AWESOME IDEA: Write a script that, given an input file with various sets of transactions, will find sections with most similar transactions in a destination file (the main file) and automatically insert those transactions in the destination file in the right place and run a diff with it. This should be part of the import suite. Do this as a post-process to import! Maybe use org-mode or other separators as a way to segregate groups of transactions.
  • KeyboardInterrupts (if you press it) in the parser will cause errors:

    $ bean-report $L exportpf > /tmp/export.ofx blais.beancount:42041: KeyboardInterrupt:

    This is exceedinly rare but maybe worthwhile to catch regardless.

  • Write a script that, given my portfolio of ETFs, will compute the total exposure of AMZN (or any other stock) to the entire portfolio value.
  • Implement a DESCRIBE command to the SQL shell in order provide help on the available row commands. I think this would be a natural way to do this.
  • An easy way to remove the diff_amount exceptional field from Balance is to move it to metadata, and this would be consistent with the goal of plugins using metadata for their own goals: assertions of Balance can be see as a feature of the plugins.
  • Try creating a “Record” class to replace namedtuple using a class decorator and properties.
  • Try removing the ‘tags’ attribute of transactions by moving it to metadata fields and making sure tools are available to perform the same aggregations using bean-query and views using bean-web.
  • bean-doctor context should accept a LINK, not just a line number from context.
  • Rename test_util.TestCase.assertLines() to assertEqualNoWS().
  • This query works:

    bean-query $L ’ balances from flag = “!” ’

    But this query fails:

    bean-query $L ” balances from flag = ‘\!’ ”

    The second one needs to have the flag escaped because of bash shell expansion, but the problem is that the escaped backslash appears in the output. This is normal bash behavior, but the problem is that the user receives no notification of failure in this case. Beancount should detect that the string compared to a flag is not a single-character string and issue an appropriate error message for it.

  • Make the web application use the regexps defined in common in its paths instead of inline ad-hoc approximations. There was never any need to do that.
  • Test out removing the circular reference in Posting. This would make writing scripts a lot easier and I bet we should be able to make do with per-account lists of (Posting, Transaction). Create a tuple type for it, to make this explicit. I bet it wouldn’t be very much work to make the conversion; try it.
  • A simple code cleanup: Since filtering Transactions out of a list of entries is so incredibly common, provide a simple helper in b.c.data to do this. filter_transactions() for example, and change all the code everywhere to use it.
  • Add a simple overview ‘stats’ report with output like this:

    Files these postings came from: …

    Unique payees: 2681 Unique accounts: 151

    Number of postings: 9026 (4.8 per day) Uncleared postings: 126

    Days since last post: -206 Posts in last 7 days: 30 Posts in last 30 days: 52 Posts seen this month: 8

  • Make booking the cost on the same currency as the instrument impossible:

    <account> 1212.023 USD {100.00 USD}

    Ditto w/ the price. This should only be done after allowing zero cost.

  • Compute pre-tax and post-tax net worth reports, based on a “tax” account metadata field and some reasonable assumptions.
  • Implement an optional feature that disables the merging of inventory lots for all lots except lots without cost. I believe that this won’t make any difference to the complexity of selecting reducing lots but I want to test it out on my real file before committing to the idea. Removing merging of lots-at-cost would make the merging logic simpler and easier to understand.

    But what about something like this? Do we want multiple lots here?

    2005-12-29 * “Dividend on NB550” Assets:CA:RRSP:NB550 1.340 NB550 {18.2348 CAD} Assets:CA:RRSP:NB550 28.646 NB550 {18.2348 CAD} Income:CA:RRSP:Dividends

  • WILL report. Create a new type of report that produces a readable document with the entire list of accounts and descriptions and account numbers pulled from metadata. This document should be attacheable to a will, to describe all the accounts, institutions’ phone numbers, account numbers, in a way that makes it possible for someone executing a will to easily understand that full nature of the assets and how to reach the relevant institutions to liquidate the assets.
  • Consider allowing a cost basis of zero. (See “Modelling stock options with Ledger” thread on ledger-cli).
  • Move the check for zero units (“Amount is zero” from the parser) to a plugin, and make this selectively removable.
  • Write the multi-year report and share on the list at https://groups.google.com/d/msg/ledger-cli/XNIK853ExNc/CWxSPa-5INMJ
  • Write a utility script that merges multiple reports with a leftmost column of account names into a single report with multiple columns.

    SELECT account, bal1, bal2 FROM (SELECT account, sum(cost(position)) as bal1 FROM CLOSE ON 2014-01-01 CLEAR) JOIN (SELECT account, sum(cost(position)) as bal2 FROM CLOSE ON 2015-01-01 CLEAR) ON account;

  • It would be useful to create a directive that checks that the balance of an account in a time interval is lesser or greater than some specific amount, e.g.

    Expenses:US:TY2014:SocSec <= 7254 USD ;; 6.2% of 117,000 USD Expenses:US:TY2015:SocSec <= 7347 USD ;; 6.2% of 118,500 USD

  • Implement a check that the sign of a @@ price is always the same as the number of units themselves.
  • Make it possible to assert the total cost basis of a particular commodity within an account (see Eric Weigle discussion on ledger-cli list).
  • When you will add cost basis to the balance assertions, make the padding directive also able to fill in with some cost basis. This would be useful for mharris (see discussion on Language Syntax document).
  • Implement a total balance assertion using the following syntax:

    YYYY-MM-DD balance account amount account amount account amount account amount

    The distinction is that it’s on multiple lines. Maybe call it balance*.

  • Build library functions to dedent, parse and create single entries, and automatically reach up the stack frame into vars to replace. These should be used in the example generation scripts and should be as convenient as possible for a user to generate new data, because I get a feeling that we’re going to do this a lot more in the future.
  • Create a plugin that automatically inserts a zero balance check right before a Close directive, for all currencies that appeared in that account.
  • Issue warnings when fetching prices with dates that are too far from the requested dates. We need to find a way to issue a global tolerance for this, that indicates to the user to fill in missing prices that are required to carry out particular reporting tasks.
  • Amount and Inventory and other basic classes: You could eventually support an implementation of __format__ which attempts to make sense of the different components, e.g., apply the format specifier to the number excluding the space required to render the currency.

(query)

  • Journal rendering: add terminal colors (easy).
  • In bean-sql, render out the tags to their own table and create a 1:N join table for them. Also, flatten out lots and refer to unique lots so that trades can be easily identified by looking at all entries that relate to a particular lot.
  • (web) In the web interface, it would be nice to have a fancy overlay here, that automatically appears after parsing if there are errors and that automatically smoothly fades out.
  • (docs) Write a script to download and bake all my PDFs docs in a printable and mobile-friendly formats.
  • Eventually you want to clean up the locations of the example files. I think the basic.beancount and starterkit.beancount files aren’t really that useful anymore, other than for automated testing. examples/tutorial/example.beancount should move away from the tutorial files.
  • (docs) I’d like the documentation links to open in “View” mode by default, YET still allowing the user to switch to “Suggestion” mode if they want to.
  • (docs) I’d like the documentation links to open in “View” mode by default, YET still allowing the user to switch to “Suggestion” mode if they want to.
  • balances report: support rendering the values not-at-cost for HTML reports too.

(open directives)

  • An invariant that we would love to have is to ensure that after parsing, all accounts that are used in a list of entries should have a corresponding Open directive for them. This would mean a variant of the validation routine that automatically inserts missing directives. At the moment, when an Open directive is missing, processing code that assumes they are always present might fail. We cannot insert the missing directives in the validation code simply because validation code is not allowed to modify the list of entries. We could insert a “fixup” step after validation, that does these kinds of automatic recoveries. Ponder this for a while.
  • Do we need to insert Open entries for the equity accounts described in options? I think we could safely plop that at the very beginning of the entries list in the parser.
  • Along with the new inventory, you can make Holding -> Position. This makes a lot of sense actually. Do do this!
  • (documents) documents found in parent directories don’t end up creating a directive because we skip them because we only restrict to accounts which have had an open declaration… this is probably not what we want, in order to maximize the number of documents captured by this. {fa96aa05361d}
  • Closing an account with a non-zero balance should trigger an error! Right now it does not. This is important.
  • (parser) Is it possible to specify no flag on a transaction?, e.g. just the date?

    2014-07-12 ..

    Does this work? (It would be nice if it did. Make it so.) We should change the grammar so that the flag is part of the txn_fields. This is elegant: basically, instead of the flag taking the place of the transaction, the ‘txn’ keyword just becomes optional. That’s it. DO THIS!

  • (web) All errors should be displayed in an overlay; proper error handling and display for the web interface is not optional. This needs to be done before shipping.
  • Figure out how to disable googleapis fonts when on a very slow connection. I’d like to enable the fonts, but if they cannot be fetched quickly, or cached, this should be disabled.
  • (parser) Add an option to the parser to not just ignore unparsed lines, more strict.
  • Beancount: Add a “lineno” format for journals that renders in “Emacs errors” compatible format, so we can easily jump in time throughout the input file instead of rendering a journal. Offer the option to list in reverse to.
  • (rendering) Journals should render in either order.
  • Use the same option on all tools for showing the timings, –verbose timings, maybe add it from the loader module.
  • Add an option for spacing in the revamped reports.
  • (pad) Review the possibility of padding units held at cost:

    “The reason it fails is that there must have been units of those commodities held at cost before the pad date, and it is an error to pad commodities at cost, because Beancount has no way to know what the cost basis of those commodities should be.”

  • When an error occurs while parsing a directive/transaction, add the ability to let the parser skip until the next directive and ignore the parsed transaction because of the error. Maybe this should be an exception mechanism, or just storing a flag that gets reset when the directive is completed. Not sure. This would be a more elegant way to deal with some errors.
  • You can implement the sign check for positions held-at-cost only when there are other of that same commodity held at cost in the inventory in the opposite sign. This should allow holding short positions yet still retain the benefit of the check for data entry errors.

    It also removes what for most people will appear as a limitation from the docs (although with experience you would realize that it is not much of a limitation at atll).

  • There’s a fundamental question about which date to be used for pricing entries. This really would depend on the view. If this is a period view, the date of the last entry is most appropriate. If it is any other kind of view, the latest price is best. All the reports should be adjusted for this.
  • Register (with filter) should have “print” mode that also includes file:lineno so that we can make Emacs “jump” between the transactions in the order they appear.
  • Idea: Add an option for triggering strict validation?

    option “processing” “strict” ; Plugins including the hardcore validation are run.

    Somehow making the hardcore validation into a plugin might be a good way to provide a strict mode. Also, you could build a beancount.plugins.builtins module that defines the list of default plugins that gets run instead of having a list in the loader. This way the user could easily invoke it at any point in time.

  • (reports revamp) Write a generic test that simply enumerates all the reports and invokes them with their default values. This should extend automatically when new reports are created.
  • (trial balance) In order to zero out the trial balance perfectly, you could insert a conversion entry at the end of it, in the same way that I do for the balance sheet. There is no reason that this is any different; this should be done the same.
  • Build a ‘events’ report that will print out the current value of all events.
  • Create a new report type: “days” that counts the days of any event in the filtered log.
  • You need to create a unit test for @@ price conversions.
  • You need to unit-test for multiline notes… do they work as expected?
  • Document args of C functions in the same way as Python’s, perhaps using the new Python3 syntax definition thingamajig (I forget the name, there’s a PEP).
  • Fetch the CSV holdings of each Holding and compute the full list of stocks I own from these ETFs in dollar value. Sort by larger to smaller. Also compute the industry with that. You need to write Vanguard download (harder, need to scrape), and iShares download (easier, CSV).
  • Directive abstraction: Add directives should be able to enumerate they accounts. Maybe add a get_accounts() method to the base namedtuple or create a mixin. Remove getters.get_accounts() and getters.get_entry_accounts() if you have this, lots of code goes away, probably a good idea.
  • Try to run the tests using ‘watchr’, ‘sniffer’, ‘autonose’ or other such tool.
  • Look at Intuit’s service for financial hub for financial data. Look for a developer account.
  • Do a presentation at meetup… Yodlee is in NY, might make sense.
  • New plugin: clean_payees, that processes the payee strings and cleans them up for display. How well can we do?
  • New plugin type: a kind of spreaded Pad directive, that creates multiple pads at regular intervals. This is to deal with smooth cash distributions or work meals assignment. You should be able to specify the frequency and have it automatically insert a number of entries to spread the expense evenly. ‘evenpad’, ‘multipad’, ‘distribution’? This should most definitely be a plugin.
  • I think if you relax the assumptions about having open and close accounts, those could even be moved to a plugin. Without this ‘open_close’ plugin, accounts would just get auto-created and no error output if they weren’t. With the plugin, we would have current strict behavior. This means that non-plugin code that requires the full set of accounts from a list of entries would not be able to rely anymore on the presence of open entries, and so would the validation.
  • Put all the Pad into a single file as a plugin, same with Open Close, and Balance. Maybe we can organize those codes to be all localized in single files, and for many of these features, they can be implemented in self-contained plugins with all their codes together! openclose.py, pad.py, balance.py, etc. I think even ‘event’ directives can become those. And maybe a good way to disambiguate between ops adn plugins is just this… maybe ops is non-plugins, e.g. prices, summarize, etc.
  • Make the plugins able to register types with the parser… this should allow the parser to call back on the plugins to create the appropriate types… this means true extensibility throughout! This is a fantastic idea… do this after v2 ship. Maybe they get parsed as a special “Unknown” directive that accepts a grab-bag of strings and tags and accounts and amounts and they get replaced by the plugins; whatever Unknown trickles through would generate a warning in the errors.
  • Setting the filename on options_map might help in making document processing also as a plugin.

(review types)

  • COOL! I can subclass the namedtuples! Do this to make printing the postings and entries much easier.

    class Posting(_Posting): def __str__(self): return _Posting.__str__(self._replace(entry=None))

  • Also derive from namedtuple to provide a stable hash function instead of code in beancount.core.compare.
  • Prices: Write a script to output the timeline of required prices/rates in the database. Then use it to drive fetching a historical table of monthly or perhaps weekly exchange rates for USD/CAD, USD/AUD, EUR/USD since the beginning of my file. Make this script reusable.
  • Create an index page for all the possible reports, from the web page
  • plugin: Consider creating a plugin that would auto-create accounts not seen yet, for the purpose of making demos. Definitely must do.
  • parser: Make tags and payees “tagged strings”, with their own data types. You can derive from str.
  • Rename “events” to “register”? This makes a lot of sense.
  • Write doc about stages of life, “climbing the mountain.”
  • Make the web application accept colons in URLs, and make the reports use them too, so that their names are the very same as those on the command-line.
  • Unrealized gains should not be added if the gain is zero.
  • In the ‘print’ report, add a comment at the end of each posting line with the balancing amount! This is an important debugging tool! Make this happen.
  • Make implicitly derived price directives generated by a transformation, as an explicit price directive.
  • (avg cost) To implement this, move all balancing to a stage after the parsing stage. Balancing the entries should be running right after parsing and will need to do a partial realization for the affected accounts only, for the postings with average cost. But in any case, all the balancing should move to a stage right after parsing and should not be an optional stage.
  • Remove legacy support for PIPE character in syntax, update cheatsheet.
  • For table rendering, move the actually formatting at rendering time. CSV files should have fractional values for percentages, txt and html should have % values. I need to figure out a good solution for this. Maybe the thing to do is to move the field selection at rendering stage, or at least to have it at both.
  • Create special make target to run tests on my own large Ledger. This should bean-check, bean-roundtrip, bean-bake / scrape.
  • Hmmm… compare does not actually allow two identical entries in a file. Solve that, using a differentiator, such as the fileloc or file no, or something. Maybe while reading we should insert a version number in duplicate entries automatially? Not sure.

    Another solution would be to warn on duplicate entries! Maybe we just don’t allow these. It really wouldn’t be much of a big deal. And this would be easy to implement as part of our load checks. They’re more often than not errors.

  • Summarize Ledger’s –limit –real –virtual –equity, etc. options.
  • Write a plugin to compute total tax/income
  • The balance sheet “close” problem - how do we specify closing at a particular point in time - can be solved by providing parameters to the report, e.g.

    balsheet:2014-01-01:2015-01-01 income:2014-01-01:2015-01-01

    Of course, this needs conveniences. The period, if there is only a SINGLE ONE, should be interpreted as “from the beginning of this period to the ending of it (one over)”. Otherwise, the meaning is the beginning of both. Here are other illustrative examples:

    balsheet -> from BEGINNING OF TIME to NOW balsheet:2014 -> from 2014-01-01 to 2015-01-01 (most common) balsheet:2014-05 -> from 2014-05-01 to 2015-06-01 balsheet:2014:2015-08 -> from 2014-01-01 to 2015-08-01

    The same goes for income. The nice thing is that I think we can now move the closing of entries within the report generation itself, instead of being at the top-level of the web app. This will be simpler and cleaner!

(plugins)

  • Pad could be a plugin, definitely.
  • Balance checks could also be a plugin.
  • It should be possible to make the parser accept unknown directives that accept an arbitrary list of accounts and string parameters, like this:

    2014-06-01 unknown Assets:US:CreditCard “Something”

(scripts)

  • bean-ledger: Write a script to convert to Ledger syntax. This should be easy!

    bean-convert -f FORMAT FILENAME

    • Convert to Ledger
    • Convert to HLedger
    • Convert to Penny

    Add an option to anonimify account names and perhaps some amounts as well.

  • bean-format or bean-align: Write a script to autoamtically align a region’s transactions, or an entire file.
  • bean-query accounts: make a report that prints out just the chart of accounts using the list of parser entries, just the open entries, ‘bean-query accounts’
  • bean-query currency_dates: Write a script that will automatically fetch the dates I held various positions at cost for throughout the history and a list of weekly dates to fetch rates for. LedgerHub could use that to fetch all the prices it needs at reasonable intervals.
  • (code) Make Position into a namedtuple with hashing instead of just an object. See if we can remove its __hash__ method.
  • Also, look at all the objects in b.core.data, and see if you can override the hash function on them automatically in order to ignore the entry in postings, and the listness in entry.postings. It would be nice to be able to hash every directive type.
  • Does table.render_table support offsets for rendering regular tuples? It really should.
  • Check out bitbucket CGI interface w.r.t. linking to source code, is the newer hg better? We should be able to link to specific lines in versions.
  • (idea) An interesting constraint would be to add an option not to allow any postings to any account that is not a leaf account.
  • (filter) Idea: For “virtual postings”, you could mark certain tags to be excluded by default, to be included only explicitly. e.g. #virtual tag would have to be brought in by selecting it via “tag:virtual”. Maybe a different prefix would be used to distinguish them, e.g. #virtual and %virtual, or #virtual and -#virtual; something like that.
  • (filter) Replace bean-holdings by “bean-query holdings”, where “holdings” is just another type of report. All the reports from the view pages should be mirrored exactly in the command-line interface.
  • (high priority) Implement a debugging command in bean-doctor, that spits out the entries that were created from the input file, as it is being parsed. This should include auto-posting values, inserted price directives, and attached tags. This would be a powerful tool to help people debug problems with parsing, or not understanding its effects!
  • web: Don’t render the full Inventory’es; instead, already render at cost and provide their full detail either by clicking on the transaction, which should render the full detail of an inventory (for debugging), or in a tooltip.
  • Write a script that will highlight some “payee vs tags vs subaccount” invariants:
    • Highlight payees that are always used with the same accounts
    • Same with tags
  • Write a script to align numbers… it has been too long and it’s quite annoying indeed.
  • tree rendering: If a parent account has only a single subaccount and the parent account otherwise has no postings in its realization, render the account on a single line instead of two, e.g.

    Expenses Expenses Taxes Taxes US US TY2014 TY2014 State State:Company Company … …

  • Plan for integrating rendering and filtering between web/HTML and text versions:
    • Filtering: Should be done in a library used in common with the web server and a new tool, bean-query, which provides a command-line interface to trigger filter, e.g. filter by year, filter by tag, etc. The point is that the same code that does the filtering for views should be run from this command-line. The code that creates views perhaps should be moved to begin that library.
    • Rendering: The web reports, such as beacnount.web.journal, beancount.web.acctree, etc. should move to beancount.reports and have HTML and text versions of all these.
  • Implement –brief option on scripts.holdings, to be able to share, which renders only % holdings.
  • journal rendering: When multiple transactions occur in the same day, it may make sense not to render the balance amount until the last one. Test it out.
  • validation: We should check that entries created by plugins at some initialization point are pointing to the right parents (or maybe we should relax the need to set the parent and make that routine set it all at once: time this, it it’s very small, do this on initialization and that makes it easier to write plugins for users and you can do away with entry_replace().)
  • bake: Make bake support curl if wget is not available. It should work with either, to relax dependencies.
  • Price entries should have an extra attribute to disambiguate between implicitly created prices, linking to the original transaction that created them, and explicitly created ones.
  • A table of price entries should be rendered under the price graph in the web interface.
  • Web interface: Instead of rendering inventories with the full contents in the journal, render the cost, and place the full inventory in a tooltip!
  • Here’s how to improve booking against lots!

    “Dealing with average cost trading or cost basis readjustments (not implemented yet) involves joining together multiple lots and recreating new ones in a way that preserves the total cost in the inventory; with this data structure / model it’s quite obvious how to implement them as basic operations on an inventory.

    I really like the simplicity of this and am wondering if we could make it even simpler.

    Automatic booking against an inventory, e.g. adding automatic FIFO or LIFO, would require having the date of each lot always inserted in the key of the inventory items (from the transaction, not from the lot-date field), along with special rules for selecting which lots a posting is allowed to modify, essentially ignoring the lot-date from the inventory if the posting does not specify it. This is partly why I’m considering making the “lot-date” compulsory and adding a “lot identifier” used to disambiguate booking against an inventory with multiple matching lots of the same cost with just differing dates, which would only be required if the posting constrains it to. One can imagine relaxing the matching rules between a posting and inventory further to allow one to just specify “-40 HOOL” above, without a cost, and if unambiguous, to allow it to just select the only lot that is available.”

    Idea: Generalize lot-date to just a “lot” string. Doesn’t have to be a date at all! It would also make the concept and usage intentions clearer I think.

  • Lot improvement: the lot specification on a reducing posting is only present to disambiguate which of the lots to reduce or match against. Maybe we should provide a different syntax when an expected reduction takes place, this would be allowed:

    (augment) 2014-06-17 * Assets:US:Investing:HOOL 10 HOOL {523.45 USD / i-want-more}

    (reducing) All of the following should be allowed: Assets:US:Investing:HOOL -7 HOOL ; possibly ambiguous Assets:US:Investing:HOOL -7 HOOL [] ; possibly ambiguous Assets:US:Investing:HOOL -7 HOOL [523.45 USD] Assets:US:Investing:HOOL -7 HOOL [2014-06-17] Assets:US:Investing:HOOL -7 HOOL [i-want-more]

    By enforcing a distinct syntax, the user is telling us that this leg is expected to reduce an existing position. This information is useful, in that it avoids possible mistakes. I like the explicitness of it.

    Sufficient debugging output should be provided from the “print” command to be able to identify which lot is being matched against and why. We need to provide more transparency into this.

  • FIFO or LIFO booking could be “enforced” simply by declaring the expected booking method of an account, and then issuing an error when explicit entries deviate from that method. This is an easy idea… would be very useful. The automatic method would only be used to resolve ambiguity! This is nice.
  • Implement a little plug-ins system that allows a user to insert a TAB in bean-web.
  • The Trial Balance page could be a good place to put all the accounts on the left and have two sets of columns: beginning of period -> end of period.
  • Implement a little plug-ins system that allows a user to insert a new tab in bean-web, with custom display.
  • In ledgerhub, use /usr/bin/strings as a last resort if all other PDF converters fail.
  • When we import, if a file was not detected, don’t spit out an org text line. Still doesn’t work.
  • In order to implement .txt output, you will need to decouple the web rendering and the generation of its included data. This will be great–ability to cut-and-paste any page into txt. format=txt, and we could still have the links clickable. Everything else would just be txt. A bit of a crazy idea, but it might work well and be simple. Maybe.
  • Bug: A transaction like this fails to parse; allow it: 2014-02-22 * “Payee” | ..
  • Serving CSV files from the Documents page should not be via download, but rather rendered directly.
  • The documents web page should render by-month + date, and by-account + date.
  • DO implement output to text NOW for posting on the mailing list.
  • Add views for the last 5 days, one day only each day (for D.Clemente)
  • Add preliminary support for renaming root accounts, even if that means the option must come first in the file. Move the checks in the parser.
  • In rendering balance directives, don’t render the amount in the “change” column; that is too confusing for some users, keep the change column for changes.
  • update activity: remove parent accounts with no child accounts.
  • update activity: this exhibits a bug in the table rendering, look for IVV, see TODO(blais) in acctree.py
  • Begin user documentation in earnest; we really need this soon.
  • Complete example file with income statement transactions.
  • URGENT - Provide some tooltip or help link from the main page to allow discoverability of what a “view” is.
  • URGENT - the level1/2 views are EmptyView’s, you need to implement those!
  • Example files (suggestion from Daniel Clemente):

    > > I think 2 files can be helpful: > > > > 1) A simple one, a „how to“ file with ~20 transactions, or better, from 1 to 3 transactions for feature. To show the normal things like receiving a salary, getting money from ATM, wire transfer, pay the bills, … So that it does not scare people without experience in double accounting. > > demo.beancount fits this place. > > > > 2) The big one (1 year, you said), to show off that beancount is powerful and is really used for long-term accounting. This one is the „inspirational“ one, to make people say „I would like to do that!“.

  • beancount: GREAT IDEA: output a subset of transactions as a spreadsheet. You need to design a textual way to refer to a subset of transactions. Output in either directions, without currencies.
  • Create a 3rd-party dependencies building script for Mac OSX users (fxt).

(Cost Basis)

  • Cost basis issue: How do I take into account the commissions and fees adjustment on the cost basis for a position?
  • How do I take into account Wash Sale Adjustments to the cost basis?
  • entries_table() really should be called postings_table().
  • You need to validate the account name options (empty, or no :, use regex to constrain).
  • Move utility functions from bean-prices to a reusable place.
  • Have another script that takes that as input and spits out current positions in the market on a web page; CGI script, should be served on Furius. Update via a Mercurial repo push.
  • Render tags
  • IMPORTANT FEATURE: Text/XLS exports
  • IMPORTANT FEATURE: Flip balances for rendering
  • IMPORTANT FEATURE: Implement Average Booking for Vanguard & RBC Adjustment, with associated tests and syntax in the parser. Update for inventory.py:

    def average(self): “”“Merge all lots of the same currency together at their average cost.

    Returns: A new instance of Inventory, with all the positions of each currency merged together at cost, bringing all these positions at average cost. “”” logging.warn(‘FIXME: continue here, this will be needed to report positions’)

    units_map = defaultdict(Decimal) costs_map = defaultdict(Decimal) for position in self.positions: lot = position.lot

    cost_currency = lot.cost.currency if lot.cost else None key = (lot.currency, cost_currency) units_map[key] += position.number costs_map[key] += position.get_cost().number

    inventory = Inventory() for lotcost_currencies, units in units_map.items(): lot_currency, cost_currency = lotcost_currencies cost_number = costs_map[lotcost_currencies] inventory.add(Amount(units, lot_currency), Amount(cost_number, cost_currency), allow_negative=True)

    return inventory

  • Render the OFX / QBO files in a <pre> tag, or figure out why the mimetype is incorrect and they don’t render properly. Right now the default rendering of the browser is insufficient.
  • (IDEA) Why aren’t we using the price on the first leg of this transaction? This is an interesting variation on the meaning of the price: it could mean either (a) the price of the lot, or (b) the conversion price of the cost of the lot. This would enable the following:

    2013-07-22 * “Bought some US investment in a CAD account” Assets:Investment:HOOL 50 HOOL {700 USD} @ 1.01 USD ;; 35350 CAD Assets:Investment:Cash -35359.95 CAD Expenses:Commissions 9.95 CAD

  • Remove the parsing of “CHECK” at some point, that was just there for compatibility.
  • More testing:

    #

    #

  • Add a validation check, that when closing and account, its balance is empty/zero.
  • Render a journal as a detailed expense report, for a set of accounts (e.g., Expenses:*) pulling out amounts in various columns based on other expressions (e.g. Assets:Cash:Caroline).
  • Idea around documents: A link between a transaction to a document can be created by associating a document’s checksum as the link of the transaction. If Beancount could associate them - and it could, it has access to the document files and the corpus of transactions - the web interface could insert a special link between the two. Maybe we could do the same thing with the filename as well.
  • A better idea to do this would be to allow specifying an explicit document directive, and finding document directives from files that are already specified should not re-create them. This way you can specify both the document and a transaction and use a common link as a natural way to associate them, e.g.:

    2014-06-20 document Income:US:Employer:GSU “2014-06-20.employer.0000000.pdf” ^ee63c6fc7aa6

    2014-06-20 * “PAYROLL” | “Refund for fractional shares” ^ee63c6fc7aa6 … …

  • Document finding from files should not create documents that have been explicitly specified in the ledger. Avoid duplication! This is an important fix to make, that will allow both to co-exist together.
  • Implement beancount.plugins.tag_pending as a general feature of links… this ought to be built-in by default, this is a great idea.
  • (prices) When attempting a conversion in holdings, if the rate isn’t available directly, you should always attempt to value it indirectly via USD or EUR.
  • Allow short sales eventually. This should already work if all that you do is selectively suppress the validation check that verifies that a position at cost may not go negative. We could selectively suppress it by adding a flag to the open directive associated with an account, or maybe adding some special syntax in the cost specification that allows us to do this.
  • Create a new directive for balance that checks for the complete balance. Ideas for syntax:

    2014-06-20 balance Assets:Some:Account 10 HOOL, 640.40 USD FULL 2014-06-20 balance Assets:Some:Account [10 HOOL, 640.40 USD] 2014-06-20 balance Assets:Some:Account <10 HOOL, 640.40 USD> 2014-06-20 balance* Assets:Some:Account 10 HOOL, 640.40 USD 2014-06-20 full_balance Assets:Some:Account 10 HOOL, 640.40 USD

    Maybe we should define a general syntax for input’ing an Inventory object, that could be read at parsing time.

  • Create a command in bean-doctor which lists all of the lots and their changes for a particular account. This is meant to be a debugging tool for booking algorithms. The rendering should be clear and detailed.
  • Implement a “fuzzing” input generator, that will output a very large input file with all possible kinds of combinations, to see where Beancount hits its limits and perhaps bring up some bugs from input I haven’t thought of. This is easy and fruitful.
  • Replace gviz by some other library that does not require you to be online.
  • Add the acquisition date of each lot to each Holding, and it should be output at that date by print_holdings as well.
  • In order to relax the constraint that you may not add negative units at cost, we could only disallow under certain circumstances:
    • An account has received units in the opposite direction
    • If the posting cross the zero boundary. Maybe starting from zero in either direction could be fine.
  • Idea: You could add a further constraint property to an account name: that the amounts may never be allowed to balance to a particular sign. This could be useful to avoid data entry mistakes. You could even write a doc just focused on all features designed to avoid data entry mistakes.
  • Idea: Relax checks for negative values: from docs

    “PLEASE NOTE! In a future version of Beancount, we will relax this constraint somewhat. We will allow an account to hold a negative number of units of a commodity if and only if there are no other units of that commodity held in the account. Either that, or we will allow you to mark an account has having no such constraints at all.”

  • You could make the narrations for padding and summarization transactions specifiable via options.
  • Silence BrokenPipeError errors from bottle using wsgiref. You could use CherryPy, which doesn’t suffer from that, or just… fix it and silence them.
  • (sanity check for conversions) Insert a validation check when transferring amounts to the balance sheet that the implied rate of the conversion entries is within certain bounds of the price, for each pair of commodities (find a way). These bounds should be proportional to the variance of the price. This would just provide an extra amount of good fuzzy feeling, knowing for sure that my solution to the conversions problem is always meaningful and correct.

Internal: Review Dependency Graph

As I’m moving to a system with more plugins and less code in the core, and with the intermediate reports stage instead of just the web interface, it’s becoming clearer where some files need to move.

  • Make various attempts to simplify depgraph, we want to ship with a really lean dependency graph.
  • ops & plugins should not depend on parser…
    • Move beancount.parser.options to beancount.core.options
    • Move beancount.parser.printer outside parser, ideally, or just factor the dependencies separately.
  • If you want to be consistent with the script names, rename beancount.reports to beancount.report. This way, bean-* matches a single package name. Just saying.

    Also, in the same vein, move beancount.scripts.query to beancount.scripts.query, either that or move the starter script for bean-web to beancount.scripts. One or the other. I prefer the former.

  • Emerge a principle for where the following files should separate, or merge the two modules:

    beancount.ops.* beancount.plugins.*

  • beancount.core.realization: Look at deps for beancount.core.realization and move it upstream where it makes sense, maybe ops.
  • beancount.core.getters: Should this move to ops as well? Check the dependency tree, see if it makes sense.

Code Quality

  • Configure more pylint tests and make them pass. We’re using a small subset at the moment.
  • Require Python 3.4 and introduce Enum’s where relevant.
  • Install flake8, PyChecker, pep8 after pylint passes, run all of them.

Core

General

  • Make all imports outside of packages import from the package root, and have the package export those symbols explicitly.

Inventory

  • Inventory: Implement a test for Inventory.get_amounts() with multiple lots of the same currency; they really should have been aggregated.

Book at Average Price

  • Inventory: Implement averaging of lots in order to report positions nicely.

Making adjustments of capital

  • Figure out how to make these kinds of adjustments:

    My name is Ian and I will help you with profit/loss and book value reporting. 2013-04-19 RTC RR – XSP – ISHARES S&P 500 INDEX FUND (CAD-HEDGED) 2012 RETURN OF CAPITAL ADJUSTMENT TO BOOK COST $60.71 2013-04-25 ADJ RR – XSP – ISHARES S&P 500 INDEX FUND (CAD-HEDGED) 2012 NOTIONAL DISTRIBUTION ADJUSTMENT TO BOOK VALUE $2,963.13 Before you make accounting entries, it is a good idea to understand the underlying transactions.

    ETFs such as XSP, make distributions throughout the year, however they do not know the composition of the income distributed until after year end when the trust completes their tax return. When the income in the trust from dividends, capital gains, and income are not sufficient to account for all the distributions, the excess distribution is classified as ‘return of capital’. Return of capital (ROC) is simply some of the capital you paid to buy the fund being returned to you. The ROC amounts are not taxable and you deduct them from your XSP book value. The XSP deduction for 2012 is C$60.71 and should be deducted from your book value in your April 2013 statement.

    Notional dividends result from the exchange traded fund (ETF) realizing capital gains and/or dividend income then reinvesting the gains/dividends in some other security(ies). No cash or reinvested units were distributed to investors but they still have to pay tax on the gains/dividends realized within the ETF. When a notional dividend is made, the dividend is included in income and the amount of the notional dividend is added to the book value of the underlying security. So you end up paying tax on the dividend up front and get a reduced capital gain or increased capital loss when you eventually sell the ETF.

    In your XSP example, if you held the ETF in a taxable account, the notional dividend would be fully taxable as C$2,963.13 income for your 2012 return. Your book value would increase by C$2,963.13.

    The book value of XSP for 4,100 units in your March 2013 statement was C$57,127.11. The return of capital reduces your book value and the notional dividend increases it so your book value at the end of April 2013 would be C$57,127.11 - C$60.71 (return of capital) + C$2,963.13 (notional dividend) = C$60,029.53.

Lots

  • Matching on Inventory Lots should be loose: try to match automatically against the most SPECIFIC lots.

    (AAPL, 18.45, nil) -> +1 (AAPL, 17.93, nil) -> +1 (AAPL, nil, nil) -> -1 … should choose any of the inventory

    Also, maybe the inventory’s date should be filled in automatically by the parser… just an idea. Maybe date doesn’t have to be allowed to be nil.

Original Idea Description for Integrating the Cost Basis in Beancount

  • Every account carries a cost basis.
  • You can have posting with or without a cost-basis.
  • If the posting has a cost-basis posting, the cost-basis is used to balance the transaction.
  • As you sum up the postings in the account, keep track of the full inventory as

    (commodity, cost) -> quantity

    As a special case, “cost” can be null. This is the case where there is no cost tracking for this commodity item. We maintain the full inventory of positions with a cost basis in the account; as a default case, the cost is null.

  • BALANCE CHECK: When balancing a transaction, if an amount has an associated cost basis, use the cost basis instead of the actual amount to balance.
  • INVENTORY CHECK: When a position is modified in the inverse direction, require a cost to book against. If no cost is specified, it just degrades to decrease from the bucket of commodities with a null cost (it all works out!)
  • ZERO CHECK: Insure that the quantity can never be negative for any bucket.
  • Optional extended check syntax: You could extend the @check syntax to include the cost, so that technically you could check that there are a specific number

2013-03-01 * buy Assets:Checking 10 HOOL # 700 USD Assets:Investment -7000 USD

2013-03-15 * sell Assets:Checking -10 HOOL # 700 USD @ 800 USD Income:RealizedPnL -1000 USD Assets:Investment 8000 USD

Syntax

Test: Items of the same kind with and without cost basis Test: Multiple items of different types with a cost basis in the same account

Realization

  • You need to convert some of TestRealization to TestCheck.
  • Whether an account shows up in a particular Ledger (realization) really only should depend on whether the account was open during the period (we now have account open/close dates… let’s use them instead of a heuristic!). Create a routine to figure out if an account was open during a specific time period?

Average Price Booking

  • You now HAVE to implement average price tracking… not an option. Thanks to Vanguard #$(*#(*$.

Prices

  • There should be a corresponding view/presentation for rendering information that we have about prices.
  • Build helpers tools for users to create their own scripts that will allow you to spit out a list of prices for the price DB.
  • Include directives will be necessary for update, because it will enable including the file of prices only. The prices should be in beancount language too, this should all be a single file format.

Filtering

Beancount reorg

  • Remove subaccounts for TMobile and employer once we have filtering working out nicely. Same with RedSquare electricity. Same with Employer subaccounts for taxes.

    Payees are just like tags!

Views

  • Replace all views by filtering queries… the root page should still have convenient links to various preset views, like the last five years, but these links should be implemented using the filtering query feature! Maybe it’s worth allowing the user to specify common queries in the options map, and provide links to them. Do this, and try removing some of my subaccounts to simplify the accounts-trees somewhat.
  • The root page should feature a prominent input form that allows the user to specify a query! This input needs live at the very root
  • (views) You should be able to filter to all transactions related to some account, e.g. Immigration
  • IMPORTANT! Try to let through some of the non-transaction entries in the view filtering. We obviously cannot let through balance entries, but documents yes, depending on the type of filtering. We should do our best to let all the entries carry through.

Filtering dimensions (Old Notes)

  • By Country
    • You should be able to look at only accounts with a particular pattern (and their other legs), e.g. :CA:
    • You perhaps should flag all the transactions that have a particular unit (e.g. CAD)
  • By Account Prefix
    • Specify a single account, and automatically select all the other accounts which are linked by any transaction in this account; generate a balance sheet from this list of accounts. e.g. Expenses:Trading, Income:PnL, Assets:Trading.
  • By Amount Size
    • I’d love a way to filter down a journal by omitting all the small items and keeping just the larger ones, to get an automatic overview of the large amounts in a long series of transactions. All the small amounts could be lumped together under a special entry.
  • By Institution
  • By Country
  • By Tag
  • By Payee
    • You should be able to click on a payee to view its transactions.
  • By Date
    • You should be able to click on dates and see all postings around that date too, e.g. +/- 10 days. Another simple and useful filter.
  • By Event (defines a period)
    • “How much did I make during the period of this event”, e.g. while I was working at CompanyX, while I was in school at UniversityY. This provides two dates, generate a view for them:

      /view/event

      This could sum up all the entries for all the internals where the event’s value was the same.

  • By Currency/Cost-Currency

    You could then possibly compute the IRR around that commodity…

Custom dimensions

  • From discussion:
    (digression not about virtual postings but answers auxiliary questions about
    them)
    Now this points to a more general idea that I’ve been pondering for a while:
    these “accounts” can often be seen as a set of flat dimensions, the fact that
    they have a hierarchy can get in the way. I tend to have accounts that look
    like this:
    TYPE:COUNTRY:INSTITUTION:ACCOUNT:SUBACCOUNT
    like this, for example:
    Assets:US:HSBC:Checking
    Assets:CA:RBC:Savings
    For these four dimensions, I actually like having most accounts (Assets,
    Liabilities and Income) specify them in this order. This does not always make
    sense though, especially for expense accounts; for those you wouldn’t really
    want to have a COUNTRY dimension at the root. You want the general category
    only, so I’ll have, for example:
    Expenses:Food:Restaurant
    Expenses:Food:Grocery
    but sometimes the dimensions get inverted too, like in my recent change about
    how to track taxation:
    Expenses:Taxes:US:TY2014:Employer:Federal
    Expenses:Taxes:US:TY2014:Employer:StateNY
    Expenses:Taxes:US:TY2014:Employer:CityNYC
    …
    Here the “institution” is your employer, and shows deeper in the hierarchy.
    Finally, you often do want to have multiple types for the same or similar
    accounts, for instance, to track gains and dividends income from a particular
    investment account, you want a mirror of most of the dimensions except for the
    assets bit:
    Assets:US:ETrade:IRA -> Income:US:ETrade:IRA
    For instance:
    Assets:US:ETrade:IRA:Cash
    Income:US:ETrade:IRA:Dividends
    You see what I’m getting at… these components really operate more like a
    database table with values possibly NULL, e.g.,
    type country institution account category
    -------- -------- ------------ --------- -----------
    Assets US HSBC Checking NULL
    Assets CA RBC Savings NULL
    Assets US ETrade IRA Cash
    Income US ETrade IRA Dividends
    Expenses NULL NULL Food Restaurant
    Expenses NULL NULL Food Grocery
    Having to order your account components in a hierarchy forces you to
    decide how you want to report on them, a strict order of grouping from
    top to bottom.
    So I’ve been thinking about an experiment to rename all accounts according to
    dimensions, where the ordering of the components would not matter. These two
    would point to the same bucket, for example (changing the syntax slightly),
    ExpensesTaxesUSTY2014EmployerFederal
    ExpensesUSEmployerTaxesTY2014StateNY
    You could then display reports (again, the usual reports, balance sheet,
    income statement, journals) for “the subset of all transactions which has one
    posting in an account in <set>” where <set> is defined by values on a list of
    dimensions, a bit like a WHERE clause would do.
    Now, now, now… this would be a bit radical, now wouldn’t it? Many of these
    accounts do point to real accounts whose postings have to be booked exactly,
    and I’m a bit worried about the looseness that this could introduce. One and
    only one account name for a particular account is a nice property to have.
    So what can we do to select across many dimensions while still keeping
    hierarchical account names?
    The first thing I did in Beancount is to create views for all unique account
    component names. For example, if the following account exists:
    Assets:US:ETrade:IRA
    You will see four “view” links at the root of the Beancount web page:
    Assets
    US
    ETrade
    IRA
    Clicking on the link selects all the transactions with a posting with an
    account where that component appears. (Views provide access to all the reports
    filtered by a subset of transactions.) You can click your way to any journal
    or report for that subset of transactions. This exists in HEAD today. You can
    draw all the reports where a particular component appears, e.g., “Employer”, as
    in “Income:US:Employer:Salary” and “Expenses:Taxes:US:TY2014:Employer:Federal”.
    But this does not define “dimensions.” It would be nice to group values for
    these components by what kind of thing they are, e.g., a bank, an instution, a
    country, a tax year, etc, without regard for their location in the account
    name. A further experiment will consist in the following: again assuming
    unique “account component names” (which is not much of a constraint to
    require, BTW, at least not in my account names), allow the user to define
    dimensions by declaring a list of component names that form this dimension.
    Here’s how this would look, with the previous examples (new syntax):
    dimension employer Microsoft,Autodesk,Apple
    dimension bank HSBC,RBC,ETrade
    dimension country US,CA,AU
    dimension taxyear TY2014,TY2013,TY2012,TY2011,TY2010
    dimension type Assets,Liabilities,Equity,Income,Expenses (implicit?)
    You could then say something like “show me trial balance for all transactions
    with posting accounts where bank is not NULL group by bank” and you would
    obtain mini-hierarchies for each group of accounts (by bank, across all other
    dimensions).
    (With the state of my current system, I could probably code this as a
    prototype in a single day.)
    Addtionally, accounts have currency constraints and a history of postings
    which define a set o currencies used in them. More selection can be done with
    this (e.g., show me all transactions with postings that credit/debit CAD
    units).
    IMHO, all you’re trying to do with these virtual accounts is aggregate with
    one less dimension, you want to remove the real account and group by community
    project. My claim is that there are ways to do that without giving up o the
    elegant balancing rules of the DE system.

    In ealtion to this… these “dimensions”, could they just become other dimensions in the filtering language?

    component:Microsoft

    employer:Microsoft bank:RBC country:US

    You can then break down by those, like a GROUP BY clause, and generate reports that have those as root accounts, or separate breakdowns.

Tags used as dimensions

  • If you had tags as key-value pairs, those could be used as well:

    2014-05-21 * … #employer:Microsoft

    Searching for:

    tag:employer=Microsoft

    This is another dimension in the same filtering language.

Language

https://docs.google.com/document/d/1d88MkHqxiVdF8XSQBT1QQpOKEOt6OC1P9ZoF3u86DwI/

Operations

Validation

  • Write a dedicated routine to check the following invariant:

    check_is_at_beginning_of_day = parser.SORT_ORDER[Check] < 0 … if check_is_at_beginning_of_day:

    if isinstance(entry, (Check, Open)): assert entry.date > prev_date, ( “Invalid entry order: Check or Open directive before transaction.”, (entry, prev_entry)) else: prev_entry = entry prev_date = entry.date

  • Sanity check: Check that all postings of Transaction entries point to their actual parent.
  • (validation) In addition to the Check/Open before-constraint, check that the entries are always sorted. Add this sanity check.
  • The default validation should check the invariant that Open and Check directives come before any Transaction.
  • Validation: Everywhere we have a filter of entries to entries, we should be able to apply a check that the total balances before and the total balances after should have the very same value.
  • In validate.py: differentiate between the case of an entry appearing too early before an Open directive, and an entry appearing for an account that simply just doesn’t exist.
  • Auto-detect and warn on likely duplicate transactions within the file.

Conversions

  • TODO: Try it out in Ledger, see how they deal with it.
  • Make the conversions entry use a price of zero, to maintain the invariants for sanity checks, something like this:

    YYYY-MM-DD * “Annul conversions at end of period” Equity:Conversions -56383 CAD @ 0 CONV Equity:Conversions +67000 USD @ 0 CONV

Open/Close

  • You must issue an error if you close an account that’s got a non-zero balance!

Padding

  • Idea: Padding entries could be extended a tiny bit in order to automatically calculate the cash distribution entries, e.g., like this:

    2014-03-04 pad Asset:Cash Expenses:Restaurant 60% 2014-03-04 pad Asset:Cash Expenses:Alcohol 40%

    2014-04-04 pad Asset:Cash Expenses:Restaurant 70% 2014-04-04 pad Asset:Cash Expenses:Alcohol 30%

    2014-05-04 pad Asset:Cash Expenses:Restaurant 70% 2014-05-04 pad Asset:Cash Expenses:Alcohol 30%

    This is a great idea, is in line with the general meaning of pad entries (implicit 100%) and would add a much desired feature.

  • Add tests for all the cases of realization padding.

Locations

  • @location really should just convert into a generic event “location”, just as address and school should; they’re just events with forward fill… Serve this at:

    http://localhost:8080/20120101/20130101/events/location/days

  • Add a “reason” field for @location, and display as trips, with some sort of meaning to them. Ok, this contradicts the previous idea.

Payee Elision / Auto-Account Leaf Name

  • About the discrepancy between the concept of “Payee” and a superfluous lead account, e.g. Internet:TimeWarner, which typically contains only transactions from that payee: maybe we can elide the account name if it contains only a single payee, or perhaps a warning may be issued? I don’t know.

    Basically, it would be nice to be able to have multiple payees in the same category over time (e.g. Electricity, Internet) but to be able to separate them somehow, without having to put the payee into the name. This is a little fuzzy, and I’m not sure how to do it, because the imported payee names are often not very clear and often truncated as well.

    Have you ever thought that Payees often end up functioning like an extra subaccount? I’ve come to realize that for Payees that only ever touch a single account, the line is really fuzzy there. I’ve been entertaining the idea of automatically creating subaccounts for payees like that.

Parser

Errors

  • We need to gather errors in a single place and report them like the others; right now I’m catching them in sum_to_date() and writing using the logging module; but they really should be trickled up with the rest.
  • Syntax errors currently have no location… this is unacceptable. Write an automated test, check for all kinds of errors, in the lexer, in the parser, in the Python. (Just work with the line number, we don’t really need character position.) Test everything with automated tests.
  • ‘lineno’ is incorrect, it points to the next entry, not the previous one, fix this bug! This is really annoying.
  • Set a correct filename in grammar.y
  • Errors from the parser and others should all be accumulated in one place, so that we do all the reporting at the very top level.
  • Don’t raise error exceptions anywhere; log everything to an error handler/accumulator class instead, and skip to the next entry/declaration.
  • Propagate exception from Python(?)
  • Problematic transactions (!) should spit something of color on stdout, they should not be forgotten so easily.
  • When using @@ the signs should match; warn if they don’t
  • Bug: Invalid account names should only be reported once.

Lexer Work

Errors in Flex Lexer

  • (parser) Support enabling flex debugging in beancount.core._parser.parse(), using “yyset_debug(int bdebug)”.
  • When an error occurs, skip the lexer to the next empty line and recommence.
    • Modify the lexer to emit EOF and add that in the grammar rules for empty_line.

Write a New Lexer From Scratch

Reasons to write your own lexer manually:

  • Should support UTF-8 encoding.
  • Should support SCHEDULE entries for org-mode (see email discussion).
  • More flexible syntax (see “Is it possbile for beancount to ignore org-mode SCHEDULED and DEADLINE?” thread).
  • Better error reporting
  • (performance) Write your own lexer manually and compare performance with flex one. I think we can do a much better job at error reporting by writing our own, but I’m unsure how the performance compares.
  • IMPORTANT LATENT ISSUE. You need to extend the lexer to parse A-Z for flags, not just PSTCU! This is important, as I just realized that it could prevent the correct parsing for entries in a round-trip, with postings produced with unexpected flags. In fact, any character with whitespace on each side should parse as a flag. This is very important.

    This manifests when adding a posting with letter ‘M’ right now. Replicate this, fix the problem.

Make the Parser Reentrant

Options

  • FIXME: We need to parse the options using the same argparse parser....

Syntax

  • You should support a payee with no description! This generates a parser error right now.
  • Allow ‘$’ as currency symbol, don’t translate to anything, it can just stand on its own as a unique kind of currency, it doesn’t matter, no changes anywhere. Also add the Euro, GBP and yen symbols.
  • The syntax should support multiline strings naturally…
  • For Links vs. Tags: dont impose an order, parse as tags_or_links. Right now the order is tags_list and links_list.
  • You should accept commas in the input; simply ignore their value.
  • Add 1/rate syntax for prices (and anything… really, why not). Convert at parsing time.

Includes

  • With the new format… support includes, it makes a lot more sense to do that now! People want this too.
  • Idea: an include directive should have a “prefix” option, to add a prefix to all accounts from the included file.

Sensible Syntax for Lots

  • Consider making the lot syntax like this:

    -4 {HOOL @ 790.83 USD}

    instead of:

    -4 HOOL {790.83 USD}

    It’s actually a lot more accurate to what’s going on…

Performance

  • Implement “D” in C, it’s worth it. This should make a substantial difference.
  • Test using the empty case of list parsing to create the initial empty lists instead of the conditional in Parser.handle_list() and measure, to see if there is a significant difference in parsing performance.
  • Parser performance: try not calling back to builder for simple types that just return their value; measure the difference, it may be worth it, and we wouldn’t lose much of flexibility, especially for the lexer types, which are aplenty.
  • Write the builder object in C… it won’t change very much anymore, and that’s probably simple enough.
  • Check the performance of D(). I suspect improving this routine could have a dramatic effect on performance.

Documents

  • IDEA: Create a plugin that will convert “doc:” metadata to a document file, that will search for a unique string name in all the filenames and associate the filename with this directive via a link or something.
  • Write a proposal for implementing a transformation on a specific set of transactions, that supports capital gains with commission taken into account.
  • Can we automatically add a ^LINK to the document directive in order to associate a PDF with a document?!? -> For trade tickets. Maybe let the modules provide a import_link() function on the associated PDF files? (This is related to ^64647f10b2fd)
  • Adding the ability for links on document directives was also requested on the ledger-cli mailing list.

    On Sat, Apr 26, 2014 at 6:18 AM, Esben Stien <b0ef@esben-stien.name> wrote:

    “Craig Earls” <enderw88@gmail.com> writes: The first use in ledger-cli is to link each transaction to a document, which is pretty important in accounting;)

    Well no, not exactly. The thing you do in importing financial data is basically to funnel transactions from all of your statements from all your institutions in a single place in a single format with a single set of accounts, so that you can do reporting with a view of everything you have. Having support for a per-transaction link to a particular document is generally unnecessary–you can easily find the corresponding document by date if you need to.

    In order to associate a unique ID with a particular transaction, in Beancount you can use a “link” which is like a special kind of tag. I think Ledger has a similar feature, per-post (“tag”?). It looks like this in Beancount:

    2013-04-06 * “Invoice to Metropolis for job well done, waiting for payment.” ^metropolis-invoice-103 … …

    The “^....” bit is a link. You can have multiple links per transactions. The web interface can show you all transactions with the same link in a separate list (under the link.... URL).

    Separately, there is a “document” directive that allows you to associate a document with an account, e.g.

    2014-01-01 document Expenses:Electricity “/path/to/filename/ConEdison-2013-12.pdf”

    Documents don’t have to be declared that way explicitly: you can also tell Beancount about a root directory where it will find documents automatically and create the document entries for you. The files just have to be organized in a directory hierarchy mirrorring the account names exactly, and files must begin with “YYYY-MM-DD” to provide a date for the document. That’s a simple convention. LedgerHub is able to move files that it recognizes to such a file hierarchy, so after you import the data, you file the files into e.g. a local git repo with all your statemetns, and your document entries show up in the registers. It’s also a nice way to organize all your statements, so if you need to bring something up for e.g. a tax audit, you quickly know where to find it.

    Those two features are not related at the moment… but I think I’ll add the ability to have links on document directives. That seems like an effective way one could associate a particular pdf document (given a declaration) with a list of transactions. You click on the link, see all the transactions + the document, and you can click on the document itself to see the detail. Seems like a legit idea.

  • Auto-doc from directories of files should ignore files already associated via an explicit documents directive; just ignore files with the same absolute name.

Testing

  • Allow file objects to parse() and dump_lexer(). This should use fdopen() or whatever else to get this job done at the parser level.
  • You need to clean up the memory of the strings created; call free() on each string in the rules.
  • Add a unit test for pushtag/poptag errors.
  • Add unittests for tags, pushtag/poptag

Dated Postings

  • In order to create multiple similar transactions at many dates in one syntax’ entry, you could allow overriding the date on each posting, e.g.:

    2013-04-01 * Blah di bla 2013-01-01 Grocery 10 USD 2013-02-01 Grocery 10 USD 2013-03-01 Grocery 10 USD Cash

    This would create three transactions, with these dates:

    date aux-date 2013-01-01 2013-04-01 10 / 3.33 2013-02-01 2013-04-01 … 2013-03-01 2013-04-01 …

    Could be a nice way to make distributed transactions.

  • Move ‘effective date’ to the postings in my input file, using the dated postings feature.
  • Another idea would be to make @pad able to pad for a percentage of the total, so that we’re able to use @pad instead of “distribution of expenses” entries.

Metadata

  • If you add tags with values, you could define some special tags, like ‘document’, which could automatically try to find the corresponding document in the repository and insert a link to it in the web page. I already have a managed stash of document filenames… something like this:

    2014-05-20 * “Invoice from Autodesk” #document: 2014-05-20.autodesk.invoice200.pdf Income:US:Autodesk -3475.20 USD Assets:US:Checking

    A document filename that does not get resolved could spit out a warning in order to keep the file tidy. This is a nice idea… perhaps nicer than just insert entries for documents, an actual link. Not sure if it would make that much of a difference though. Something to ponder.

    Create a plugin that will convert “doc:” metadata to a document file, that will search for a unique string name in all the filenames and associate the filename with this directive via a link or something.

  • One idea Ledger uses well is the ability to associate key-values meta-data to transaction objects, a-la-Common Lisp. See the –pivot feature. It seems a bit superfluous at the moment, but may be useful in order to provide the ability to implement custom aggregations eventually, instead of using the strings. Maybe the payee could be a special case of this, e.g payee=”value”

    (From mailing-list):

    Take this example:

    2011-01-01 * Opening balance Assets:Cash 25.00 GBP Equity:Opening balance -25.00 GBP

    2011-02-01 * Sell to customer AAA ; Customer: AAA ; Invoice: 101 Assets:Receivables 10.00 GBP Income:Sale -10.00 GBP

    2011-02-02 * Sell to customer BBB ; Customer: BBB ; Invoice: 102 Assets:Receivables 11.00 GBP Income:Sale -11.00 GBP

    2011-02-03 * Sell to customer AAA ; Customer: AAA ; Invoice: 103 Assets:Receivables 12.00 GBP Income:Sale -12.00 GBP

    2011-02-03 * Money received from customer AAA for invoice 101 ; Customer: AAA ; Invoice: 101 Assets:Cash 10.00 GBP Assets:Receivables -10.00 GBP

    Now you can see how much each customer owes you:

    ledger -f d bal assets:receivables –pivot Customer 23.00 GBP Customer 12.00 GBP AAA:Assets:Receivables 11.00 GBP BBB:Assets:Receivables


    23.00 GBP

    And you can see which invoices haven’t been paid yet:

    ledger -f d bal assets:receivables –pivot Invoice 23.00 GBP Invoice 11.00 GBP 102:Assets:Receivables 12.00 GBP 103:Assets:Receivables


    23.00 GBP

Plugins

Stock Splits

  • Find a way to automatically create multiple currencies to account for stock splits. The user should not have to do this themselves:

    “One choice you have is whether you want to keep the same symbol pre and post split. If you keep the same symbol the price database will show a drop in price over time. If not, choose a new symbol for the post split period. So far in my own file I use the same symbol but I think eventually I’d like to find a way to differentiate them automatically and have a multiplier in the price database, because doing it manually is not nice. In any case both methods work.”

    Perhaps a directive could be created to declare them that would automatically insert converting transactions, but that makes it difficult to deal with weird cases, like oddly unequal splits (e.g. Google A/C), or cases with spinoffs, as below. Perhaps the splitting transaction should be inserted automatically, but that the split directive would just create a new currency name, internally.

    A currency would then be referred to by a pair of (name, date), and that would resolve to a internal currency name.

  • (IDEA) In order to create suitable stock split entries that would look like this:

    2013-04-01 * “split 4:1” Assets:CA:ITrade:AAPL -40 AAPL {{5483.09 USD}} Assets:CA:ITrade:AAPL 160 AAPL {{5483.09 USD}}

    You could easily add support for a directive that looks like this:

    2013-04-01 split Assets:CA:ITrade:AAPL 4:1 AAPL

    This would allow the user to do some processing specific to stock splits by processing the explicit stock split entries.

  • Include this in the user examples, + stock splits:

    2013-04-01 * “name change”

    Assets:CA:ITrade:AAPL -40 AAPL {{5483.09 USD}} Assets:CA:ITrade:NEWAAPL 40 NEWAAPL {{5483.09 USD}}

    2013-04-01 * “spinoff” Assets:CA:ITrade:KRFT -100 KRFT {{20000 USD}} Assets:CA:ITrade:KRFT 100 KRFT {{17000 USD}} Assets:CA:ITrade:FOO 20 FOO {{ 3000 USD}}

Wash Sales

  • (script) Write a script to check whether an account’s trades are subject to the wash sale rule (I need this for my personal stock plan):

    “An Internal Revenue Service (IRS) rule that prohibits a taxpayer from claiming a loss on the sale or trade of a security in a wash sale. The rule defines a wash sale as one that occurs when an individual sells or trades a security at a loss, and within 30 days before or after this sale, buys a “substantially identical” stock or security, or acquires a contract or option to do so. A wash sale also results if an individual sells a security, and the spouse or a company controlled by the individual buys a substantially equivalent security.”

    The wash sales amount should be reported in an account, and should be calculated as a plugin.

Strict Unused Pad Directives

  • The validation check that pushes an error on unused pad directives should be moved to a plugin, that should be optional. There is rationale for allowing to keep unused pad directives. Don’t be so strict, Martin.

Link Trades

  • Create a plugin that will link together all reducing transactions automatically. When a transaction reduces a position, both transactions should have a common unique link. This can all get done in a plugin!

Capital Gain Without Cost

  • Implement the proposal for putting the capital gain in the cost as a plugin that transforms the relevant transactions, those tagged as such. This will require some loosening of the booking method in order to make it easier to disambiguate a sale, and some good debugging tools as well.

    You could automatically look for the right amounts by looking at the signs. I think you could automate a lot of it.

Auto-Link Booking Transactions

  • Automatically create a link between transactions that book each other. I’m not sure how I’m going to implement that - perhaps in the lot matching, a hash to the original entry will be kept in the lot - but we should be able to update the links to all the transactions that book together.

    This will be a great debugging tool as well… a very powerful idea that can be implemented entirely in a plug-in.

Unrealized Gain

  • Find a way to pass in a plug-specific option via the file.
  • Unrealized capital gains could be inserted automatically into special sub-accounts, based on the current price and the cost-basis of particular accounts. This could be inserted automatically! e.g.

    DATE check Assets:US:Ameritrade:AAPL 10 AAPL {200 USD}

    DATE price AAPL 210 USD

    Assets:US:Ameritrade:AAPL 2000 USD Assets:US:Ameritrade:AAPL:Gains 100 USD

    The “Gains” subaccount could be inserted automatically if the price differs from the cost basis… this would be a clever way to represent this! We could even do this by inserting a transaction automatically with an offsetting account… actually this would be the RIGHT way to do this!

    We need an option to designate which subaccount leaf to create all the new transactions for:

    %option account_unrealized “Unrealized”

    2013-05-23 A “Booking unrealized gains for AAPL” Assets:US:Ameritrade:AAPL:Unrealized 230.45 USD Income:Unrealized -230.45 USD

    By doing this, the reporting does not have anything to do… it can choose to report positions at cost or in held units, and whether the gains are included or not entirely depends on whether these transactions have been inserted in or not.

Strict Average Cost Inventory Booking Checker

  • Build a plugin that will check that accounts with average cost inventory booking method only have such reductions in them:

    https://docs.google.com/document/d/1F8IJ_7fMHZ75XFPocMokLxVZczAhrBRBVN9uMhQFCZ4/edit#heading=h.m74dwkjzqojh

    “Another approach would be to not enforce these aggregations, but to provide a plugin that would check that for those accounts that are marked as using the average cost inventory booking method by default, that only such bookings actually take place.”

    This is, of cource, to be implemented only after implementing support for the average cost inventory booking method.

Tip Calculator

  • Write another example plugin that splits “Expenses:Restaurant” legs into two two postings: “Expenses:Restaurant x 83%” and “Expenses:Tips x 17%”.

Vacation Cap Date

  • Make an plugin that computes the precise date at which my vacation will cap (240 VACHR) base on an account.

Budget

Auto-Remove, Auto-Pad

  • Add a auto-remove-unused part of the auto_accounts plugin, that automatically removes Open directives for unused accounts. This is useful for demos and such.
  • Write a plugin that automatically inserts a padding directive for accounts with no open directive and with a balance check.

Strict Signs Checker

  • Write a plugin that enables a check that all postings’ amounts are of the correctly allowed sign, e.g. Expenses should almost always be a positive amount, Income a negative one, Assets can be both, also Liabilities. If an amount is posted in the contra direction, this should trigger a warning, unless the transaction is flag with a particular character, or some special tag is present.

FBAR

  • Automatically compute the maximum account values of foreign accounts for the FBAR filing.

After-Tax Balance Sheet

  • Ha… I think you just gave me a fun idea! I’ll write a plugin in Beancount that automatically adds a “future tax expense” entry to offset pre-tax money for the balance sheet, e.g. if I have a 401k account with a value of say 100,000 USD in it, it would automatically insert an entry at the latest day like this:

    2014-07-03 F “Taxes to be paid on distributions.” Expenses:Taxes:Federal 27000 USD Expenses:Taxes:StateNY 8000 USD Liabilities:FutureTaxesOnDistirbutiosn -35000 USD

    This would make the balance sheet reflect only post-tax money, and thus be more meaningful. If I want to see post-tax money, I’ll just enable the plugin from a command-line option. I’d have to find some generic way to identify which accounts are pre-tax somehow.

Payees as Subaccounts

  • Create a plugin that will define subaccounts for payees within accounts and modify all the transactions accordingly. This would be a great way to kick the tires on this idea without affecting the rest of the system.

    Expenses:Electricity:ConEdison Expenses:Phone:TMobile Expenses:Groceries:WholeFoodsMarket Expenses:Groceries:UnionMarket

  • Should we define some notion of the default level for aggregation, per account? For example, in Expenses:Electricity:ConEdison, the default level of aggregation should be Expenses:Electricity. If we define that, using subaccounts should not bother us much.

Dashboard

Add the following to the portfolio dashboard:

  • PnL since yesterday, one week ago, two weeks ago, one month ago, three months ago
  • Current portfolio breakdowns
  • Cash report
  • A listing of short-term lots vs. long-term lots
  • Schedule of lots to become long-term in the near future
  • Returns (computed correctly, over many periods)

From email to fxt:

I want to build an investment dashboard, that would contain:

  • List of holdings, with various rollups (see the different aggregations of holdings reports)
  • Rollups of holdings against various types (e.g., Stocks vs. Bonds)
  • P/L since the morning or for the last day, over the last week, last two weeks, last month, last quarter, last year.
  • Report of uninvested cash and the detail of where it is
  • A listing of short-term vs. long-term lots, and a schedule of which lots are going to switch from short-term to long-term in the near future (to avoid selecting those for sale)
  • Returns, as computed by my prototype of our ideas during the bicycle trip
  • Automatically refresh current prices if run intra-day

This script would run every hour on a crontab and generate static HTML files that I could access from my phone to make investment decisions and monitor gains/losses during the day. I’m certain you would appreciate having such a thing too. I want to integrate the code I already have out of beancount/experiments and start moving all this stuff to the beancount.dashboard.* and add unit tests and make it work on the tutorial file. This should make it easy for others to use.

Tools

Emacs Support

  • Idea: Implement another command like C-c x but that prints out all the linked transactions. Like context, print out balances from before & after, but also print out the combined changes to all the accounts in the linked transactions.
  • Idea: Implement movement commands that move the cursor to the previous/next linked transaction.
  • Set the comment-syntax; currently it thinks it’s ‘# ’

    Note: This is now present

  • In the new mode, we need to recreate a function that will mark a posting as valid (replace ‘!’ by ‘*’).

Reports

Warnings

  • You should have some way to highlight accounts with either failing checks in them, or ‘!’ on their postings or transactions in the balance sheet and/or trial balance.
  • Perhaps we want to produce a report of all transactions with a highlight on them.

Balance Sheet

  • (web) We really need to reorder the accounts in a way that is more sensible… it’s annoying to see the accounts I care about at the top of the page. Cash, Points, AU, should be at the bottom… I wonder if there’s a nice heuristic. Last updated date? I think that would be good enough.
  • We need to figure out how to order the accounts on the balsheet; I want the most relevant near the top. Sorting accounts: compute a score made up of
    • nb. txns from the last 3 months
    • nb. checks from the last 3 months (weighted more heavily)
    • line-no of Open directive in the file.
    • last updated date.

Capital Statement

  • Implement the Capital Statement report

Cash Flow Statement

Statement of Retained Earnings

  • This is possible; search online for examples, makes sense that we should have one, it’s really, really simple to do.

Account Linkage Report

  • Generate a Graphviz link of all the interaccount transactions that are larger than a certain amount.

    Generate a graph for the main kinds of account interchanges, by looking at the most significant transactions between the accounts. For example, ignore transactions which are too small in absolute value, or whose total is too small a portion of the total.

    Fun little project: Create a graphviz output from a Ledger, where transactions above a certain amount would generate a link between accounts. Note: the threshold could be either for single transactions, or for aggregate amounts (absolute value).

HTML Rendering

  • Rendering: When you collapse a parent account, its aggregate amount should render, and disappear when not collapsed.
  • Numbers should align to the right.
  • USD and CAD should be aggregated in their own columns for balance sheet and income statements. These should be specified from the command-line.
  • All entries should have collapsing a-la-JavaScript, along with collapse/reveal all buttons. All JS.
  • If the software is finally fast enough in Go, render RESTful on the fly for any date:
    • REST: balsheet/20121231
    • REST: income/20121231/20131231

    This way, you could have any year on the same run. No need to restart, even have a menu with all the years, and perhaps even some of the latest months.

  • It would be really nice to render the line numbers to the source in the HTML
  • (Performance) Implement buffered output for faster response using a separate thread and an iterator that yields from app.write when the data buffer is large enough.
  • Postings that have a “!” flag should have at least their background red.
  • You should more explicitly state the beginning and ending period on each statement pages (it is super important information). Just below the title.

Excel Output

  • Find good ways to transfer data to an Excel spreadsheet. A link to download a file should be supported.

Credits and Debits Rendering

  • Color the background of numbers with an inverted sign (e.g. payments in a liability account) differently! There should be modes to rendering balance sheets and income statements with inverted amounts, and it should all be done client-side. When amounts are rendered as credits/debits, color their background distinctly, so that it’s obvious what kind of sign convention is in use.

Links to Source

  • The new format code should keep and optionally render the source file/line of any transaction, and allow clicking to get to the source line in the rendering.
  • Maybe there should be a script that can take a report specification and output a list of emacs-compatible links to the entries, interspersed with the text format rendering! You could go “next-error” to go through the entries in time order, emacs taking you there one-by-one.

Multi-Period Reports

  • One kind of report that would be GREAT is a single grid with all income accounts on the left with year by year on the horizontal. An overview of all the years. Same with month-by-month report.

CSV Reports / Text Reports

  • Using an intermediate data structure, produce text and csv / xls reports, downloadable from the web front-end, or even generatable directly. All of this reporting infrastructure should be reusable, ideally.
    • A text rendering of the balance sheet / income statement would be very useful for collaboration/communication with others. Add a link to download a text version of any report. This would be made easy if we only have a few distinct types of reports.

Plots / Time-Series

  • Create a command to extract time series for any account, as a csv file. You could then easily use this for plotting!
  • Generate graphs of account amounts over time
  • Include average amounts, average delta amount

List of Positions

  • Given a list of entries, you should be able to extract a list of positions at any point in time. Provide this as a simple function that can just be reused.
  • The list of positions should provide a way to check the purchase price of each position.
  • Positions should attempt to fetch current values using this: http://www.google.com/ig/api?stock=RGAGX

Maximum Values Report

  • You should report a trial-balance -like listing of the minimum and maximum values of all the accounts.

Event Reports

  • We should be able to count the days of each event type.

Distribution of Expenses and Income

  • Add a pie chart to visualize the constitution of the Income Statement for Expenses and Income.

Summary Reports

  • To create custom views, for example, weekly summaries, you could convert the ledger into another ledger, where entries would have been replaced by summary entries instead, and all the other functionalities would still work.

Financial Ratio Analysis

Budgeting / Goals

  • We could easily add features for budgeting, e.g. somehow set goals and then report on the difference between actual and the goal, and project in the future according to rate, e.g.:

    ;; Check that the total for this position between 2013-06-01 and 2013-12-31 < 800 USD 2013-12-31 goal Expenses:US:Restaurant 2013-06-01 < 800 USD

    ;; Check that the balance of this account on 2013-12-31 is >= 1000 USD 2013-12-31 goal Assets:Savings >= 1000 USD

Trades

  • You should be able to report on all booked trades during a period, especially with the new booking algorithm, this will be useful. Create a new report type for this.

Web Interface

Programmable View

  • GREAT IDEA! Have a web form that you can input a view filtering expression, e.g. year:2014 component:Microsoft to have that year’s transactions made with this component. Encode the results in a unique string that you can decode and create a corresponding view of the subset selected by the expression. You can then view any of the reports for that subset! This means we can then get rid of many of the root page’s links automatically, yet still provide all the opportunities… this is the way to go, and would best mirror the command-line capabilities.

Error reporting

  • We really need to list all the ‘!’ entries somewhere; they should be annoying.
  • In the balance sheet or trial balance, mark accounts that have errors in red, or add a little red start next to them.
  • Implement basic error reporting page from the list of errors.

Debits and Credits

  • The new balance sheets should be able to invert the numbers (and then they should get rendered differently). Basically, every number shown should be either in signed or cr/dr format. We should be able to switch between the two at render time. This should work across all number-rendering routines everywhere–do this centrally.
  • In the balance sheet and income statement, we need to render the amounts inverted (and in a slightly different style).

Links

  • Serve links on: /link/LINK, this needs to be implemented; render a nice “link” href on the description somehow, use a fancy unicode char (no graphics).
  • (web) Render links to the right of descriptions, and the link href link should actually render a page of the related linked entries.

Single-View Server

  • Idea: for condo & baking files into a zip file: allow serving only one ledger realization.
    • One option is to use the same base/root straing as for the web URL:

      http://localhost:8080/byyear/2013/…

      serve_one_ledger(getledger(‘byyear/2013’), port=8080) –realization=’byyear/2013’

    This would serve only that realization, and not others. This way I could bake only this one in a zip file. This would be useful.

Code Org

  • (web) Move table rendering functions into their own files, smaller files.

Aesthetics

  • In the entries table HTML, highlight the relevant posting leg somehow, maybe use a ‘>>’ marker, or make it bold. Something. (Bold is too much, use >>.)
  • Render “as of YYYY-MM-DD” under the title for Balance Sheet, and “from YYYY-MM-DD to YYYY-MM-DD” under the title for Income Statement
  • Answer to favicon.ico request.
  • Add an option to render the entries table upwards, not just downwards.
  • Use that beautiful new font (Roboto) from Tactile in the new rendering. Totally worth it. Use the nice Lucida-like font for numbers, like in TurboTax.

JavaScript / Client-Side Interaction

  • Render balance sheet/ income statement cells with two numbers for parent nodes, so that when you collapse a node, all the amounts of its children sum up automatically and display in its cell. You should have a consistent report regardless of whether nodes are collapsed or not. This will require some JavaScript effort.
  • Implemented a JavaScript cursor in JS. J, K up down. SPC = toggle.
  • In Journal view, pressing ‘C’ should toggle displaying the checks on and off.

Trial Balance

  • We should have a nicer way to tell what accounts need to be updated. Highlight them red if they haven’t been updated in more a month (configurable). Put the last updated date in the balance sheet or perhaps the trial balance page. Should be easy; we don’t need a dedicated page for this.
  • Do we need a dedicated page for listing all documents? This page could include documents without a date, could be rendered as a tree-table, with the list of each document in the corresponding account. Maybe that’s overkill. DK.
  • Shove more information in the Trial Balance page, info about errors, documents, etc.

Multi-Year

  • A multi-year report is a global report.

Source

  • The source page should take a special ‘?line=ddd’ parameter that will scroll the page to the transaction at that line.

Conversions

  • Render the Conversions amount at the bottom of the Conversions page…

Bake & Scrape

  • Make the web scraper run in multiple threads… it’s quite a bit too slow as it is. I’m sure we can make it scrape in parallel using multiprocessing and a work queue (this should be a fun little project and would make baking to an archive a lot faster in many cases).

Import

GnuCash

  • Write a converter of GnuCash XML files into Beancount.
  • Contact xentac@ for an example GnuCash input file with 2-3 years of data. Willing to share (see email).

Export

HTML Export as File

  • Test “bean-bake” with the v2, it doesn’t appear to work.

XML

  • Output to a structured XML format, some people are finding that useful to build other visualizations. In order to test this completely, do a round-trip test. The code should live in beancount.parser, parallel to the existing code there.

Ledger

  • Export the compatible subset to Ledger format, so you can compare the reports. This should be done from a tool called “bean-convert”.

Visualizations

TreeMaps

Portfolio tracking softwares

  • You should be able to export to input files or APIs for websites that track portfolios for you, such as Google Finance and Yahoo and others. Use the list of holdings as input. This should perhaps just be another report name.

Documentation

Challenges

  • Document those below which I’m already able to do, and those which require new features to be able to be done, move them into a separate appendix, with explanations on how to do it.

Cash vs. Accrual Accounting

Of course a real accountant would just do this: (accrual based accounting)

2014-05-19 * “Booking tithe” Expenses:Tithe 300 USD Liabilities:Tithe -300 USD

2014-05-20 * “Paying tithe” Liabilities:Tithe 300 USD Assets:Checking -300 USD

But this records the expense on a different day than when you actually paid it. That would be a problem if, for example, you live in the US and wanted to claim a tax deduction for the tithe, in which case you must claim the deduction for the year the tithe was actually paid (cash based accounting).

This is indeed the right solution to this! Accumulate a liability as you go, and resolve it with real transactions later on.

This case keeps coming back again and again, of wanting to do accrual accounting but wanting to do cash declarations. I think we need to have a long and separate discussion about cash vs accrual accounting and for sure we can come up with a creative solution that solves this problem.

Can I generate a nice year-on-year summary of income and expenses?

  • Including RSP contribs, like my bu spreadsheet that I crafted manually? Can I do that? That would be awesome!

Maximum Balance

  • Can I compute the maximum value of each account at the end of every year (for foreign assets decl.) This would be useful for FBAR / FATCA declarations.

Complete Return (IRR) on Condo

  • Challenge: Can I compute IRR return on my condo accurately? TODO: Add benefits received as an Income, as transactions. You should be able to compute the IRR of any Ledger!

Taxation Rate

  • Challenge: Can I automatically compute my taxation rate for every year?

List of Assets

  • Challenge: Can I obtain a list of my assets at any time?

Make a report of currency exposure

  • For a particular balance sheet, report the total currency exposure of the ledger. This should be a very simple report, probably in the form of a pie chart. Maybe this pie chart should be located in the capital report (possibly makes sense).

Capital Gains

  • Capital gains should not count commissions nor on the buy nor on the sell side. How do we book them like this? Can we count this somehow automatically? Misc accounts? Not sure.

Inflation Adjusted Balance Sheets and Charts

  • It would be AWESOME to look at a balance sheets from the past but inflation-adjusted for any date… Answer this question easily:

    “What was I making in 2010 in today’s dollar terms?”

  • How would I produce an inflation adjusted version of some charts. Maybe all charts should have that option?

Statement of Assets (for Will)

  • In order to have someone else be able to take care of your business, you should be able to produce a list of the accounts open at the end of the period, with the account ids and balances. This should be printable and storable, for someone else to take care of your things in case you die.

Compare common costs using constant TMV

  • Look at average meal 10 years ago, average electricity, etc. things that should be equal, and correct for the time-value-of-money, compare prices today with prices then. Maybe come up with some kind of constant unit that I can convert everything to.

GIFI Reporting

  • You could write a script to automatically fill this form: http://www.cra-arc.gc.ca/E/pub/tg/rc4088/rc4088-12e.pdf

    “With Beancount, one thing that would be doable outside of Beancount, as a separate script, is to associate a set of accounts to these GIFI codes and automatically generate the forms.”

Change List

  • Implemented in Python 3, from scratch.
  • Internal data structures are more functional, immutable, allowing you to more easily create scripts that use the in-memory data. Overall, the new code is way simpler and much easier to understand because of this. It’s actually become dead simple.
  • New, simplified, and more consistent (and rigid) syntax will make it possible to add more features in the future, and to have parsers in other languages too (e.g. Go).
  • Booking trades with capital gain tracking should now work.
  • The new parser is written in C, so it is much much faster, and future changes will be easier
  • The new web server fixes annoying rendering issues.
    • Balance sheet amounts can now reported in terms of book values.
    • Debit accounts can now be rendered with positive numbers (color-coded).
    • The internal data structure changes are much more general, and allow, for instance, creating a balance sheet at any point in time. In particular, you can have a balance sheet at the beginning and end of an exercise.
  • Some internal design flaws were fixed, like checks on filtered ledgers showing up from incorrect periods.
  • Various outputs to text, csv, and xls are now supported for easier sharing.
  • The input file is monitored by the server, and can be automatically reloaded. This makes it easier to just start the web server, then edit the file to update what you need.
  • There is no need to specify a filter period anymore; the interface is able to realize any required periods, and the GUI provides access to most common cross-sections (all, by year, by tag, by payee, transactions with bookings, etc.). You should be able to just specify the GUI.
  • Client-side javascript has been added for a neater, more compact rendering of journals.
  • New scripts to extract a list of current positions at any time, and global summaries over many years or months.

Presentation Material

  • Use impress.js to built a visualization of the DE method
  • Record a video, that’s an easy way to explain how this works.
  • IDEA!!! Use drawings a-la-ThinkBig or whatever it is. This will be the perfect medium for this. Mix it with video. Start writing a detailed script.
  • Begin with a USB key in hand. “On this 8 GB USB key, I have all of 8 years history of financial transactions in my life. Every single price paid that went recorded into an account it these.

Padding documentation from email

  • Put this in the docs to explain “pad”

    > > Ok, restarted example, let’s say you begin > > accounting in dec 2013, you’ll have this: > > > > 2010-01-01 open > > 2010-01-01 pad > > 2013-12-04 balance > > 2013-12-08 * … > > 2013-12-11 * … > > 2013-12-17 * … > > > > eventually, moving forward, you’ll get to 2014: > > > > 2010-01-01 open > > 2010-01-01 pad > > 2013-12-04 balance > > 2013-12-08 * … > > 2013-12-11 * … > > 2013-12-17 * … > > 2013-12-22 * … > > 2013-12-29 * … > > 2014-01-02 * … > > 2014-12-04 balance > > 2014-12-06 * … > > > > Allright, now you decide you like this, and you > > want to enter statements before you started. > > You find your paper statement for november, and > > fill in: > > > > 2010-01-01 open > > 2010-01-01 pad > > ; here you insert > > 2013-11-04 balance > > 2013-11-08 * … > > 2013-11-18 * … > > … > > ; this is what was there previously > > 2013-12-04 balance > > 2013-12-08 * … > > 2013-12-11 * … > > 2013-12-17 * … > > 2013-12-22 * … > > 2013-12-29 * … > > 2014-01-02 * … > > 2014-12-04 balance > > 2014-12-06 * … > > > > Great. Now, notice how the balance for > > 2013-11-04 is probably different than that of > > 2013-12-04. If instead of a pad directive you > > had added a manual adjustment, you’d have to > > change it here. This is the beauty of the pad > > directive: it automatically does it for you. > > > > Now, let’s keep going backward in time. You dig > > around your records, you find September’s > > statement, but you cannot find the statement > > for October, maybe it’s lost, or somewhere > > else. Fine! You insert a pad directive to > > account for those missing transactions: > > > > 2010-01-01 open > > 2010-01-01 pad > > > > 2013-09-04 balance > > 2013-09-05 * … > > … september transactions > > 2013-09-30 * … > > 2013-10-04 balance > > > > ; padding for missing October statement, > > where is my statement? > > 2013-10-04 pad > > 2013-11-04 balance > > > > … november transactions > > 2013-11-08 * … > > 2013-11-18 * … > > … > > 2013-12-04 balance > > > > 2013-12-08 * … > > 2013-12-11 * … > > 2013-12-17 * … > > 2013-12-22 * … > > 2013-12-29 * … > > 2014-01-02 * … > > 2014-12-04 balance > > > > 2014-12-06 * … > > > > This is the full example.

Improve this bit:

> But the detailed explanation cannot be found. There’s only one phrase: „Think > of the Equity account as something from the past that you had to give up in > order to obtain the beginning snapshot of the Assets + Liabilities balance.“ > > Great comment. I’ll improve this.

More user comments:

> After doing my research, I found about debits and credits, which in Beancount > you represent with positive numbers and negative numbers respectively. I > found that having a name for each group of accounts helps me to think of them > at the same time, e.g. Liabilities+Equity+Income as part of a common thing, > instead of having to research each of it independently. > In the documentation you start speaking about numbers, then about signs, then > about grouping the accounts. Maybe it’s better to go top-down and start > saying that there are two types of account (usually +, usually -) and then > divide each group further. > > I will change that, thanks for the comment.

Example

(documentation)

  • Write a worked and detailed example of generating automated transactions in the Plugins document.

Contributor agreement

  • See note at the bottom of: https://github.com/fourier/ztree

    Since ztree is a part of GNU ELPA, it is copyrighted by the Free Software Foundation, Inc.. Therefore in order to submit nontrivial changes (with total amount of lines > 15), one needs to to grant the right to include your works in GNU Emacs to the FSF.

    For this you need to complete this form, and send it to assign@gnu.org. The FSF will send you the assignment contract that both you and the FSF will sign.

    For more information one can read here to understand why it is needed.

    As soon as the paperwork is done one can contribute to ztree with bigger pull requests. Note what pull requests without paperwork done will not be accepted, so please notify the maintainer if everything is in place.

Name ideas

  • beangrind (new import system)
  • beanroast (new import)a
  • beangreen
  • beanfilter
  • beancocoa
  • beantamp