New Fava extension: Tax loss harvester

139 views
Skip to first unread message

Red S

unread,
Mar 9, 2020, 11:32:32 PM3/9/20
to Beancount
I recently shared a beancount tool for identifying tax loss harvesting opportunities. This is the fava plugin version. Starting a new thread for this because these these are different code bases, and I intend primarily to develop this one (the fava plugin) unless there is a lot of interest in the other as well.


README.md with screenshot:

fava_tax_loss_harvester

Tax loss harvester plugin for Fava (Beancount personal finance software).

Reports the set of lots that can be tax loss harvested from your beancount input file. Includes a comprehensive wash sale report. Example:

TLH screenshot

The example above shows that 350,100 USD of losses can be harvested by selling the rows listed. However, 1 BNCT of that would be considered a wash sale and will not be allowable. It also shows the account and quantities of each commodity to sell total sale proceeds (1,051,900 USD) if all the recommended lots were sold.

Installation

Clone the source to a directory (eg: plugins/fava/tlh relative to your beancount source).

Include this in your beancount source:

2010-01-01 custom "fava-extension" "plugins.fava.tlh" ""

Configuration

Configure TLH through your beancount sources. Example:

2010-01-01 custom "fava-extension" "plugins.fava.tlh" "{
  'account_field': 'account',
  'accounts_pattern': 'Assets:Investments:Taxable',
  'loss_threshold': 50,
  'wash_pattern': 'Assets:Investments',
}"

account_field

Default: LEAF(account)

This string is a part of the beancount query. If you want to see the entire account name, set this to 'account'.


accounts_pattern

Default: ''

Regex of the set of accounts to search over for tax loss harvesting opportunities. This allows you to exclude your tax advantaged and other non-investment accounts.


loss_threshold

Default: 1

Losses below this threshold will be ignored. Useful to filter out minor TLH opportunities.


wash_pattern

Default: ''

Regex of the set of accounts to search over for possible wash sales. This allows you to include your tax advantaged and all investment accounts.


TODO:

  • show if a loss generated would be long term or short term

Justus Pendleton

unread,
Mar 11, 2020, 5:43:55 AM3/11/20
to Beancount
On Tuesday, March 10, 2020 at 10:32:32 AM UTC+7, Red S wrote:
I recently shared a beancount tool for identifying tax loss harvesting opportunities. This is the fava plugin version. Starting a new thread for this because these these are different code bases, and I intend primarily to develop this one (the fava plugin) unless there is a lot of interest in the other as well.

It looks pretty good. Here are a few things I noticed while trying it out:

It looks like if account_field is set to LEAF(account) then the URLs for the accounts are broken -- they take you to my-personal-ledger/account/LEAF instead of my-personal-ledger/account/Assets:Tree:Leaf

There's something wrong in how it collects the holdings. The command line version generates the correct set of holdings but the fava version also includes some lots that I sold last week. I haven't looked yet to figure out why they are being included.

The "purchases within the past 30 days" doesn't include purchases I made, it only includes sales I made. I think it is supposed to be the other way around?

Red S

unread,
Mar 11, 2020, 6:35:46 AM3/11/20
to Beancount


On Wednesday, March 11, 2020 at 2:43:55 AM UTC-7, Justus Pendleton wrote:
It looks like if account_field is set to LEAF(account) then the URLs for the accounts are broken -- they take you to my-personal-ledger/account/LEAF instead of my-personal-ledger/account/Assets:Tree:Leaf

I noticed this as well. I assume fava is adding this link if the column is named 'account'. I'll figure out a fix later.
 
There's something wrong in how it collects the holdings. The command line version generates the correct set of holdings but the fava version also includes some lots that I sold last week. I haven't looked yet to figure out why they are being included.

Ah, I included 'date <= DATE_ADD(TODAY(), -30)' in the fava version, to filter out purchases within the past 30 days since they cause washes. I realize now that is incorrect, since that (incorrectly) filters out sales during the last 30 days as well. I should include them in both the holdings and in the wash sales. Fix committed. Thanks for spotting this!
 
The "purchases within the past 30 days" doesn't include purchases I made, it only includes sales I made. I think it is supposed to be the other way around?

This needed a fix as well. Not sure why it doesn't include the purchases, but I added 'number>0' in the query to filter out sales. Would you mind trying again?

Lesson: the queries pack a lot of assumptions into a dense SQL-like statement, and I'd not be surprised if there're a few more cases hiding. I'll soon commit a unit test to make this easier.

Thank you very much for test driving this and the helpful feedback!

Red S

unread,
Mar 13, 2020, 4:16:46 AM3/13/20
to Beancount
Summary on top grouped by commodity (thanks Justus Pendleton for the idea).

Also, washes have been merged into a single table.

Red S

unread,
Mar 17, 2020, 2:58:59 AM3/17/20
to Beancount
Updates to the TLH extension in these interesting times we live in:

- the command line client has now been folded in to the fava client and uses the same code (refactored out to support both fava and bean-query)
- a --brief option to the command line client displays the summary only
- unit tests now included

Red S

unread,
May 11, 2022, 5:42:26 PM5/11/22
to Beancount
This is a good week (at least for US index investors) to consider whether tax-loss harvesting might benefit you. To help with that, here is an article I wrote on it:

Includes requirements, wash sale subtleties and safe to sell/buy dates, and comparisons to robo-advisors.

And here is the fava_investor TLH module. It's not just for fava: a plain-beancount command line version is also included.

Reply all
Reply to author
Forward
0 new messages