SQL Server:计算运行总计的重复值之间的PnL

时间:2018-11-15 18:44:49

标签: sql sql-server tsql

请查看以下列:K_ExeSharesExePriceRunningTotal。 我的任务是计算PnL for "1", "2"(如示意图所示)

编辑:添加了指向脚本表的链接

FULL SCRIPTED DATA IN T-SQL

Trimmed Dataset to Two trades

enter image description here

接下来是工作流程:

  1. 交易者在某些证券(在此情况下为SQ)中打开显示为“ a”(在“方向”栏中标记为“ OPENING”)的头寸,然后关闭“在”方向中标记为“ b”的仓位(“方向”中的“ CLOSING”)。
  2. 在平仓后,Running总计变为0
  3. 我需要将“ 1”,“ 2”上的损益计算为“为开立该头寸支付的钱”减去“为平开该头寸而收到的钱”。并针对每对开/关操作
  4. 请注意,需要在RunningTotal列中的两个零之间计算PnL。在所附的示例中,在ID为1至7的行之间,然后为8至21的行之间,等等。

在每个零值之间需要分别计算PnL 。换句话说,每批开/关应该是原子PnL计算。我们不能使用连续的,因为有时会引入不正确的值和数字,这将破坏将来的所有计算。因此,“ 1”中的PnL应该与“ 2”中的PnL calc完全分开。因为有成千上万的此类交易,我们不希望在一项交易中引入错误来影响所有连续的交易PnL。

预期结果:

中间计算 enter image description here

这是我需要的最终结果:

enter image description here

谢谢!

请为我的英语感到抱歉。

1 个答案:

答案 0 :(得分:1)

类似的事情应该在正确的轨道上。您可以尝试使用rollup而不是union来获取详细信息以及摘要行。当然,如果不需要明细行,则完全删除并集。

with rnk as (
    select *,
        sum(case when Direction = 'OPENING' and RunningLocal = 0 then 1 else 0 end)
            over (order by Id) as Block,
        case when Direction = 'OPENING' then -1 else 1 end * K_ExeShares * ExePrice as Cashflow
    from T -- your table
)
select
    Block, Direction,
    99999 as id, null as K_ExeShares, null as ExePrice, null as Cashflow,
    sum(Cashflow) as Ttl,
    case when Direction = 'OPENING' then 'BOUGHT' else 'SOLD' end as "Description"
from rnk
group by Block, Direction
union all
select
    Block, Direction,
    Id, K_ExeShares, ExePrice, Cashflow,
    sum(Cashflow) over (partition by Block, Direction order by Id),
    Direction
from rnk
order by Block, Direction desc, Id;

我相信这可以改善。 https://rextester.com/QFEKW74472

参加#2

看起来更近了:

with rnk as (
    select *,
        sum(case when Direction = 'CLOSING' and RunningTotal = 0 then 1 else 0 end)
            over (order by Id desc) as Block,
        -K_ExeShares * ExePrice as Cashflow
    from T -- your table
)
select
    max(Block) over () - Block as Block, Direction,
    Id, K_ExeShares, ExePrice, Cashflow,
    sum(Cashflow) over (partition by Block order by Id) as RunningTotalAmount
from rnk
order by Block, Direction desc, Id;

https://rextester.com/YMCX27766