I need some help or pointers with a single query, that can build a profit/loss for each individual stock trade based on FIFO (first-in-first-out) principle on the dataset attached below. Should be compatible with SQL Server 2016+ and Azure SQL.
Example data looks like this:
StockName | TransactionDate | TranCode | Quantity | PriceUSD | TotalAmountUSD |
---|---|---|---|---|---|
StockABC | 2017-12-11 11:16:11.000 | BUY | 2364,444444 | 0,114323 | 270,310382 |
StockXYZ | 2017-12-11 11:16:11.000 | BUY | 2364,444444 | 0,114323 | 270,310382 |
StockABC | 2017-12-14 14:16:24.000 | SELL | 1000 | 0,158849 | 158,849 |
StockXYZ | 2017-12-14 14:16:24.000 | SELL | 1000 | 0,158849 | 158,849 |
StockABC | 2017-12-14 19:38:46.000 | SELL | 700 | 0,198934 | 139,2538 |
StockXYZ | 2017-12-14 19:38:46.000 | SELL | 700 | 0,198934 | 139,2538 |
StockABC | 2017-12-15 09:38:09.000 | SELL | 664,4444444 | 0,207171 | 137,65362 |
I need a calculation, that calculates profit for each individual trade.
E.g. if i buy 10 of stockABC at price 5 and buy 10 later to price 6, and i sell all 15 at price 9, i need to profit calculated, taking in regard price for for BUYS.
I have tried to play around with CTE's cursors and the likes, but i have only been able to find help regarding Totals on quantities.
Overall data amount is low (> 50000 rows in total), so don't put too much regard in performance.
Test data can be inserted from below:
CREATE TABLE dbo.Stock
(
Currency VARCHAR(50),
TransactionDate DATETIME,
TranCode VARCHAR(5),
Quantity NUMERIC(38,18),
Price NUMERIC(38,18),
CostBasis NUMERIC(38,18)
)
INSERT INTO dbo.Stock (Currency, TransactionDate, TranCode, Quantity, Price, CostBasis)
SELECT *
FROM
(SELECT
'StockABC' AS Currency,
'Dec 11 2017 11:16AM' AS TransactionDate,
'BUY' AS TranCode,
'2364.444444440000000000' AS Quantity,
'0.114323000000000000' AS Price,
'270.310382000000000000' AS CostBasis
UNION
SELECT
'StockABC' AS Currency,
'Dec 14 2017 2:16PM' AS TransactionDate,
'SELL' AS TranCode,
'1000.000000000000000000' AS Quantity,
'0.158849000000000000' AS Price,
'158.849000000000000000' AS CostBasis
UNION
SELECT
'StockABC' AS Currency,
'Dec 14 2017 7:38PM' AS TransactionDate,
'SELL' AS TranCode,
'700.000000000000000000' AS Quantity,
'0.198934000000000000' AS Price,
'139.253800000000000000' AS CostBasis
UNION
SELECT
'StockABC' AS Currency,
'Dec 15 2017 9:38AM' AS TransactionDate,
'SELL' AS TranCode,
'664.444444440000000000' AS Quantity,
'0.207171000000000000' AS Price,
'137.653620000000000000' AS CostBasis
UNION
SELECT
'StockABC' AS Currency,
'Dec 18 2017 11:34AM' AS TransactionDate,
'BUY' AS TranCode,
'1334.531919170000000000' AS Quantity,
'0.489515000000000000' AS Price,
'653.273392000000000000' AS CostBasis
UNION
SELECT
'StockABC' AS Currency,
'Dec 21 2017 9:02PM' AS TransactionDate,
'SELL' AS TranCode,
'334.531919170000000000' AS Quantity,
'0.473771000000000000' AS Price,
'158.491522000000000000' AS CostBasis
UNION
SELECT
'StockABC' AS Currency,
'Dec 26 2017 10:44AM' AS TransactionDate,
'BUY' AS TranCode,
'400.000000000000000000' AS Quantity,
'0.440974000000000000' AS Price,
'176.389600000000000000' AS CostBasis
UNION
SELECT 'StockABC' AS Currency, 'Dec 26 2017 10:45AM' AS TransactionDate, 'SELL' AS TranCode, '399.000000000000000000' AS Quantity, '0.438398000000000000' AS Price, '174.920802000000000000' AS CostBasis
UNION
SELECT 'StockABC' AS Currency, 'Dec 30 2017 11:34AM' AS TransactionDate, 'SELL' AS TranCode, '500.000000000000000000' AS Quantity, '0.633751000000000000' AS Price, '316.875500000000000000' AS CostBasis
UNION
SELECT 'StockABC' AS Currency, 'Jan 3 2018 5:45PM' AS TransactionDate, 'SELL' AS TranCode, '20.000000000000000000' AS Quantity, '1.056470000000000000' AS Price, '21.129400000000000000' AS CostBasis
UNION
SELECT 'StockABC' AS Currency, 'Jan 10 2018 8:48AM' AS TransactionDate, 'BUY' AS TranCode, '292.310860920000000000' AS Quantity, '0.750911000000000000' AS Price, '219.499441000000000000' AS CostBasis
UNION
SELECT 'StockABC' AS Currency, 'Mar 6 2018 6:51PM' AS TransactionDate, 'BUY' AS TranCode, '700.495360820000000000' AS Quantity, '0.283468000000000000' AS Price, '198.568019000000000000' AS CostBasis
UNION
SELECT 'StockABC' AS Currency, 'Mar 21 2018 3:42PM' AS TransactionDate, 'SELL' AS TranCode, '1472.806221740000000000' AS Quantity, '0.217339000000000000' AS Price, '320.098231000000000000' AS CostBasis
UNION
SELECT 'StockABC' AS Currency, 'Apr 11 2018 6:03PM' AS TransactionDate, 'BUY' AS TranCode, '910.127737230000000000' AS Quantity, '0.164000000000000000' AS Price, '149.260949000000000000' AS CostBasis
UNION
SELECT 'StockABC' AS Currency, 'Apr 16 2018 7:53AM' AS TransactionDate, 'SELL' AS TranCode, '450.000000000000000000' AS Quantity, '0.235482000000000000' AS Price, '105.966900000000000000' AS CostBasis
UNION
SELECT 'StockABC' AS Currency, 'Apr 24 2018 8:15PM' AS TransactionDate, 'SELL' AS TranCode, '460.127737230000000000' AS Quantity, '0.297748000000000000' AS Price, '137.002114000000000000' AS CostBasis
UNION
SELECT 'StockABC' AS Currency, 'Jul 13 2018 8:08PM' AS TransactionDate, 'BUY' AS TranCode, '1500.009200180000000000' AS Quantity, '0.133000000000000000' AS Price, '199.501224000000000000' AS CostBasis
UNION
SELECT 'StockABC' AS Currency, 'Jul 22 2018 5:08PM' AS TransactionDate, 'SELL' AS TranCode, '500.000000000000000000' AS Quantity, '0.174302000000000000' AS Price, '87.151000000000000000' AS CostBasis
UNION
SELECT 'StockABC' AS Currency, 'Aug 5 2018 5:34PM' AS TransactionDate, 'SELL' AS TranCode, '1000.009200180000000000' AS Quantity, '0.127404000000000000' AS Price, '127.405172000000000000' AS CostBasis
UNION
SELECT 'StockABC' AS Currency, 'Sep 22 2018 1:29PM' AS TransactionDate, 'BUY' AS TranCode, '1810.263568330000000000' AS Quantity, '0.082654000000000000' AS Price, '149.625525000000000000' AS CostBasis
UNION
SELECT 'StockABC' AS Currency, 'Nov 25 2018 2:55AM' AS TransactionDate, 'BUY' AS TranCode, '3000.000000000000000000' AS Quantity, '0.035000000000000000' AS Price, '105.000000000000000000' AS CostBasis
UNION
SELECT 'StockABC' AS Currency, 'Feb 11 2019 9:07AM' AS TransactionDate, 'BUY' AS TranCode, '1782.043635700000000000' AS Quantity, '0.042000000000000000' AS Price, '74.845833000000000000' AS CostBasis
UNION
SELECT 'StockABC' AS Currency, 'Mar 9 2019 2:19PM' AS TransactionDate, 'BUY' AS TranCode, '4190.000000000000000000' AS Quantity, '0.043930000000000000' AS Price, '184.066700000000000000' AS CostBasis
UNION
SELECT 'StockABC' AS Currency, 'Apr 25 2019 5:41PM' AS TransactionDate, 'BUY' AS TranCode, '2261.000000000000000000' AS Quantity, '0.075000000000000000' AS Price, '169.575000000000000000' AS CostBasis
UNION
SELECT 'StockABC' AS Currency, 'Sep 9 2019 5:06PM' AS TransactionDate, 'BUY' AS TranCode, '2200.000000000000000000' AS Quantity, '0.045927000000000000' AS Price, '101.039400000000000000' AS CostBasis ) A