FIFO Tax Lot Gains
MediumQueues · Robinhood
A brokerage tracks cost basis using first in, first out (FIFO) tax lots. You are given a chronological list of events; each event is [action, symbol, shares, price]:
["buy", symbol, shares, price]creates a new lot ofsharesshares ofsymbol, each bought atprice.["sell", symbol, shares, price]sellssharesshares ofsymbolatpriceeach.
A sell consumes shares from that symbol's lots starting with the oldest lot. If the oldest lot has fewer shares than still need to be sold, it is used up entirely and the sale continues with the next oldest lot. A lot that is only partly used keeps its remaining shares at their original price. Lots of different symbols never interact.
The realized gain of a sell is the sum, over every share it sells, of sell price - purchase price of that share's lot. It is negative when shares are sold at a loss.
Return a list with the realized gain of each sell event, in the order the sells occur. A sell never asks for more shares than are currently held for that symbol.
Example 1
- Input:
- events = [["buy", "HOOD", 4, 20], ["buy", "HOOD", 6, 25], ["sell", "HOOD", 7, 30], ["buy", "HOOD", 2, 18], ["sell", "HOOD", 5, 22]]
- Output:
- [55, -1]
- Explanation
- The first sell uses all 4 shares bought at 20 (gain 4 * 10 = 40) and then 3 of the shares bought at 25 (gain 3 * 5 = 15), for 55. The second sell takes the remaining 3 shares at 25 (3 * -3 = -9) and then 2 shares at 18 (2 * 4 = 8), for -1.
Example 2
- Input:
- events = [["buy", "AAPL", 10, 100], ["buy", "TSLA", 5, 200], ["sell", "TSLA", 5, 190], ["sell", "AAPL", 2, 150]]
- Output:
- [-50, 100]
- Explanation
- Each symbol has its own lots. Selling 5 TSLA at 190 against a cost of 200 loses 50; selling 2 AAPL at 150 against a cost of 100 gains 100.
Example 3
- Input:
- events = [["buy", "X", 3, 8], ["sell", "X", 1, 8], ["sell", "X", 2, 11]]
- Output:
- [0, 6]
- Explanation
- Selling at the purchase price realizes 0. The partly used lot still carries its original cost of 8, so the last 2 shares gain 3 each.
Constraints
0 <= events.length <= 10^5actionis"buy"or"sell";symbolis a non-empty uppercase string1 <= shares <= 10^61 <= price <= 10^6- Every sell is for at most the number of shares of that symbol currently held