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
256 stars 42 forks source link

FIFO and exchange/wallet cost-basis calculation #83

Closed gbtorrance closed 1 year ago

gbtorrance commented 1 year ago

I have some questions about exchanges/wallets. I have read the comments in issue 79 and found the discussion quite helpful, but some questions remain.

I plan to use FIFO for tax year 2022.

My understanding is that RP2 uses "across exchange" (pool) accounting for this, so that whatever is the first/earliest transaction with remaining/unused cost basis will be "sold", regardless of exchange. Is this correct?

My situation is as follows: I used external SaaS software to calculate my tax year 2021 taxes. After calculating what I needed for tax year 2021 filing it also provided me with a list of "end of year positions" indicating asset, crypto amount, and cost basis remaining, but did NOT break this out by exchange/wallet. As such, I currently don't have an easy way to segregate transactions by exchange for input to RP2, so I am just specifying a single exchange called "Unknown" for all transactions, even though the crypto is actually spread over many exchanges and wallets. Is this OK? I assume so (given the understanding above regarding "across exchange" calculations)?

If I decide in future to try and segregate transactions by exchange, I'd like to make sure I properly understand the FIFO cost basis calculation behavior. Assuming it is "across exchange", how exactly does it work? For example, if I bought BTC on both exchange A and exchange B, and I then sell some BTC from exchange B, the balance of BTC on exchange B will obviously go down. But if the first/earliest BTC buy transactions are on exchange A, then doesn't that mean that the remaining cost basis of the transactions on exchange A should be reduced when selling on exchange B? Could this lead to a situation where an exchange has zero BTC remaining, but as non-zero cost basis remaining or, visa versa, an exchange has a non-zero BTC balance, but zero cost basis remaining? I think I'm getting quite muddled here. Can you help me understand where I'm going wrong?

Thanks for all your help!

eprbell commented 1 year ago

I have some questions about exchanges/wallets. I have read the comments in issue 79 and found the discussion quite helpful, but some questions remain.

I plan to use FIFO for tax year 2022.

My understanding is that RP2 uses "across exchange" (pool) accounting for this, so that whatever is the first/earliest transaction with remaining/unused cost basis will be "sold", regardless of exchange. Is this correct?

Yes, correct.

My situation is as follows: I used external SaaS software to calculate my tax year 2021 taxes. After calculating what I needed for tax year 2021 filing it also provided me with a list of "end of year positions" indicating asset, crypto amount, and cost basis remaining, but did NOT break this out by exchange/wallet. As such, I currently don't have an easy way to segregate transactions by exchange for input to RP2, so I am just specifying a single exchange called "Unknown" for all transactions, even though the crypto is actually spread over many exchanges and wallets. Is this OK? I assume so (given the understanding above regarding "across exchange" calculations)?

I'm not sure about what how the IRS would react to transactions with "Unknown" exchange: it may be worth the effort of documenting exchange information. Also consider the technique described in this FAQ on how to switch from another tax software to RP2 (I think it may be relevant to your case): https://github.com/eprbell/rp2/blob/main/docs/user_faq.md#how-to-switch-from-another-tax-software-to-rp2

If I decide in future to try and segregate transactions by exchange, I'd like to make sure I properly understand the FIFO cost basis calculation behavior. Assuming it is "across exchange", how exactly does it work? For example, if I bought BTC on both exchange A and exchange B, and I then sell some BTC from exchange B, the balance of BTC on exchange B will obviously go down. But if the first/earliest BTC buy transactions are on exchange A, then doesn't that mean that the remaining cost basis of the transactions on exchange A should be reduced when selling on exchange B? Could this lead to a situation where an exchange has zero BTC remaining, but as non-zero cost basis remaining or, visa versa, an exchange has a non-zero BTC balance, but zero cost basis remaining? I think I'm getting quite muddled here. Can you help me understand where I'm going wrong?

I recommend you take a look at crypto_example.ods, which covers the case you described. Here's how to run the example: https://github.com/eprbell/rp2/blob/main/README.md#running. After generating files open the crypto_example_fifo_rp2_full_report.ods output file and look at the "BTC Tax" tab and specifically the "Gain / Loss Detail" table: this table contains the precise mapping between in and out lot fractions.

Hope this helps.

gbtorrance commented 1 year ago

Thank you for the reply! I generated the example you suggested, and have been studying the reports. I hate to be a nuisance, but I'm still struggling to make sense of it.

Is it correct to say that a "lot" essentially represents one of the IN lines? And a "fraction" represents part of a "lot"?

What I'm struggling to grasp is how RP2 tracks the balance on a particular asset on an exchange as well as the cost basis for assets. It seems to me that these need to be tracked independently, because when an asset is sold from an exchange, the cost basis associated with that sale may be associated with crypto from another exchange (since the crypto from the other exchange may be "first" according to FIFO). Right? I'm not clear how this is tracked by RP2, and how I can manually follow along in the "full report" (if this is, indeed, possible).

Also, looking at the "BTC In-Out" tab of the full report I see this:

