Parse Robinhood transaction CSVs to estimate capital gains for the current year
- Download Robinhood "account activity report" transaction CSVs covering the history of your account. You may need to make multiple requests, for example one per year.
- Run
robinhood_capital_gains_estimator.py transactions.csvto calculate long and short term capital gains for the current year. You can pass in multiple files, or a directory of CSVs. Pass multiple files in chronological order, or if passing in a directory, name the enclosed CSVs such that when sorted by name, they will be in chronological order.
This script calculates an estimate for capital gains given the provided data, but it may not match the final values calculated by Robinhood. For example, Robinhood does not always provide cost basis data for older transactions in their account activity reports. In such cases, the script simply assumes a cost basis of 0. Some other transaction types such as SXCH and MRGS are also processed with cost basis assumed to be 0. There may also be some transaction types that this script is not aware of. For example, this script has not been tested with stock options transactions. In addition, this script assumes FIFO transaction ordering.
Lotclass:prev_lot(Reference to previousLot)instrument(Instrument name i.e. AAPL or SPY)purchase_date(Date when shares purchased)purchase_price(Price per share when purchased)quantity(Quantity of shares)sell_date(Date when shares sold)sell_price(Price per share when sold)next_lot(Reference to nextLot)
lot_roots(dict with references to the oldestLotfor each instrument)lot_heads(dict with references to the newestLotfor each instrument)current_quantities(dict containing the currentquantityof each instrument)
- Iterate through transactions (
Buy,CONV,SXCH,MRGS,Sell, andSPL) to build up a chain of lots for each instrument- If the transaction is a
Buy,CONV,SXCH, orMRGStransaction, a newLotis created and appended to the end of that instrument's chain. Thepurchase_priceis set to 0 forCONV,SXCH, andMRGStransactions (inaccurate but easier to handle). - If a
Selltransaction, theLotchain is traversed from itsROOT, marking lots as sold until the amount in theSelltransaction is fully allotted. If this causes aLotto be only partially sold, thatLotis split into two lots, with the firstLotcompletely sold and the secondLotcompletely unsold. - If a
SPLtransaction, theLotchain is traversed from itsHEADuntil a sold lot is found, multiplyingquantityof each unsoldLotby thesplit_ratio.current_quantitiesis also updated to store the new quantity of that instrument.
- If the transaction is a
- To calculate capital gains for current year, start at the
HEADof each instrument, iterate backwards until a sold lot is hit, then start counting profits per lot until hitting a lot sold prior to the current year.
Reverse splits (SPR) are not yet supported.
Currently, dividends (CDIV) and stock lending income (SLIP) are ignored. These could be tracked and included in the output.
Robinhood seems to have a bug where their stock split (SPL and SPR) transactions are logged to 4 decimal places, even though shares are held to 6 decimal places. This can cause stock split calculation errors. This script currently checks for such situations and prompts the user to input the correct split ratio. I have submitted a bug report to Robinhood, so hopefully this will get resolved in due time.