问题描述
|
我有一个包含交易清单的表:
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列的总和,因此在添加Trade#5之前,PnL为+ 6k。
在添加了交易#5之后,这显示PnL为-14k,这实际上并不能反映我们的立场。
我想要某种过滤掉未平仓交易的方法?因此,仅当我们在表中添加了购买的2k IBM股份时,Trade#5才被允许进入总和。
我最初的尝试是:
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))
的计算结果为false,所以不会被计算在内。
关于如何解决此问题的任何想法?
谢谢克里斯
解决方法
可运行示例
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,2000,22,-44000),(3,-1000,30,30000),(4,-2000,40000),(5,-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 ;
,除了使用SQL来匹配库存之外,您还可以让应用在其他“已关闭”列中设置标志吗?然后,您可以这样做:
SELECT Security,SUM(Consid)
FROM mytable
WHERE Closed = 1
GROUP BY Security
,不能说出您的逻辑,只是要纠正您说的错误:
HAVING (case when SUM(Quantity) = 0 then 1 else 0 end)