Added taxes.org, and a table printer

This commit is contained in:
Peter Selby 2018-09-13 10:19:04 -07:00
parent b75d956c13
commit 90aefc0f29
4 changed files with 118 additions and 36 deletions

31
resources/taxes.org Normal file
View File

@ -0,0 +1,31 @@
* Taxes 2017
Basic idea:
- Make a list of all purchases and all sales in history.
- Take the sales from 2017. Calculate capital gains. That's the bulk of the
taxes.
- Trades count as sale of crypto #1, purchase of crypto #2.
- Already paid taxes for 2013...that should be accounted for in step 1.
- BCH and BTG count as income: all deposits should be multiplied by the day-1
value and counted as income--everything else counts as capital gains.
- BCH traded on the first day at $277, according to bitcoin.tax.
- Uhh, some Coinbase "sends" are really sales. Look for "Sent to Coinbase".
- Coinbase sent to Vault of Satoshi, where they were sold. Should be
considered sold...but I don't know how to calculate the tax. Anyway, I
paid it in 2014:
- 1AF6ZPez9NFc7nUfJtwBgod6aWcYaDTi3F
- 1LTrqFApTvfSn415Rjs1ukCVN149zADxxJ
- 1LTrqFApTvfSn415Rjs1ukCVN149zADxxJ
- 18as544Wxg3ZScCZo7fjWSV4JGUhsLv6AR
- 18as544Wxg3ZScCZo7fjWSV4JGUhsLv6AR
- 1GxxcLKjqHD1wZWoZ3KNgiqjQonGDpZS4
- 1G3GM7izNsegWnxTB3RbuXAkC9YZxfeYP1
- Definitely gifts:
- 1L4kschshGtKJPM3T5RXhBJYtEHhFa3xq (Omar)
- 18Co5639x3Dp1EExfbgEzBKXYn329cwYKt
- Vircurex:
- 1FripmTRgNFx6M2C7udeDWKYW8wfR5vuUU
- 1FripmTRgNFx6M2C7udeDWKYW8wfR5vuUU

View File

@ -22,32 +22,36 @@
(s/def ::recipient [:self :buyer :merchant])
(def txn-common [::id
::amount
::currency
::txn-type
::account
::currency])
(s/def ::notes string?)
(def txn-common-req [::id
::amount
::currency
::txn-type
::account
::currency])
(defmulti txn-type ::txn-type)
(defmethod txn-type :buy [_]
(s/keys :req (concat txn-common
(s/keys :req (concat txn-common-req
[::from-currency])
:opt [::amount-consumed]))
:opt [::notes]))
(defmethod txn-type :sell [_]
(s/keys :req (concat txn-common
(s/keys :req (concat txn-common-req
[])
:opt [::consuming-txns]))
:opt [::notes]))
(defmethod txn-type :trade [_]
(s/keys :req (concat txn-common
[::to-currency])))
(s/keys :req (concat txn-common-req
[::to-currency])
:opt [::notes]))
(defmethod txn-type :send [_]
(s/keys :req (concat txn-common [])
:opt [::recipient]))
(s/keys :req (concat txn-common-req [])
:opt [::notes]))
(defmethod txn-type :receive [_]
(s/keys :req (concat txn-common [])
:opt [::sender]))
(s/keys :req (concat txn-common-req [])
:opt [::notes]))
(defmethod txn-type :fee [_]
(s/keys :req (concat txn-common [])))
(s/keys :req (concat txn-common-req [])
:opt [::notes]))
(s/def ::txn (s/multi-spec txn-type ::txn-type))
(s/def ::txns (s/coll-of ::txn))
@ -59,4 +63,7 @@
::open ::high ::low ::close]
:opt-un [::volume_from ::volume_to])))
(s/def ::pricemaps (s/map-of keyword? ::pricemap))
(s/def ::rate-fetcher (s/fspec :args (s/cat :date ::datetime)
:ret decimal?))
(s/def ::rate-fetchers (s/map-of keyword? ::rate-fetcher))

View File

@ -13,7 +13,8 @@
(import/load-coinbase-csv (io/resource "Coinbase-50f5ebcff0c2719719000033-TaxTransactionsReport-2018-05-18-21_36_35.csv"))))
(defn rates []
(let [btcusd (import/load-bittrex-rates (io/resource "Bittrex_BTCUSD_1h.csv"))]
(let [btcusd (import/load-bittrex-rates (io/resource "Bittrex_BTCUSD_1h.csv"))
ada->usd (partial import/bittrex-rate:ada->usd btcusd)]
(-> {}
(assoc :btc->usd (-> btcusd (import/bittrex-rate:btc->usd)))
(assoc :bcc->usd (-> (io/resource "Poloniex_BCHUSD_1h.csv")
@ -21,7 +22,7 @@
(import/bittrex-rate:bcc->usd)))
(assoc :ada->usd (-> (io/resource "Bittrex_ADABTC_1h.csv")
(import/load-bittrex-rates)
(partial import/bittrex-rate:ada->usd btcusd)))
ada->usd))
(assoc :eth->usd (-> (io/resource "Bittrex_ETHUSD_1h.csv")
(import/load-bittrex-rates)
(import/bittrex-rate:eth->usd)))
@ -30,8 +31,42 @@
(import/coinmarketcap-rate:btg->usd)))
(assoc :usdt->usd (fn [date] 1)))))
(s/fdef rates
:ret ::tax/pricemaps)
:ret ::tax/rate-fetchers)
(defn bittrex []
(import/merge-bittrex-transactions (rates)
(import/load-bittrex-csv "resources/bittrex-fullOrders.csv")))
(defn all-txns []
(concat (gdax) (coinbase) (bittrex)))
(defn project [ks m]
(into {} (map (fn [k] [k (get m k)]) ks)))
(defn round-str [dec]
(format "%.2f" dec))
(let [format (java.text.SimpleDateFormat. "yyyy-MM-dd")]
(defn format-date [date]
(.format format date)))
(defn update-field [field f txns]
(map (fn [txn] (update txn field f)) txns))
(defn print-as-table [txns]
(let [restrict-fields (partial project [::tax/timestamp
::tax/txn-id
::tax/txn-type
::tax/amount
::tax/currency
::tax/usd-amount
::tax/id
;;::tax/notes
])]
(clojure.pprint/print-table
(->> txns
(sort-by ::tax/timestamp)
(update-field ::tax/amount round-str)
(update-field ::tax/usd-amount round-str)
(update-field ::tax/timestamp format-date)
(map restrict-fields)))))

