Package: capitalg
Capital G: Capital Gains Tax CalculatorCalculate capital gains using either LIFO and FIFO methods.FeaturesCalculates capital gains based on FIFO or LIFO accounting methodsOutputs both long term and short term gainsAudit trail: Trace each cost base amount to its raw transactionsTax jurisdiction agnosticOutputs results to.csvfor easy spreadsheet analysisHandles transactions that are denominated in non tax currency (e.g. ETH/BTC)Tested on > 10k transactionsWho should use this?Spreadsheet-savy traders who need to calculate captial gains across thousands of tradesUseful where the assets have been traded on multiple exchanges, especially cryptocurrenciesWhy not use an existing tax service?This is freePrivacy, especially for cryptocurrency traders: Whilst it's convenient to have a crypto tax service automatically read your transactions from relevant exchanges, it typically involves sharing your exchange API keys with the tax service. This can expose all your funds to potential hackers and other bad actors.UsageSetuppip install capitalgCreate a folder calledcapitalg_filesto hold input and output files. This should contain your transactions intransactions.csv, and exchange rates inrates.csvif applicable.See input filesbelow for details on constructing these files.Calculate Capital Gainscapitalg calculate  -q lifo -t US/Pacific -c usd -d 2021-12-31-q can be either lifo or fifo-t is your timezone (optional - defaults to UTC). A list of valid timezones can befound here-c tax currency. Must be consistent with the formats in the transactions file-d tax year end date in YYYY-MM-DD format-p path to folder containing input and output files (defaults tocapitalg_files)When the calculation has finished,capitalg_fileswill contain the following output files:cg_events.csv: Shows every sale (a Capital Gains Tax event) and its assoicated cost base, including a cost base id. To see your taxable income, sum the "captial_gain_total" field within tax year dates. This file also splits captial gains into long term "captial_gain_lt" and short term "captial_gain_st"formatted_transactions.csv: A list of individual transactions after formatting. Formatting primarily involves demoninating all transactions in the base currencycost_base_transactions.csv: A list of "cost bases" used in each of the CG events. Links to the CG events file using the cost base idunallocated_cost_base_transactions.csv: consists of buy transactions that have not yet been assigned to a capital gains event (they will be used in future capital gains events)Calculate Capital Gains by Asset for a Tax YearTo calculate the total capital gains by tax year,cg_events.csvcan be imported to Excel or Google Sheets and summed by tax year and asset.Alternativelycapitalg summarycan be used to calculate capital gains by asset for a given tax year.capitalg calculateneeds to be run before running the summary command (capitalg_files/cg_events.csvmust be present). Capital gains can be calcualted for the year used in thecalculatecommand, or any prior year.capitalg summary -d 2021-12-31-d tax year end date in YYYY-MM-DD format-p Path to folder containing input and output files (defaults to./capitalg_files)Example outputbtc
captial_gain_total: 21,518
captial_gain_lt: 0
captial_gain_st: 21,518

eth
captial_gain_total: 33,609
captial_gain_lt: 0
captial_gain_st: 33,609

total
captial_gain_total: 55,127
captial_gain_lt: 0
captial_gain_st: 55,127To calculate an approximate outstanding asset balance at the time of the tax year end date that was used in thecalculatemethod,capitalg balancecan be used. This sums unallocated costs by asset. It also deducts any transaction fees paid in the currency of the assets from thetransactions.csvfile (for example, BTC transaction fees).capitalg balance -c usd-c tax currency. Must be consistent with the formats in the transactions file-p Path to folder containing input and output files (defaults to./capitalg_files)Example outputbtc: 7.8223
eth: 30.0287
...Calculating capital gains from within a python scriptfrom pathlib import Path

from capitalg import calculate_cg
from capitalg.analysis import get_balance, cg_summary
from capitalg.constants import FILE_CG_EVENTS, FILE_TRANSACTIONS, FILE_UNALLOCATED_COST_BASE_TRANSACTION

calculate_cg(
    input_path=Path('capitalg_files'),
    queue_type_code='lifo',
    tax_currency='usd', # must be lower case
    tax_timezone='US/Pacific',
    tax_year_end='2021-12-31'
)


# Capital gains can be totalled for the tax_year_end used in calculate_cg, and any prior years
cg_events_file = Path('capitalg_files') / FILE_CG_EVENTS
summary_2021 = cg_summary(cg_events_path=cg_events_file, tax_year_end='2021-12-31')
summary_2020 = cg_summary(cg_events_path=cg_events_file, tax_year_end='2020-12-31')

print('Capital Gains 2021')
print(summary_2021)
print()
print('Capital Gains 2020')
print(summary_2020)


# Balance will be as at '2021-12-31', which was used in calculate_cg
balance = get_balance(
    tax_currency='usd',
    transactions_file_path=Path('capitalg_files') / FILE_TRANSACTIONS,
    cost_base_file=Path('capitalg_files') / FILE_UNALLOCATED_COST_BASE_TRANSACTION
)

