From f228da98d889ad3e6f3adaa2ac90bb64d4991dc6 Mon Sep 17 00:00:00 2001 From: Aaron Fiore Date: Fri, 26 Jul 2024 20:05:23 -0700 Subject: [PATCH] hledger-flow: bittrex: cost-basis work-around for bitcoin.tax Issue #51 describes at least a few undocumented bitcoin.tax issues: - Bicoin.tax gives unexpected cost-basis results when `Fee` is given with `Total` (when `Total` is given in place of `Price`). The expectation is that bitcoin.tax will perform the cost-basis calculation on `Total` when `Fee` is also given. However, bitcoin.tax *will* give expected cost-basis results if `Price` is given in place of `Total` (with `Fee` also given) *or* if `Total` is given *after* local cost-basis adjustments are made (but *without* `Fee` given). The rationale for why docker-finance doesn't use `Price`: * docker-finance has all of the `Total`s; so `Price` isn't necessary. * Local price information isn't available for most trades (and shouldn't be necessary since all `Total`s are available). - Additionally, when `Fee` is non-fiat (crypto), it now must be marked as a SPEND in order to be disposed (and to produce an accurate closing report). - Finally, if `FeeCurrency` *does* not match either `Symbol` or `Currency` (e.g., BTC-ETH w/ BNB fee), it's unknown if cost-basis must be calculated locally as well (if `Total` is given). Local calculations cannot be done because `Fee` price information is (almost certainly) not available for this type of trade. Until upstream can assert that attaching the `Fee` will subsequently adjust the cost-basis of `Total` *and* dispose of the `Fee` in the process (while also allowing `Total` to be used in place of `Price`), the `Fee` (and `FeeCurrency`) column(s) must not be populated and values instead moved to SPEND (as described above). Upstream is aware of these issues (since May) and they're in the process of resolution. In the meantime, docker-finance work-arounds should suffice for all trades that have a fiat `Fee` and/or a `Fee`/`FeeCurrency` that matches one side of the trading pair. --- .../accounts/bittrex/bittrex-shared.bash | 19 ++++++++ .../accounts/bittrex/bittrex-shared.rules | 44 +++++++++++++++++-- 2 files changed, 59 insertions(+), 4 deletions(-) diff --git a/container/src/hledger-flow/accounts/bittrex/bittrex-shared.bash b/container/src/hledger-flow/accounts/bittrex/bittrex-shared.bash index e09889e..075641d 100755 --- a/container/src/hledger-flow/accounts/bittrex/bittrex-shared.bash +++ b/container/src/hledger-flow/accounts/bittrex/bittrex-shared.bash @@ -60,6 +60,7 @@ function parse_deposit() printf("%.8f", $4); printf OFS # Amount printf OFS # Proceeds printf OFS # Fees + printf OFS # Cost-basis printf $5 OFS # Destination printf $6 OFS # TXID printf "IN" OFS # Direction @@ -90,6 +91,22 @@ function parse_trade() # So, turn BTC-USD into two separate columns. sub(/-/, ",", $4) + # TODO: HACK: see #51 and respective lib_taxes work-around + # Calculate cost-basis + switch ($3) + { + case "BUY": + cost_basis=sprintf("%.8f", $6 + $7) + break + case "SELL": + cost_basis=sprintf("%.8f", $6 - $7) + break + default: + printf "FATAL: unsupported order type: " $3 + print $0 + exit + } + printf $1 OFS # UID printf date OFS # Date printf "TRADE" OFS # Type @@ -99,6 +116,7 @@ function parse_trade() printf("%.8f", $5); printf OFS # Amount printf("%.8f", $6); printf OFS # Proceeds printf("%.8f", $7); printf OFS # Fees + printf cost_basis OFS # Cost-basis printf OFS # Destination printf OFS # TXID printf OFS # Direction @@ -129,6 +147,7 @@ function parse_withdrawal() printf("%.8f", $4); printf OFS # Amount printf OFS # Proceeds printf("%.8f", $5); printf OFS # Fees + printf OFS # Cost-basis printf $6 OFS # Destination printf $7 OFS # TXID printf "OUT" OFS # Direction diff --git a/container/src/hledger-flow/accounts/bittrex/bittrex-shared.rules b/container/src/hledger-flow/accounts/bittrex/bittrex-shared.rules index 9477ea7..a990260 100644 --- a/container/src/hledger-flow/accounts/bittrex/bittrex-shared.rules +++ b/container/src/hledger-flow/accounts/bittrex/bittrex-shared.rules @@ -15,7 +15,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -fields code_,date,type,order_type,currency_one,currency_two,amount_,proceeds,fees,destination,txid,direction,subaccount +fields code_,date,type,order_type,currency_one,currency_two,amount_,proceeds,fees,cost_basis,destination,txid,direction,subaccount date-format %Y-%m-%d %H:%M:%S description %date +0000 @@ -59,7 +59,6 @@ if %type ^TRADE$ amount %amount_ %currency_one @@ %proceeds %currency_two account2 assets:bittrex:%subaccount:%currency_two comment type:%type, order_type:%order_type, code:%code_, taxed_as:%order_type - comment2 %date +0000,BUY,bittrex,%currency_one,%amount_,%currency_two,%proceeds,, if %type ^TRADE$ & %fees [1-9] @@ -67,11 +66,48 @@ if %type ^TRADE$ amount3 -%fees %currency_two account4 expenses:bittrex:%subaccount:fees:trades:%currency_two amount4 %fees %currency_two - comment2 %date +0000,BUY,bittrex,%currency_one,%amount_,%currency_two,%proceeds,%currency_two,%fees + +# +# BUY +# + +if %type ^TRADE$ +& %order_type ^BUY$ + comment2 %date +0000,BUY,bittrex,%currency_one,%amount_,%currency_two,%cost_basis,, + +if %type ^TRADE$ +& %order_type ^BUY$ +& %fees [1-9] + comment2 %date +0000,BUY,bittrex,%currency_one,%amount_,%currency_two,%cost_basis,%currency_two,%fees +# TODO: HACK: re: #51, FeeCurrency and Fee are added even though cost_basis is calculated (for non-fiat fee disposal, see lib_taxes) + +# TODO: HACK: see #51 and respective lib_taxes work-around +if %type ^TRADE$ +& %order_type ^BUY$ +& %fees [1-9] +& %currency_two ^USD$ + comment2 %date +0000,BUY,bittrex,%currency_one,%amount_,%currency_two,%cost_basis,, + +# +# SELL +# if %type ^TRADE$ & %order_type ^SELL$ amount -%amount_ %currency_one @@ %proceeds %currency_two - comment2 %date +0000,SELL,bittrex,%currency_one,%amount_,%currency_two,%proceeds,%currency_two,%fees + comment2 %date +0000,SELL,bittrex,%currency_one,%amount_,%currency_two,%cost_basis,, + +if %type ^TRADE$ +& %order_type ^SELL$ +& %fees [1-9] + comment2 %date +0000,SELL,bittrex,%currency_one,%amount_,%currency_two,%cost_basis,%currency_two,%fees +# TODO: HACK: re: #51, FeeCurrency and Fee are added even though cost_basis is calculated (for non-fiat fee disposal, see lib_taxes) + +# TODO: HACK: see #51 and respective lib_taxes work-around +if %type ^TRADE$ +& %order_type ^SELL$ +& %fees [1-9] +& %currency_two ^USD$ + comment2 %date +0000,SELL,bittrex,%currency_one,%amount_,%currency_two,%cost_basis,, # vim: sw=2 sts=2 si ai et