View File

@ -8,7 +8,7 @@
[clojure.spec.alpha :as s]
[orchestra.spec.test :as st]))
(st/instrument)
;;(st/instrument)
(defn file? [obj]
(instance? java.io.File obj))
@ -114,7 +114,8 @@
::tax/usd-amount (:usd_amount_transacted txn)
::tax/account :coinbase
::tax/amount (:quantity_transacted txn)
::tax/currency (:asset txn))
::tax/currency (:asset txn)
::tax/notes (str/replace (:notes txn) #"\n" " :: "))
(common->local)))
(defmulti coinbase->local :transaction_type)
@ -130,7 +131,7 @@
(defmethod coinbase->local :receive [txn]
(-> txn
(assoc ::tax/txn-type :recieve)
(assoc ::tax/txn-type :receive)
(common-coinbase->local)))
(defmethod coinbase->local :send [txn]
@ -144,8 +145,7 @@
(common-coinbase->local)))
(defn merge-coinbase-transactions [txns]
(map coinbase->local txns
))
(map coinbase->local txns))
(defn common-gdax->local [txn]
(-> txn
@ -296,15 +296,18 @@
:args (s/cat :bccusd ::tax/pricemap)
:ret (s/fspec :args (s/cat :date ::tax/timestamp) :ret decimal?))
(defn pp [obj]
(clojure.pprint/pprint obj)
obj)
(defn bittrex-rate:ada->usd [btcusd adabtc]
(let [->usd (bittrex-rate:btc->usd btcusd)
timestamps (sort (keys adabtc))]
(fn [date]
(let [ada-in-btc (first (map get-avg-rate
(get adabtc (bsearch-timestamps timestamps
(.getTime date)))))
btc-in-usd (->usd date)]
(* ada-in-btc btc-in-usd)))))
(.getTime date)))))]
(* ada-in-btc (->usd date))))))
(s/fdef bittrex-rate:ada->usd
:args (s/cat :btcusd ::tax/pricemap :adabtc ::tax/pricemap)
:ret (s/fspec :args (s/cat :date ::tax/timestamp) :ret decimal?))
@ -329,14 +332,14 @@
(s/fdef bittrex-rate:usdt->usd
:ret (s/fspec :args (s/cat :date ::tax/timestamp) :ret decimal?))
(defn build-bittrex-rates [btcusd-csv bccusd-csv adabtc-csv ethusd-csv]
#_(defn build-bittrex-rates [btcusd-csv bccusd-csv adabtc-csv ethusd-csv]
(let [btcusd (load-bittrex-rates btcusd-csv)]
{:btc->usd (-> btcusd bittrex-rate:btc->usd)
:bcc->usd (-> bccusd-csv load-bittrex-rates bittrex-rate:bcc->usd)
:ada->usd (-> adabtc-csv load-bittrex-rates (partial bittrex-rate:ada->usd btcusd))
:eth->usd (-> ethusd-csv load-bittrex-rates bittrex-rate:eth->usd)
:usdt->usd (bittrex-rate:usdt->usd)}))
(s/fdef build-bittrex-rates
#_(s/fdef build-bittrex-rates
:args (s/cat :btcusd-csv file?
:bccusd-csv file?
:adabtc-csv file?
@ -364,30 +367,36 @@
(assoc ::tax/txn-type :sell
::tax/amount (:quantity txn)
::tax/currency (:from-currency txn)
::tax/usd-amount usd-amount)
::tax/usd-amount usd-amount
::tax/notes "split from sell")
(common-bittrex->local))
(-> txn
(assoc ::tax/txn-type :buy
::tax/amount (with-precision 10 (/ (:quantity txn)
(:price txn)))
::tax/currency (:to-currency txn)
::tax/usd-amount usd-amount))]))
::tax/usd-amount usd-amount
::tax/notes "split from sell")
(common-bittrex->local))]))
(defn bittrex-buy->local-txns [rates txn]
(let [usd-amount (* (:quantity txn)
(get-bittrex-rate rates (:to-currency txn) :usd (:closed txn)))]
(get-bittrex-rate rates (:from-currency txn) :usd (:closed txn)))]
[(-> txn
(assoc ::tax/txn-type :buy
::tax/amount (:quantity txn)
::tax/currency (:to-currency txn)
::tax/usd-amount usd-amount)
::tax/usd-amount usd-amount
::tax/notes "split from buy")
(common-bittrex->local))
(-> txn
(assoc ::tax/txn-type :sell
::tax/amount (with-precision 10 (/ (:quantity txn)
(:price txn)))
::tax/currency (:from-currency txn)
::tax/usd-amount usd-amount))]))
::tax/usd-amount usd-amount
::tax/notes "split from buy")
(common-bittrex->local))]))
(defn bittrex-txn->local-txns [rates txn]
(match (:type txn)