print('Asset balance as at 2021-12-31')
print(balance)Input filestransactions.csvcapitalg_files/transactions.csvis an aggregation of all transactions from all exchanges and all years prior and including the current tax year. The required fields are:fieldexampledescriptionidabc123transaction id for traceability - use the exchange id where possibleexchangebittrexexchange label for traceabilitydate2019-04-05T23:00:00datetime in ISO 8601 format. If ends in Z (Zulu), UTC is assumed. Be sure to include the T separatortzutctimezone of the transaction, must be fromthis list. If thedatefield ends in "Z", this field will be overridden with "UTC". Many exchanges use UTC, smaller exchanges may use their local timezones.typebuy"buy" or "sell"base_currencyusdbase currency of transaction. If this is not the same as your tax currency, you must provide exchange rates in the rates.csv fileasset_codebtcasset code, i.e. what was bought or soldqty0.4numeric - the quantity bought or soldprice9200.52numeric - the price of the asset denominated in the base currencyfee_currencyusdcurrency of the feefee10.5numeric - fees of transaction (e.g. brokerage) in the fee currencynoteexample noteoptional note on the transactionRows can be in any order (doesn't have to be chronological), as long as headers are on the first row.rates.csvThe header of the first column should bedate, with date fields in YYYY-MM-DD format, ideally in your tax timezone.Additional headers should be the value of the assets, with field values being the asset's daily exchange rates in your tax currency. For example, assuming tax currency is USD (exchange rates are made up for demo purposes):datebtceth2019-04-056012325002019-04-06614562598Recording non-standard transactions in thetransactions.csvfileThis is the approach I used for my personal tax return after discussions with my accountant. This is not tax advice. Circumstances may differ by jurisdiction. Discuss with a tax professional in your jurisdiction.Exchanging one asset for another assetWhen exchanging one asset for another, a captial gains tax event occurs. For example, if you buy ETH with BTC, this is treated as 2 separate transactions:The sale of BTC to your base currency (a taxable event)The purchase of ETH with your base currencycapitalgwill automatically split the transaction, however the transaction requires that the rates fields to be populated in order to estimate the "fair market value" of your base currency.Consider purchasing 5ETH for 0.125BTC. This can be recorded intransactions.csvas follows:idexchangetzdatetypebase_currencyfee_currencyasset_codeqtypricefeenote1bittrexutc2019-04-05T23:00:00Zbuybtcbtceth50.0250.0002ccSince this transaction is not denominated in the tax currency (usd in this example), we will need to provide the exchange rate of the base_currency of the transaction (btc), denominated in your taxable currency (usd). Note that the date in the rates file should ideally be in your tax timezone.rates.csv:datebtc2019-04-0560000Notes:The fee is in only gets allocated to the sale transaction to avoid double counting. You can see this in theformatted_transactions.csvoutput file.The rates file needs to contain exchange rates that are the "fair market value" in your tax currency. Ideally this would be the price at the time of the transaction, however this can be difficult, if not impossible to know. A suitable alternative might be to use a daily asset price, available from sites like CoinMarketCap. If you are unsure about this, seek local tax advice.Chain splitsAssuming sales of forked currencies are taxable in your jurisdiction, you can treat a chain split as a buy for price 0 at the time of the split. Only relevant fields shown:idexchangetzdatetypebase_currencyasset_codeqtypricefeenote1bittrexutc2017-10-05T23:00:00Zbuyusdbch0.500btc chain split to bchStolen / lost assetsA lost/stolen asset can be recorded as a sale for 0 in your tax currency. Only relevant fields shown:idexchangetzdatetypebase_currencyasset_codeqtypricefeenote1quadrigautc2018-11-05T23:00:00Zsellusdbtc0.500gerald cotten stole my moneyCryptocurrency withdrawal feesYou might be able to treat a withdrawal fee as a sale for price 0. In this way, the fee is captured as a capital gains loss from your cost base. Discuss with your tax professional. Only relevant fields shown:idexchangetzdatetypebase_currencyasset_codeqtypricefeenote1bittrexutc2018-11-05T23:00:00Zsellusdbtc0.000500withdrawawl feeOther incurred feesSometimes extraneous fees are incurred which are still related to your capital gains activities. For example, a bank might charge a transfer fee to deposit money on an exchange.You might be able to treat these as 0 quantity sales with the fees included. In this way, the fee is captured. Discuss with your tax professional.Example: A bank charges a $200 international transfer fee to deposit money to an exchange. Only relevant fields shown:idexchangetzdatetypebase_currencyasset_codeqtypricefeenote1bankutc2018-11-05T23:00:00Zsellusdna00200bank feeLegal DisclaimerThere is no warranty for this program. Do your own research and seek professional tax advice relevant to your tax jurisdiction.The creator and any contributors will not be held liable in any way for damages, losses or errors resulting from use of this module.DevelopmentTo develop / use the module in pre-configured environment, run it in a docker container:docker build -t captialg .docker container run -it --user "$(id -u)" --rm -v "$(pwd)":/usr/src/app:cached captialg bashTestingRun all testspytestFutureI have no intentions to automatically read transactions from cryptocurrency exchanges by integrating with their APIs. Not only is this an unbound task, it would undermine this library if/when exchange APIs break for whatever reason (for example exchanges can have system outages, or go out of business). If you wish to build a separate library that integrates with exchange APIs to populatetransactions.csv, I would consider linking to it in this README.In future, I would consider automatically extracting fiat and/or cryptocurrency rates from a reliable source in order to populaterates.csv, with the fallback option that a user could always provide their ownrates.csvfile.