New tool: Tax loss harvester for beancount

114 views
Skip to first unread message

Red S

unread,
Mar 7, 2020, 7:54:03 PM3/7/20
to Beancount
I cleaned up a tool I've been using to find opportunities to do tax loss harvesting from my beancount file, and am sharing it here. A well crafted query may get you a rough list, but I find a few bells and whistles to be far more useful, and hence use this harvester tool. For example, this finds possible wash sales and reports on the details.


Tax loss harvester for Beancount personal finance software

Reports the set of lots that can be tax loss harvested from your beancount input file. Example:

$ ./tlh.py ~/accounts/accounts.beancount -a "Assets:MyInvestments"

Account              Qty  Ticker       Market  Purchased    W      Loss
---------------  -------  --------  ---------  -----------  ---  ------
HTrade-Main        32.22   YYY        1982.123  2019-11-22           41
HTrade-Main         1.313  YYY         893.23   2019-11-23         1142
HTrade-Main        40.4    APPLE       704.344  2019-11-20           83
HTrade-Main       159.504  BETAX      7615.4    2019-07-10   *      384
HTrade-Second      68.695  APPLE       526.55   2019-05-10           19
HTrade-Second      77.786  BETAX      4437.66   2019-08-15   *       28
6 (5 sets)         0                20596.97                       1697

Wash sales: recent purchase (within 30 days):
----------  ------------ ------- -------  -----
2020-01-25  HTrade-Third   75.39  100.00  BETAX
----------  -----------  ------- -------  -----

The example above shows that 1697 USD of losses can be harvested by selling the rows listed. However, 100 USD 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 (20596.97 USD) if all the recommended lots were sold.

Features

  • reports on possible wash sales (US) in the second table above
  • optionally set a loss threshold. Useful to filter out minor TLH opportunities
  • reports the total number of sale transactions needed
  • optionally takes:
    • account patterns to search for wash-sale creating purchases
    • account patterns to exclude for wash-sale creating purchases (eg: tax deferred accounts)

TODO:

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

Martin Blais

unread,
Mar 7, 2020, 9:37:13 PM3/7/20
to Beancount
Thank you for sharing RedS! I've added a link to the contributions doc.

--
You received this message because you are subscribed to the Google Groups "Beancount" group.
To unsubscribe from this group and stop receiving emails from it, send an email to beancount+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/beancount/9efb8263-b248-4c77-8096-2538e57677c4%40googlegroups.com.

Justus Pendleton

unread,
Mar 9, 2020, 8:54:55 PM3/9/20
to Beancount
On Sunday, March 8, 2020 at 7:54:03 AM UTC+7, Red S wrote:
I cleaned up a tool I've been using to find opportunities to do tax loss harvesting from my beancount file, and am sharing it here.

Nice work! I have a similar script I've been using. Some notes based on trying yours:

* Showing wash sales is a nice touch!
* It requires argcomplete & tabulate; you might want to mention that in the github README.
* You only show the leaf part of the account name. That's understandable but in my hierarchy I have Assets:Vanguard:Brokerage and Assets:Schwab:Brokerage and Assets:WellsFargo:Brokerage and they all just show up as "Brokerage" :-(. Off the top of my head, I don't have a great solution to this problem. Maybe have a --full-account-names flag?
* My script has a command line arg to group results by security. I have a fair number of lots so when I run yours I get (especially today!) about two pages of results (98 lines). A bit about my workflow. My tlh script gets run daily so I just want a fairly high-level summary at that time. When I actually go to my broker to sell things is when I want the full detailed version of things.
* I don't quite understand what --wash-pattern-exclude is for? Tax deferred accounts can generate wash sales. (They're even worse than normal accounts because if they generate a wash sale, the lowered basis is useless.)
* The market value get printed in scientific notation if it is large. Presumably other values do as well but I don't have $1.58433e+06 in capital losses yet to test out ;)
* Consider adding commas when printing the the Qty, Market, and Loss numbers; it makes it easier for humans to read IMHO.
* The wash sales table formatting looks off to me. There are extra lines of -------. I guess that's a bug or something? Here's what I mean:

Wash sales: recent purchase (within 30 days):
----------  -------------------  ----  ------  ----
2020-03-02  Interactive-Brokers  -500  -12955  REET
----------  -------------------  ----  ------  ----
----------  -------------------  -----  -------  ---
2020-02-28  Interactive-Brokers  -6182  -385117  RZV
----------  -------------------  -----  -------  ---
----------  -------------------  ----  --------  ----
2020-03-02  Interactive-Brokers   500   57921.5  VIOV
2020-02-28  Interactive-Brokers  1000  115940    VIOV
2020-02-28  Interactive-Brokers  1300  150936    VIOV
----------  -------------------  ----  --------  ----
----------  --------  ------  ------  -----
2020-02-28  Rollover  19.539  512.31  VEGBX
----------  --------  ------  ------  -----
----------  ----  ------  ------  -----
2020-02-28  Roth  79.342  465.74  VWEAX
----------  ----  ------  ------  -----

