Package: rp2
RP2 v1.5.0Privacy-focused, free, powerful crypto tax calculatorTable of ContentsIntroductionHow RP2 OperatesLicenseDownloadInstallationUbuntu LinuxmacOSWindows 10Other Unix-like SystemsRunningInput and Output FilesRP2 EcosystemList of Ecosystem ProjectsReporting BugsContributingDeveloper DocumentationFrequently Asked QuestionsChange LogIntroductionRP2is a privacy-focused, free, non-commercial, open-source, community-driven cryptocurrency tax calculator for multiple countries (currently US, Japan and Spain are supported). Preparing crypto taxes can be a daunting and error-prone task, especially if multiple transactions, coins, exchanges and wallets are involved. This task could be delegated to a crypto tax preparation service, but many crypto users value their privacy and prefer not to send their transaction information to third parties unnecessarily. Additionally, many of these services cost money. RP2 solves all of these problems:it manages the complexity related to coin flows and tax calculation and it generatesreports that accountants can understand(in the format of form 8949, for the US case), even if they are not cryptocurrency experts;it prioritizes user privacy by storing crypto transactions and tax results on the user's computer and not sending them anywhere else;it's 100% free, open-source and non-commercial.This means that with RP2 there are no transaction limits, no premium versions, no payment requests, no personal data sent to a server (at risk of being hacked), no account creation, no unauditable source code.Another unique advantage of RP2 istransparent computation: RP2 generates full computation details for every lot fraction, so that it's possible to:verify step-by-step how RP2 reaches the final result;track down every lot fraction and its accounting details, in case of an audit.RP2 currently supports theFIFOaccounting method for US and Spanish taxes and the Total Average Method for Japanese taxes.RP2 reads a configuration file and an input spreadsheet containing crypto transactions. Theseinput filescan be generated either manually or automatically usingDaLI, a RP2 data loader and input generator (which is also privacy-focused, free, non-commercial, open-source and community-driven). After parsing the input, RP2 uses high-precision math to calculate long/short term capital gains, cost bases, balances, average price, in/out lot relationships/fractions, and finally it generatesoutput files.RP2 has a programmable plugin architecture foroutput generators,accounting methodsandcountries. The builtin output generator plugins are in part generic and in part country-specific, but RP2's architecture makes it possible to contribute additional generators for different countries or for different country-based cases. The builtin output generator plugins are:tax_report_us: generates a US-specific tax report meant to be read by tax preparers (in the format of form 8949);tax_report_jp: generates a Japan-specific tax report meant to be read by tax preparers;rp2_full_report: generates a comprehensive report (valid for any country), with complete transaction history, lot relationships/fractions and computation details;open_positions: geterates a report (valid for any country) on assets with non-zero crypto balance: unrealized gains / losses, portfolio weighting, and more.RP2 has extensiveunit testcoverage to reduce the risk of regression.IMPORTANT DISCLAIMERS:RP2 offers no guarantee of correctness (read thelicense): always verify results with the help of a tax professional.The author of RP2 is not a tax professional, but has used RP2 personally for a few years.How RP2 OperatesRP2 has been designed to have expressive primitives that can be used as building blocks for most tax scenarios: complex tax events can be described with patterns, built on top of these primitives (see theFAQ listfor examples).RP2 treats virtual currency as property for tax purposes, as perIRS Virtual Currency Guidance.RP2 supports the FIFO accounting method: however, in and out lots typically don't have matching amounts, so RP2 fractions them, maps in/out lot fractions and computes the resulting cost basis and capital gains for each lot fraction.RP2 groups lot fractions into the following taxable event categories, each of which has aspecific tax treatment:AIRDROP: gains from airdrops;DONATE: donations to charitable organizations;FEE: fee-only transaction, used in some DeFi scenarios (e.g. gas fee for running certain smart contracts);GIFT: gifts to parties who are not charitable organizations (not tax-deductible).HARDFORK: gains from hard forks;INCOME: gains from miscellaneous income (e.g. Coinbase Earn);INTEREST: gains from interest;MINING: gains from mining;MOVE: the fee for moving currency between two accounts controlled by the same owner;SELL: specifically, sale andconversion of a cryptocurrency to another. RP2 splits them in two subcategories:long-term capital gains (if supported by the country plugin: e.g. in the US it's 1 year or more), orshort-term capital gains otherwise;STAKING: gains from staking;WAGES: income from crypto wages.For each of these categories RP2 generates an output spreadsheet with transaction details and computed gains/losses (seeInput and Output Filesfor more details). Users can give this output to their tax preparer with the rest of their tax documentation (see also FAQ onwhich tax forms to file). Note that buying cryptocurrency using fiat currency is not a taxable event.NOTE ON NFTs: Read theFAQ on NFTsto learn about how RP2 treats NFTs.LicenseRP2 is released under the terms of Apache License Version 2.0. For more information seeLICENSEorhttp://www.apache.org/licenses/LICENSE-2.0.DownloadThe latest version of RP2 can be downloaded at:https://pypi.org/project/rp2/InstallationRP2 has been tested on Ubuntu Linux, macOS and Windows 10 but it should work on all systems that have Python version 3.7.0 or greater.Installation on Ubuntu LinuxOpen a terminal window and enter the following commands:sudo apt-get update
sudo apt-get install python3 python3-pipThen install RP2:pip install rp2Installation on macOSFirst make sureHomebrewis installed, then open a terminal window and enter the following commands:brew update
brew install python3Then install RP2:pip install rp2Installation on Windows 10First make surePython3.7 or greater is installed (in the Python installer window be sure to click on "Add Python to PATH"), then open a PowerShell window and enter the following:pip install rp2Installation on Other Unix-like Systemsinstall python 3.7 or greaterinstall pip3pip install rp2RunningRP2 requires two files as input:an ODS-format spreadsheet, containing crypto transactions (ODS-format files can be opened and edited withLibreOfficeand many other spreadsheet applications);a config file, describing the format of the spreadsheet file: what value each column corresponds to (e.g. timestamp, amount, exchange, fee, etc.) and which cryptocurrencies and exchanges to expect.The two input files can either:be generated automatically usingDaLI, the data loader and input generator for RP2, orbe prepared manually by the user.The formats of these files are described in detail in theInput Filessection of the documentation.Examples of an input spreadsheet and its respective config file:input/crypto_example.odsconfig/crypto_example.ini.After reading the input files, RP2 computes taxes and generates output files, which contain information on long/short capital gains, cost bases, balances, average price, in/out lot relationships and fractions, etc. They are described in detail in theOutput Filessection of the documentation.To try RP2 with example files, downloadcrypto_example.odsandcrypto_example.ini. Let's call<download_directory>the location of the downloaded files.The RP2 executable is country-dependent:rp2_<country_code>, where country code is aISO 3166-1 alpha-2, 2-letter identifier (e.g.rp2_us,rp2_jp, etc).To generate US tax output for the example files open a terminal window (or PowerShell if on Windows) and enter the following commands:cd <download_directory>
rp2_us -o output -p crypto_example_ crypto_example.ini crypto_example.odsResults are generated in theoutputdirectory and logs are stored in thelogdirectory.To print full command usage information for therp2_uscommand:rp2_us --helpInput and Output FilesRead theinput filesandoutput filesdocumentation.RP2 EcosystemThis is a call for coders: come and help us expand RP2's functionality!RP2 is the first component of what could be a powerful, community-driven suite of open-source, crypto tax software. It is intended as the core of a larger project ecosystem, maintained by the community. These projects can extend RP2's capability, usefulness and ease of use in new ways. For example:DaLI data loader plugins: add support for more exchanges and wallets (via REST API and/or CSV files).Dali, the RP2 data loader, uses them to generate an input ODS file and a config file that can be fed directly to RP2;RP2 plugins: RP2 can be expanded via its programmable plugin architecture, which enables support for new output generators, countries and accounting methods;RP2 GUI: make RP2 more user-friendly and accessible to people who are not familiar with the CLI;RP2 high-level interface: RP2 captures complex tax events using a few powerful, low-level primitives, aggregated in patterns. A higher level tool, might abstract out these patterns and present them to the user in a friendlier way (for example it may capture a complex concept like DeFi bridging as a primitive, rather than a pattern);more...Important note: any RP2 ecosystem project must make user privacy its first priority.If you'd like to start an ecosystem project, please open anissueto let the RP2 community know.List of Ecosystem ProjectsHere's the current list of projects in the RP2 ecosystem:DaLI: data loader and input generator for RP2 (https://github.com/eprbell/rp2).Reporting BugsRead theContributingdocument.ContributingRead theContributingdocument.Developer DocumentationRead thedeveloper documentation.Frequently Asked QuestionsRead theuser FAQ listand thedeveloper FAQ list.Change LogRead theChange Logdocument.RP2 Change Log1.5.0added support for Spain (see #97)1.4.2fixed small bug in rp2_full_report generator: OUT transactions had slightly incorrect fiat_out field. The displayed value was fiat_out_no_fee - fiat fee, instead of fiat_out_no_fee. This bug didn't affect actual tax computation or the tax_report output: it only affected the fiat_out field in the OUT table of rp2_full_report.1.4.1added new RP2RuntimeError to handle non-recoverable problems without using Exception1.4.0added support for Japantemporarily disable LIFO and HIFO (seehttps://github.com/eprbell/rp2/issues/79)documentation improvements1.3.1fixed #77: accounting engine AVLTree keys didn't normalize timezones, which caused a rare but obscure bug in certain casesadded debug log for progress of tax engine during lot accounting. This should make it much easier to debug certain user data errors, such as "Total in-transaction crypto value < total taxable crypto value"fixed tax_report_us plugin bug: investment expenses sheet was resized only with number of move transactions (ignoring number of fee ones): this caused a row overflow when generating tax_report_us output under certain conditionsminor documentation improvements1.3.0configuration files are no longer expressed in JSON format: they now use the INI format. Old JSON-format configuration files can be converted automatically to the new INI format with the following command: rp2_config <json_config>1.2.0added support forswitching accounting methods year over yearadded support for simplified accounting method plugin creation. With this new infrastructure a new accounting method can be added by defining just two small methods. Seedocumentationupdated documentation with new accounting method features1.1.0fixed 2 bugs in HIFO plugin: see #74 for details. If you're using HIFO, be sure to upgrade to this or later version.refactored classic computer science data structures in separate Prezzemolo libraryadded FAQs and tweaked documentation1.0.9revised and improved all documentationadded FAQsminor fixes1.0.8added generated report localization infrastructure: it's now possible to generate taxes for any country in any language (e.g. Japanese taxes in French). See README.dev.md for detailsadded -g command line option to select the language to use for generated reportsdefault generators are now specified in the country plugin (so that each country can select their allowed generators)allowed accounting methods are now specified in the country plugin (so that each country can select their allowed accounting methods)minor fixes in the Legend generation codeupdated documentation with new Localization section and updated Country and Report plugin sections with latest API changesadded user FAQs1.0.6added HIFO accounting method pluginupdated documentation and FAQs1.0.5added country plugin for Japansmall improvements in documentation1.0.4fixed issue #39: if ODS file had numeric unique_id it tripped the type checking systemadded support for generators section in configuration: this allows users to select which generator plugins to run. Also deprecated -l/--plugin CLI optionsupdated documentation with new generators section descriptionadded FAQ1.0.3minor improvements1.0.2new open positions plugin, showing a variety of information on unrealized gains and losses (https://github.com/eprbell/rp2/pull/35)minor improvements to documentation1.0.0Tax season is over: time for RP2 to hit v1.0.0! RP2 (and DaLI) gained a lot of users and traction in less than one year of existence (https://star-history.com/#eprbell/rp2&Date). During this time lots of bugs were fixed and features added. Thanks to everybody who engaged with PRs, issues, discussions and DMs.0.9.31fixed a bug in rp2_full_report generator reported in #31: in out-transactions if crypto_fee == 0 and fiat_fee > 0, the fiat fee was reported as zero (but this affected only the output, not the tax calculation which was correct)added some user FAQs0.9.30minor improvements to documentation0.9.29various improvements to documentation0.9.28RP2 logo worked on Github, but not on Pypi: fixed0.9.27added RP2 logo to readme.mdimproved an error message when disposed-of crypto is greater than acquired crypto0.9.26removed requirements.txt: now using dev section in setup.cfg, which avoids duplication of informationadded FAQ on Excel being unable to open some RP2-generated ODS filesv0.9.25added initial version of developer FAQ document:https://github.com/eprbell/rp2/blob/main/docs/developer_faq.mdminor refactoring editsv0.9.24added crypto_fee to InTransactions (by popular demand): previously in-transaction fee would only accept fees in fiat, but in certain situations fee is paid in crypto (e.g. crypto conversion, etc.). With this fix, either crypto_fee or fiat fee can be assigned (not both). If fiat_fee is assigned, crypto_fee is set to 0. If crypto_fee is assigned, fiat_fee is set to crypto_fee * spot_price. The reason for this behavior is that if the fee is paid in fiat, then no crypto is used for the fee, but if the fee is paid in crypto, then its converted fiat value is needed to compute taxes. Note that RP2 models a non-zero crypto_fee with a separate fee-typed out-transaction.added new unit test for the new InTransaction crypto_fee (input/test_data4.ods)updated documentation to reflect new features from this releaseadded a new FAQ on crypto rewards and reworded various answers.v0.9.23added fee-only transactions: this type of transactions occur in certain DeFi scenarios (seerelevant FAQfor more)added documentation of transparent computation, including one new FAQ on how to verify RP2 tax computation results:https://github.com/eprbell/rp2/blob/main/docs/user_faq.md#how-to-verify-that-tax-computation-is-correctminor edits to documentationv0.9.19added new FAQsadded pointers in documentation to DaLI, the data loader and input generator for RP2:https://github.com/eprbell/dali-rp2v0.9.18improved error message when ods_parser._process_constructor_argument_pack tries to parse a numeric argument and fails because the value is not numericv0.9.17added an extra check in IntraTransaction constructor: if spot_price == 0 and fee > 0 then raise an error (because the fiat value of the fee cannot be computed)minor edits to documentationv0.9.16in the tax_report_us output the following tabs had the description field mistakenly hidden: Airdrops, Income, Interest, Mining, Staking, Wages. All other tabs didn't have the problem. The hidden field is now visiblethe unique_id field (containing hash or exchange-specific id) is now generated in the output files (both tax_report_us and rp2_full_report)v0.9.15added Income sheet to plugin ODS template (needed by tax_report_us generator to support the new Income InTransaction type)v0.9.14added support for Income-type InTransaction (to capture misc income like Coinbase Earn)renamed old unique_id field to internal_id and added a new unique_id field to all transactions, which captures hash for IntraTransactions and exchange-specific unique ids for In/OutTransactionsupdated documentation to reflect latest changesminor fixes and refactoringv0.9.13Add py.typed to rp2 package to indicate type hint support.v0.9.12Added support for multiple logger names (e.g. plugins can use different logger names than core RP2 code).v0.9.11refactored to_string() method to be top-level, so that it's easier to use in external projects.addedRP2 Ecosystemparagraph to README.mdadded a few more FAQs to user frequently asked questions documentimproved CLI descriptionminor fixesv0.9.10fixedissue #6: OUT transaction fee is now a deduction as perhttps://www.irs.gov/publications/p544andhttps://taxbit.com/cryptocurrency-tax-guide(previously it was considered part of proceeds and therefore taxed)restructured User FAQ documentadded several questions to User FAQ document (many of them DeFi-related)various edits and improvements throughout entire documentationv0.9.9add DONATE and GIFT-typed InTransactionschanged Legend sheet to include time filter informationupdated documentation to reflect changes in this versionv0.9.8added hyperlinks to rp2_full_report output:taxable events and acquired lots in tax sheet are now hyperlinked to their definition line in the in-out sheet. In LibreOffice, CTRL-click on them to jump to the target (on Mac Command-click)summary lines in the Summary sheet are now hyperlinked to the first line of the given year in the tax sheetmodified time filter CLI options (-f and -t) to accept a full date (YYYY-MM-DD): so it's now possible to filter transactions before and after a given daymajor refactoring: renamed "from lot" and "in lot" to "acquired lot" throughout identifiers, strings, templates, documentation, etc.updated documentation to reflect changes in this versionv0.9.7added profiler instrumentationadded large input test and refactored ODS output testremoved rmtree("output") from test_ods_output_diff.py: it modifies the file system, which can cause problems when running tests in parallel (currently not enabled, but that may change in the future).minor fixesv0.9.6fixed a bug in timestamp check: in and out lots were not allowed to have the same timestamp, but in certain scenarios it could happen (e.g. high-frequency trading)fixed a subtle corner-case bug in LIFO, which caused the first gain/loss pair to be incorrect: the minimal input that reproduced the bug is now captured in one of the tests (test_data2.ods, sheet B1). This ensures there will not be a regression.disable a link check in user faq: the link was failing the check (incorrectly) on Github actionsv0.9.5added new LIFO testsminor fixesv0.9.4added accounting-method programmable plugin infrastructure: by subclassing AbstractAccountingMethod it's now possible to add support for a new accounting method (previously only FIFO was hard-coded in)added accounting-method plugins: FIFO, LIFOadded accounting-method-specific tests, plus additional tests of internal classes (both new and old)Added Legend sheet to tax_report_us outputupdated documentation to reflect changes in this versionminor fixesv0.9.3added country-specific programmable plugin infrastructure: by subclassing AbstractCountry it's now possible to add support for a new country (currently only US is supported)abstracted out currency from APIs and code in general: references to "usd" have been changed to "fiat"updated documentation to reflect changes in this versionv0.9.2Verified software is up to date for FY 2021Wrote several answers in User FAQ documentMinor fixesv0.8.1Added several new tests (from/to_year command line option variations and new transaction types)Reworked time filter logic to fix two bugs related to -f and -t options:with time filtering on, running sums reflected only filtered transactions, instead of all transactions (in other words, running sums should not be affected by filtering)with time filtering on, number of fractions reflected also fractions with year higher than time filterwith time filtering on, sold lot percentages would be shown incorrectly in some casesUpdated documentation: various fixes and improvementsv0.8.0added new transaction types: AIRDROP, HARDFORK, INTEREST, MINING, STAKING, WAGES. Removed transaction type EARN, which used to encompass all the above typesrevisited output generators: rp2_report was renamed to rp2_full_report and mock_8949_us was renamed to tax_report_us. The tax_report_us plugin now generates one sheet per taxable event type: Airdrops, Capital Gains, Donations, Gifts, Hard Forks, Interest, Investment Expense, Mining, Staking, Wages.fixed bug in from/to_year logic: entry sets didn't consider the time filter in certain corner casesupdated documentation to reflect above changesv0.7.3Added from/to_year command line optionv0.7.2Minor fixes related to Pypi package distribution and uploadv0.7.1Minor fixes related to Pypi package distribution and uploadv0.7.0First version uploaded to PypiAdded pre-commit hooksAdded bandit security checksMajor revision of user and developer documentationFixed lint errorsVarious bug fixes and improvementsv0.6.0First version tracked in change logAdded Python packaging supportSwitched to high-precision math (decimal.Decimal)Finished documentation (except FAQs)Added bumpversionVarious bug fixes and improvements