2011-04-14 71 views
0

我有一个包含交易列表的表:SQL损益库存查询

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 

所以损益基本Consid列的总和,因此加入贸易#5之前的损益会+ 6K。

贸易#5增加后,这表明PnL为-14k,这不是真的反映我们的立场。

我想要的是过滤未关闭的交易的某种方式?所以当我们添加了2k IBM股票的购买时,交易#5将被允许进入总和。

我在这个INTIAL尝试是:

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 >[email protected]) AND (Name = 'my_Comp') 
        GROUP BY ABS(Quantity) 
        HAVING (SUM(Quantity) = 0)) AS dt),0) 

但我没有想通了,有一个边缘状态,其中通过,如果我有一个行业与+ 5的量,+ 5,-5它不计算在内,因为(SUM(Quantity) = 0))的计算结果为false。

有关如何纠正此问题的任何想法?

感谢克里斯

+1

如果购买方是你的正数的交易卖方是负数量交易,你怎么知道5号位并不近,但4号位是?你是否有另外一个专栏或指标,表明第4位属于第2位的交易?例如,它仅仅是表中列出的交易顺序,所以位置5是最后一个,所以必须是开放位置? – 2011-04-14 17:15:20

回答

0

Runnable Example

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

感谢大家的回应 – 2011-04-15 13:43:16

+0

感谢大家的回应,首先解释我的问题更清楚一点:我可以在任何时候有一个负数或正数或零总数量。虽然我可以有一个详细说明开放或关闭位置的标志,这个位置不会非常灵活,也不会像我想的那样自动化。 @NathanDeWitt。我认为@ CadeRoux的想法可能会奏效,我需要首先使用数字,我的初步想法是假设我按时间顺序输入交易,这在大多数情况下都是正确的,但当失败时会出现边缘案例但我认为可以工作 – 2011-04-15 13:49:45

+0

我的另一个想法是使用加权平均价格来计算PnL,如果我走这条路线,我会发布代码 – 2011-04-15 13:50:49

0

而不是使用SQL对您的库存匹配,你可以有你的应用程序中的一个额外的“关闭”栏设置一个标志?然后,你可以这样做:

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

不能说你的逻辑,刚刚杀青你说的是错的:

HAVING (case when SUM(Quantity) = 0 then 1 else 0 end)