SQL PnL Inventory Query - PullRequest
       10

SQL PnL Inventory Query

0 голосов
/ 14 апреля 2011

У меня есть таблица, содержащая список сделок:

Security ;   Quantity ; Price ;  Consid
 1. IBM  ;    +1,000 ;   20  ;  -20k
 2. IBM  ;    +2,000 ;   22  ;  -44k
 3. IBM  ;    -1,000 ;   30  ;  +30k
 4. IBM  ;    -2,000 ;   20  ;  +40k
 5. IBM  ;    -2,000 ;   20  ;  -20k

Таким образом, PnL - это, как правило, сумма столбца Consid, поэтому до добавления сделки № 5 значение PnL было бы + 6k.

После того, как была добавлена ​​сделка № 5, это показывает, что PnL -14k, что на самом деле не отражает то, где мы стоим.

Что мне хотелось бы, так это какой-нибудь способ отфильтровать незамкнутые сделки? Таким образом, сделка №5 будет допущена к сумме только тогда, когда мы добавим в таблицу покупку 2 тыс. Акций IBM.

Моя первоначальная попытка была:

set @Ret = @Ret + isnull((SELECT SUM(GC) AS GS
FROM  (SELECT SUM(GrossConsid) * - 1 AS GC
                     FROM   Trades AS CT
                     WHERE  (SpecialCond = 'Prop') AND (SettType <> 'Futures') AND (TrdDt <= @Date) AND (TrdDt >=@StartDate) AND (Name = 'my_Comp')
                     GROUP BY ABS(Quantity)
                     HAVING (SUM(Quantity) = 0)) AS dt),0)

но я так и не понял, что существует граничное условие, при котором, если у меня есть сделки с количеством +5, + 5, -5, оно не считается, потому что (SUM(Quantity) = 0)) оценивается как ложное.

Есть идеи, как мне это исправить?

Спасибо, Крис

Ответы [ 3 ]

0 голосов
/ 14 апреля 2011

Не могу сказать о вашей логике, просто исправить то, что вы говорите, неправильно:

HAVING (case when SUM(Quantity) = 0 then 1 else 0 end)
0 голосов
/ 14 апреля 2011

Пример выполнения

DECLARE @tbl AS TABLE (Seq int, Security varchar(3), Quantity int, Price int, Consid int) ;
INSERT INTO @tbl VALUES
(1, 'IBM', 1000, 20, -20000)
,(2, 'IBM', 2000, 22, -44000)
,(3, 'IBM', -1000, 30, 30000)
,(4, 'IBM', -2000, 20, 40000)
,(5, 'IBM', -2000, 20, -20000);

WITH RunningInventory AS (
SELECT l.Seq, SUM(r.Quantity) AS Inv
FROM @tbl AS l
LEFT JOIN @tbl r
ON r.Seq <= l.Seq
GROUP BY l.Seq
)
SELECT *
FROM @tbl AS trx
INNER JOIN RunningInventory
    ON trx.Seq = RunningInventory.Seq
WHERE RunningInventory.Inv >= 0 ;
0 голосов
/ 14 апреля 2011

Вместо того, чтобы использовать SQL для сопоставления своих ресурсов, можете ли вы установить в своем приложении флаг в дополнительном столбце "Закрыто"?Тогда вы могли бы сделать это:

SELECT Security, SUM(Consid)
FROM mytable
WHERE Closed = 1
GROUP BY Security
...