image

The "Send/Sold" column, according to the Legend, represents "Lots that have been sent or sold, according to the order defined by the Accounting Method (see General section)". So does this mean that this number represents the amount of the crypto in "Crypto In" that has been used/allocated so far in cost basis calculations for gain/loss transactions? So, if we look at line 4 in "In-Flow Detail", does that mean that 1 BTC of 4 BTC has been used , and 3 BTC (from that "lot") remains associated with the BTC cost basis? Or is this, rather than being about cost basis, about the amount of the lot that has been removed from the particular exchange via a corresponding OUT transaction associated with the same exchange?

I realize the above probably doesn't make a lot of sense. I'm really trying to "get it", but I'm struggling. Any pointers you can provide would be helpful.

Thanks!

eprbell commented 1 year ago

Thank you for the reply! I generated the example you suggested, and have been studying the reports. I hate to be a nuisance, but I'm still struggling to make sense of it.

No problem, happy to help clarify any doubts.

Is it correct to say that a "lot" essentially represents one of the IN lines? And a "fraction" represents part of a "lot"?

An acquired lot is one of the IN lines, a taxable event is one of the OUT lines. These lots are fractioned and matched to one another according to the accounting method (FIFO). The result of the matching is shown in the "Gain / Loss" table: each line here shows precisely how one taxable event fraction is matched to one acquired lot fraction. The left half of the table (in blue) shows taxable event fractions, the right half (in purple) shows acquired lot fractions.

What I'm struggling to grasp is how RP2 tracks the balance on a particular asset on an exchange as well as the cost basis for assets.

In FIFO the IRS allows "universal pooling of assets" (see https://www.coindesk.com/layer2/2022/02/23/fifo-vs-specific-identification-how-do-you-choose/), which is what RP2 does.

It seems to me that these need to be tracked independently, because when an asset is sold from an exchange, the cost basis associated with that sale may be associated with crypto from another exchange (since the crypto from the other exchange may be "first" according to FIFO). Right?

Not sure I understand the question fully: universal pooling means that the acquired lots are treated as if they were coming from one single pool. Computing balances is a completely different calculation, which is done per-exchange and keeps track of non taxable transactions (like INTRA ones).

I'm not clear how this is tracked by RP2, and how I can manually follow along in the "full report" (if this is, indeed, possible).

You can read the "Gain / Loss" table line by line (be sure to scroll to the right to see acquired lots because it's a large table): look at which taxable event fraction is associated with which acquired lot fraction and you'll be able to understand how RP2 does the matching.

Also, looking at the "BTC In-Out" tab of the full report I see this:

image

The "Send/Sold" column, according to the Legend, represents "Lots that have been sent or sold, according to the order defined by the Accounting Method (see General section)". So does this mean that this number represents the amount of the crypto in "Crypto In" that has been used/allocated so far in cost basis calculations for gain/loss transactions?

Yes, and you'll be able to see the same transactions in the right half of the "Gain / Loss" table (the acquired lot half).

So, if we look at line 4 in "In-Flow Detail", does that mean that 1 BTC of 4 BTC has been used , and 3 BTC (from that "lot") remains associated with the BTC cost basis? Or is this, rather than being about cost basis, about the amount of the lot that has been removed from the particular exchange via a corresponding OUT transaction associated with the same exchange?

The "Sent/Sold" field shows the percentage of that acquired lot that has been disposed of. The "1" on the 4th line of the IN table should be a percentage (it should be 100%, not 1): I'm not sure why it doesn't show as percentage for you. What spreadsheet software are you using? I use Libre Office and it shows correctly as percentage for me.

Hope this helps.

gbtorrance commented 1 year ago

I think it's all starting to make sense. Thank you!

The "Sent/Sold" field shows the percentage of that acquired lot that has been disposed of. The "1" on the 4th line of the IN table should be a percentage (it should be 100%, not 1): I'm not sure why it doesn't show as percentage for you. What spreadsheet software are you using? I use Libre Office and it shows correctly as percentage for me.

That's weird. I'm using LibreOffice 6.0.7.3 running on Linux Mint, and I haven't done anything to the formatting. It just defaults to Number/General.

Thanks again for taking the time to explain all of this! I appreciate it. (Feel free to close the ticket if you're ready to do so.)

eprbell commented 1 year ago

I think it's all starting to make sense. Thank you!

Glad to hear that!

The "Sent/Sold" field shows the percentage of that acquired lot that has been disposed of. The "1" on the 4th line of the IN table should be a percentage (it should be 100%, not 1): I'm not sure why it doesn't show as percentage for you. What spreadsheet software are you using? I use Libre Office and it shows correctly as percentage for me.

That's weird. I'm using LibreOffice 6.0.7.3 running on Linux Mint, and I haven't done anything to the formatting. It just defaults to Number/General.

I'm using 7.2.7.2: can you try again with a more recent version?

Thanks again for taking the time to explain all of this! I appreciate it. (Feel free to close the ticket if you're ready to do so.)

No worries, sounds good.