Calculating capital gains using LIFO queue

Last-in, first-out (LIFO) in a method in which the most recent equities purchased are the first to be sold. In this post, I will focus on the implementation of LIFO method in Python.

LIFO queue In the previous post, I described the implementation of a FIFO queue in which the equities purchased first are the first to be sold. Hence, I highly recommend reading this description because in this post I will slightly modify the previous code and add the LIFO support.

Implementation

For the implementation, I chose a minimal possible set of packages that allows me to avoid external dependencies and better shows the details of the FIFO mechanism. The implementation heavily exploits deque class, which is a list with quicker append and pop operations from the right and left side of the container and more intuitive addition (appendLeft) and removal (popLeft) of elements. On the beginning we add have two transaction Trans(“2022-01-01”,5,10) and Trans(“2022-01-02”,5,12) which we place in our queue. Next, come sell transactions. Depending on the amount of sold shares, we have 3 cases.

Case 1

We take the next item Trans(“2022-01-03”,-5,12). The numbers of shares in buy and sell transactions are equal. In this case, the contrary pair of transactions is balanced. The previously removed buy transaction from the queue and the current sell transaction are not added to the queues. The next sell transaction Trans(“2022-01-04”,-5,12) repeats this pattern.

FIFO queue – case 1
FIFO queue – case 1

Case 2

We take the next item Trans(“2022-01-03”,-2,12). The number of shares in the buy transaction Trans(“2022-01-01”,5,12) which matches the sell transaction is 5. We deduct from shares between the buy and sell transaction and the updated buy transaction returns to the list. The next sell transaction Trans(“2022-01-04”,-8,12) is balanced by the remains of the 1st buy transaction and the whole 2nd buy transaction.

FIFO queue – case 2
FIFO queue – case 2

Case 3

We take the next item Trans(“2022-01-03”,-8,10). The number of shares in the buy transaction Trans(“2022-01-01”,5,12) is not sufficient to match the sell transaction. Therefore the buy transaction doesn’t return to the queue. Instead the unbalanced part of the sell transaction and the next sell transaction Trans(“2022-01-04”,-2,14) are balanced with the next buy transaction Trans(“2022-01-02”,5,12).

FIFO queue – case 3
FIFO queue – case 3

Source code

The source code is nearly the same as in the previous post. There are two lines that need simple alterations. What is important, we don’t change the way how elements are pulled from the queue. Instead, we modify how the queue is built. The new elements are placed on the left side – on the opposite side of the queue in the FIFO algorithm. As you can see, we can further parametrise our function which now will be able to compute both FIFO and LIFO queues.

def balanceQueue(all_trans,session,comp_method):
...
...
if tq.amount*t.amount>0:
    #return the first element back to the same place
    qTransactions.appendleft(tq)
    #add the new element to the list
    if comp_method=='fifo':
        qTransactions.append(t)
    else:
        qTransactions.appendleft(t)
...
...
if (t.amount!=0 and len(qTransactions)==0):
    #Add unbalanced transaction to the queue
    #The queue changes polarisation
    if comp_method=='fifo':
        qTransactions.append(t)
    else:
        qTransactions.appendleft(t)
...

The whole code

Leave a Reply

Your email address will not be published. Required fields are marked *