eprbell / rp2

Privacy-focused, free, open-source cryptocurrency tax calculator for multiple countries: it handles multiple coins/exchanges and computes long/short-term capital gains, cost bases, in/out lot relationships/fractioning, and account balances. It supports FIFO, LIFO, HIFO and it outputs in form 8949 format. It has a programmable plugin architecture
https://pypi.org/project/rp2/
Apache License 2.0
264 stars 42 forks source link

Adding HIFO #11

Closed YagiOoda closed 2 years ago

YagiOoda commented 2 years ago

I was wondering the possibility of adding HIFO to the existing FIFO and LIFO cost basis structures (https://www.investopedia.com/terms/h/hifo.asp). It is available to use in the USA and would potentially help save a lot on taxes such that you're always selling the highest priced lot.

Unfortunately, my knowledge of python is more in the scripting/engineering realm, so I'm not sure how much help I would be on the coding aspect...

Thanks!

eprbell commented 2 years ago

I agree, HIFO would be good to have (and also more accounting methods in general). I don't have cycles right now to implement new accounting methods, but I'll happily review PRs. I'm labeling this issue "Help Wanted" to increase its visibility.

RP2 has a robust plugin architecture that is designed for extending its functionality. Accounting methods are plugins: as such they are encapsulated and must implement a minimal, well-defined API.

Here are a few pointers for anybody who would like to start working on this:

tonykau1 commented 2 years ago

Agreed, this would be valuable. A few more considerations on the topic for whoever build on this:

To further minimize the tax, a combination of FIFO and HIFO may be necessary, accounting for long term cap gains rate vs short term (and short term would need to be an input of the user's expected incremental rate/bracket).

LIFO may also be most efficient if all lots are short term and you want to let your oldest lost mature to LTCG as soon as possible.

eprbell commented 2 years ago

RP2's programmable plugin architecture makes all sorts of accounting methods possible: each one of them has to be implemented as a new plugin. It would be great to have many accounting method plugins, so that users can experiment and find what works best for their specific situation.

ninideol commented 2 years ago

Hello, I'm new to open source and I would like to try to add HIFO if it's still available

eprbell commented 2 years ago

That's great! I'll assign this to you. Let me know if you have any questions or comments.

ninideol commented 2 years ago

Thanks! It said in the contributing guidelines : "one feature per commit". Do I have to push only one commit on my pull request ?

eprbell commented 2 years ago

No: it just means to avoid more than one feature in one commit, but one feature (in this case the HIFO plugin) can be spread over multiple commits, if desired.

ninideol commented 2 years ago

Hi, to test the code, can i write a test file only for hifo method ? And how can i use hifo as accounting method in a terminal ? (it asks me to use choose only from fifo or lifo and i don't find where i can change it ?

eprbell commented 2 years ago

Hi, to test the code, can i write a test file only for hifo method ? And how can i use hifo as accounting method in a terminal ? (it asks me to use choose only from fifo or lifo and i don't find where i can change it ?

Yes, absolutely: write an ODS file to test hifo-only.

As for the question on hifo not being listed by RP2 among the possible choices, here are a few hints:

You probably already did this, but just in case: be sure to read the links indicated in my comment above and use lifo.py as boilerplate, since hifo is going to be relatively similar to it. If you show me the code I can give you more precise feedback.

Hope this helps!

ninideol commented 2 years ago

Thank you for your response and your time ! I think i did all three hints it keeps ask me for lifo or fifo. I'm looking for what I missed. And I'm struggling a bit on the get_acquired_lot_for_taxable_event method, in lifo it iterates by year but it can't be like that with price and it seems too much to find the highest one every time. Do have I to sort data so I can find highest easily ?

eprbell commented 2 years ago

To understand why it's happening, you can instrument the code in the following places:

A few prints there can probably shed some light.

Regarding your question on get_acquired_lot_for_taxable_event(), accounting_method plugins receive iterators to the acquired_lots and to the taxable_events in the initialize() method. This method can iterate over the lots and organize them in custom data structures that will allow the other methods easy access to the lots. The nature of these custom data structures depends on the semantics of the accounting methods. For LIFO I organized acquired lots in a list and an AVL tree per year. HIFO would be somewhat similar to LIFO but the sorting would be different for sure: in LIFO the AVL tree is sorted by timestamp, whereas in HIFO (if you use AVL trees) it would be sorted by amount (e.g. reimplement the _get_avl_node_key() method). I'm sure there are some other semantic differences between the two plugins, but I hope this gives you a few pointers.

ninideol commented 2 years ago

Thank you for the tips, I finally succeed to launch rp2 with hifo.

ninideol commented 2 years ago

Hi, sorry for the delay. I may have an implementation for HIFO accounting method, here it is : https://github.com/ninideol/rp2/tree/develop . Do you prefer a draft pull request maybe ?

eprbell commented 2 years ago

That's great! Thanks for working on this. Yeah, a PR would be best.

ninideol commented 2 years ago

Thanks ! I opened a PR

eprbell commented 2 years ago

Thanks, will review in the next few days.

eprbell commented 2 years ago

HIFO has been added in the latest version of RP2 (see #41).