Overall, nice job!

Red S

unread,
Mar 9, 2020, 9:30:06 PM3/9/20
to Beancount
Great feedback, thanks! Fixes for all your points coming very soon.

Meanwhile, I'm working on a fava plugin version. I'm considering continuing further development only on the fava version, given it's additional effort to maintain both. Curious: do you use fava, and would you prefer having this in fava?

Red S

unread,
Mar 9, 2020, 11:42:20 PM3/9/20
to Beancount
I just shared my fava extension that takes care of most of these. Let me know if you use fava. Detail:


> * It requires argcomplete & tabulate; you might want to mention that in the github README.

Will add.


> * You only show the leaf part of the account name. That's understandable but in my hierarchy I have Assets:Vanguard:Brokerage and Assets:Schwab:Brokerage and Assets:WellsFargo:Brokerage and they all just show up as "Brokerage" :-(. Off the top of my head, I don't have a great solution to this problem. Maybe have a --full-account-names flag?

In the fava extension, the 'account_field' config option defaults to 'LEAF(account)' but you can set it to 'account'.


> * My script has a command line arg to group results by security. I have a fair number of lots so when I run yours I get (especially today!) about two pages of results (98 lines). A bit about my workflow. My tlh script gets run daily so I just want a fairly high-level summary at that time. When I actually go to my broker to sell things is when I want the full detailed version of things.

Makes sense. Reporting so it works for everyone is tricky. In this case, allowing custom reporting is also tricky. One idea: split the 'units' column into a number and currency so you can at least sort by currency, which approximates your group-by-security. What do you think? If that helps, feel free to send me a patch, else I'll get to it at some point. Other proposals welcome.


> * I don't quite understand what --wash-pattern-exclude is for? Tax deferred accounts can generate wash sales. (They're even worse than normal accounts because if they generate a wash sale, the lowered basis is useless.)

You're right. Removed.


> * The market value get printed in scientific notation if it is large. Presumably other values do as well but I don't have $1.58433e+06 in capital losses yet to test out ;)

Not a problem in the fava version, since it uses fava/beancount to render.


> * Consider adding commas when printing the the Qty, Market, and Loss numbers; it makes it easier for humans to read IMHO.

Fixed (in fava)


> * The wash sales table formatting looks off to me. There are extra lines of -------. I guess that's a bug or something? Here's what I mean:

N/A for the fava version. But I basically print one table for each security, hence the header/footer.

Thanks a bunch for the feedback!

Justus Pendleton

unread,
Mar 10, 2020, 2:03:59 AM3/10/20
to Beancount
On Tuesday, March 10, 2020 at 8:30:06 AM UTC+7, Red S wrote:
Meanwhile, I'm working on a fava plugin version. I'm considering continuing further development only on the fava version, given it's additional effort to maintain both. Curious: do you use fava, and would you prefer having this in fava?

I don't use fava terribly often. I find personal finance tends to be a write-many, read-rarely kind of workflow and fava (for me, at least) is more about reading. I probably only use it once or twice a month maximum.

That said, I think making it a Fava plugin probably makes sense; a GUI is always going to offer richer possibilities for exploring data. To make it even better you could try to offer a stripped down version that can be run on the commandline that just outputs a simple "hey, there is some TLH, look at fava for more details".

Red S

unread,
Mar 11, 2020, 2:35:44 AM3/11/20
to Beancount
Thanks Martin!

In case you're collecting fava extensions as well, here is the corresponding TLH fava extension: https://github.com/redstreet/fava_tax_loss_harvester
I find the fava extension most useful and plan to maintain it. 'm not yet sure if I'll maintain the command line tool, in addition.
To unsubscribe from this group and stop receiving emails from it, send an email to bean...@googlegroups.com.

Red S

unread,
Mar 17, 2020, 3:06:47 AM3/17/20
to Beancount
Hello Martin,
I've combined both the beancount command line client and fava extension into https://github.com/redstreet/fava_tax_loss_harvester. It'd be great if you could point to that repo in the contributions doc. Thanks!

Martin Blais

unread,
Mar 27, 2020, 1:12:43 AM3/27/20
to Beancount
Done, thx


To unsubscribe from this group and stop receiving emails from it, send an email to beancount+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/beancount/2e041524-e051-4025-93ad-65fba1f0bd9f%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages