In order to calculate adjusted cost base (ACB), it's a running sum of either Price * Quantity + Commission, or Previous ACB/Share * Quantity, depending on whether it's a sale or a purchase.
I have the following table, named transaction_t
:
Date | Action | Quantity | Price | Commission |
---|---|---|---|---|
2021-01-02 | buy | 150 | 110.21 | 5.95 |
2021-01-21 | buy | 360 | 106.87 | 5.95 |
2021-03-21 | sell | 360 | 106.87 | 5.95 |
For calculating a running "adjusted cost base", I have the following query:
SELECT
SUM(CASE
WHEN T.Action in ("buy", "reinvest") THEN T.Quantity
WHEN Action = "sell" THEN -T.Quantity
END
) OVER (ORDER BY T.Date) AS quantity_balance,
SUM(CASE
WHEN T.Action in ("buy", "reinvest") THEN T.Quantity * T.Price + T.Commission
WHEN T.Action = "sell" THEN T.Quantity * ***(previous_total_acb / previous_quantity_balance)***[1]
END
) OVER (ORDER BY T.Date) AS total_acb
FROM transaction_t AS T;
This query doesn't work. Because the pseudo code previous_total_acb / previous_quantity_balance
are refering to the column that are being defined in that window function.
How to make this work in SQLite?
Note [1]: Here the previous_total_acb
is a pseuoudo code, I intend it to refer to the column itself, the total_acb
. But sqlite doesn't seem to support such looping-back reference.
The previous_quantity_balance
is referring to the sibling column that is also created by a window function, the quantity_balance
. This doesn't seem to work either.
You would use a CTE (or subquery) to prepare your lookback calculations, and then reference them in your final query. I don't understand your actual sql. Here is a simplified version that might not make sense but simply demonstrates the structure:
This first CTE is just to give some values, which in your case comes from your table:
WITH TBL(d, a, q, p)
AS
(
SELECT * FROM (
VALUES (20210102, 'buy', 150, 110.21),
(20210121, 'buy', 380, 106.87),
(20210321, 'sell', 360, 104.33)
)
),
so in reality you would start here with WITH
SRC AS
(
SELECT d,
a,
q,
p,
q*p AS cost,
lag(q*p) OVER (ORDER BY d) AS prev_cost
FROM TBL
)
Which yields this:
+--------+----+---+------+-------+---------+
|d |a |q |p |cost |prev_cost|
+--------+----+---+------+-------+---------+
|20210102|buy |150|110.21|16531.5|NULL |
|20210121|buy |380|106.87|40610.6|16531.5 |
|20210321|sell|360|104.33|37558.8|40610.6 |
+--------+----+---+------+-------+---------+
and from there you could use the current and previous values to produce a calculated field
SELECT d, cost, cost-prev_cost AS diff FROM SRC ORDER BY d;
which (as I said is just for demonstration and has no real meaning here) yields
+--------+-------+----------+
|d |cost |diff |
+--------+-------+----------+
|20210102|16531.5|NULL |
|20210121|40610.6|24079.1 |
|20210321|37558.8|-3051.79 |
+--------+-------+----------+
So putting that together and assuming your data is stored in TBL
it would look like
WITH SRC AS
(
SELECT d,
a,
q,
p,
q*p AS cost,
lag(q*p) OVER (ORDER BY d) AS prev_cost
FROM TBL
)
SELECT d, cost, cost-prev_cost AS diff FROM SRC ORDER BY d;
You can have as many CTE's as needed to prep your 'lookback' data. Not sure, but seems you might need at least one more middle prep CTE in your case to calculate previous_total_acb
before you can use it in your final query.