如何计算期货的平仓盈亏和持仓盈亏
计算平仓盈亏和持仓盈亏 曾创能 2010/03
1.1 平仓盈亏和持仓盈亏计算原理
1.1.1 构造游标
构造三个游标
CURSOR_COPEN:当日开仓记录 从当日成交表中获取所有开仓记录(OffSetFlag='0'),按持仓实体(合约代码、会员代码、客户号、投保标志、方向、交易日期、成交编号)排序
CURSOR_CCLOSETODAY:当日平仓记录 从当日成交表中获取平今仓记录(OffSetFlag='3'),按持仓实体排序;
CURSOR_CCLOSEYESTODAY:当日平昨仓记录 从当日成交表中获取平昨仓记录(OffSetFlag='4');
以下基于以上三个个游标,构建今开仓明细记录(即去掉当日平仓后的净新开仓)和平仓明细记录。
今开仓明细计入TODAY_OPEN_DETAIL表,平仓明细计入CLOSE_DETAIL表。
1.1.2 盈亏计算处理
1. 初始化:
打开CURSOR_COPEN;
打开CURSOR_CCLOSETODAY;
从CURSOR_COPEN中取第一条开仓记录;
从CURSOR_ CCLOSETODAY中取第一条平今仓记录;
剩余开仓数量= CURSOR_COPEN.数量
剩余平仓数量= CURSOR_CCLOSETODAY.数量
2. 如果CURSOR_CCLOSETODAY为空,即无当日平仓,那么CURSOR_COPEN中所有记
录即为当日新开仓记录,计入TODAY_OPEN_DETAIL表,如果CURSOR_CCLOSETODAY不为空,那么需对平今记录进行循环处理。 3. 循环
判断:
如果CURSOR_CCLOSETODAY的指针已指向末尾,那么将当前CURSOR_COPEN计入当日新开仓明细表TODAY_OPEN_DETAIL,开仓数量取 剩余开仓数量
CURSOR_COPEN指针往后移
剩余开仓数量=CURSOR_COPEN.数量
否则,进行如下处理:
分支一:如果CURSOR_CCLOSETODAY中客户合约与CURSOR_COPEN中相同 分支二:如果CURSOR_CCLOSETODAY中客户合约与CURSOR_COPEN不相同
对于分支一的说明: 分支一表明:存在对当前开仓对应的持仓实体的平仓记录。此时需要处理平仓。按先开先平的原则,需要将持仓实体的当日开仓按成交编号逐一对冲。 对于分支二的说明:
分支二表明:存在对当前开仓对应的持仓实体的平仓记录。此时,当日开仓记录对应的持仓实体已无当日平仓记录可处理。
因此,需对分支一和分支二分别处理。
4. 对分支一的处理
判断
如果 剩余平仓数量
将当前CURSOR_CCLOSETODAY计入平仓明细表CLOSE_DETAIL,数量取 剩余平仓数量,开仓价取 CURSOR_COPEN.成交价格; 剩余开仓数量 = 剩余开仓数量 - 剩余平仓数量 剩余平仓数量 = 0
CURSOR_CCLOSETODAY指针往后移;
剩余平仓数量=CURSOR_CCLOSETODAY.数量;
否则,如果剩余平仓数量 > 剩余开仓数量 将当前CURSOR_CCLOSETODAY计入平仓明细表CLOSE_DETAIL,数量取剩余开仓数量,开仓价取CURSOR_COPEN.成交价格; 剩余平仓数量 = 剩余平仓数量 -剩余开仓数量 剩余开仓数量=0
CURSOR_COPEN指针往后移;
剩余开仓数量=CURSOR_COPEN.数量;
否则,剩余平仓数量 = 剩余开仓数量
将当前CURSOR_CCLOSETODAY计入平仓明细表CLOSE_DETAIL,数量取剩余开仓数量,开仓价取CURSOR_COPEN.成交价格; 剩余平仓数量 = 0 剩余开仓数量 = 0
CURSOR_COPEN指针往后移;
CURSOR_CCLOSETODAY指针往后移; 剩余开仓数量=CURSOR_COPEN.数量;
剩余平仓数量=CURSOR_CCLOSETODAY.数量;
5. 对分支二的处理
对于分支二,有如下几种子分支:
子分支A: 平仓记录对应的实体发生变化,开仓记录对应的实体未发生变化(相对于各自当前指针的上一条)
子分支B:平仓记录对应的实体和开仓记录对应的实体同时发生变化(相对于各自当前指针的上一条),且变化后的实体不相同
子分支C:平仓记录对应的实体未发生变化,开仓记录对应的实体发生变化(相对于各自当前指针的上一条)
6. 对于子分支A的处理
此种情况下,平仓已经处理完毕,当前持仓实体仍有开仓记录。 当前平仓实体 = CURSOR_CCLOSETODAY.主键。 需做如下处理:
✓ 将当前CURSOR_COPEN计入今开仓明细表TODAY_OPEN_DETAIL。
其中,如果 剩余开仓量 0 ,那么 开仓数量 取 剩余开仓量 否则 开仓数量 取 CURSOR_COPEN中的成交数量; 如果 剩余开仓量 0 ,那么 剩余开仓量 = 0; ✓ CURSOR_COPEN指针往后移;
✓ 剩余开仓数量=CURSOR_COPEN.数量; ✓ 剩余平仓量 = 0
7. 对于子分支B的处理
此种情况下,表明变化后的开仓记录对应的持仓实体,今天没有平今仓记录。 剩余开仓量 = 0
当前平仓实体 = CURSOR_CCLOSETODAY.主键。 当前开仓实体 = CURSOR_COPEN.主键。
需将当前CURSOR_COPEN计入今开仓明细表 TODAY_OPEN_DETAIL。具体处理与上一步相同。
8. 对于子分支C的处理
此种情况下,表明开仓记录当前实体发生变化,且该实体没有平今仓记录。 剩余开仓量 = 0
当前开仓实体 = CURSOR_COPEN.主键。
需将当前CURSOR_COPEN计入今开仓明细表 TODAY_OPEN_DETAIL。具体处理与上一步相同。
循环的退出条件为: CURSOR_COPEN 和 CURSOR_CCLOSETODAY的指针都已针到末尾。
9. 对CURSOR_ CCLOSETODAY进行处理,将其插入到平仓明细表CLOSE_DETAIL
对CURSOR_ CCLOSETODAY循环,逐一取其记录,插入到平仓明细表CLOSE_DETAIL表。
其中,开仓价 取 昨结算价。 10. 计算平仓盈亏
平仓盈亏=∑(CLOSE_DETAIL.平仓价-CLOSE_DETAIL.开仓价)*CLOSE_DETAIL.平仓数量*合约乘数 11. 计算持仓盈亏
对于今开仓明细表 TODAY_OPEN_DETAIL,按持仓实体分组,统计 今仓量。 通过当日客户持仓(快照)表,找出持仓实体对应的持仓总量。 理论上:持仓总量 = 今仓量 + 昨仓量(或称历史仓量) 那么,昨仓量 = 持仓总量 -今仓量
根据 昨仓量 和 今开仓明细表 TODAY_OPEN_DETAIL 计算持仓盈亏
持仓盈亏 = 昨仓量 * ( 今结算价 – 昨结算价) + ∑(今结算价 - TODAY_OPEN_DETAIL. 开仓价)* TODAY_OPEN_DETAIL.数量
1.2 平仓盈亏和持仓盈亏计算实例分析
1.2.1 假定与约束
假定:
昨日对应的交易日为2009/03/22 今日对应的交易日为2009/03/23 会员代码均为0001 投保标志均为投机 多空方向均为多头
品种CU交易单位1手=5吨,成交价按每吨计
当前状态下各类数据如下:
1.2.1.1 今开仓明细和平仓明细计算过程
1. 打开CURSOR_COPEN和CURSOR_CCLOSETODAY
2. CURSOR_CCLOSETODAY不为空,需对平今记录进行循环处理
3. 当前CURSOR_COPEN对应的实体(客户:111111;合约:CU0907)与
CURSOR_CCLOSETODAY对应的实体(客户:222222;合约:CU0908)不同,走分支二 4. 平仓记录对应的实体和开仓记录对应的实体同时发生变化(原来都为空),走分支B 5. 将当前CURSOR_COPEN计入今开仓明细表TODAY_OPEN_DETAIL,此时:
CURSOR_COPEN指针往后移(此时指针序号为2)
6. 当前CURSOR_COPEN对应的实体(客户:111111;合约:CU0908)与
CURSOR_CCLOSETODAY对应的实体(客户:222222;合约:CU0908)不同,走分支二 7. 平仓记录对应的实体未变化,开仓记录对应的实体发生变化,走分支C
CURSOR_COPEN指针往后移(此时指针序号为3)
9. 当前CURSOR_COPEN
对应的实体(客户:222222;合约:CU0908)与
CURSOR_CCLOSETODAY对应的实体(客户:222222;合约:CU0908)相同,走分支一 10. 剩余开仓数量=4,剩余平仓数量=6
剩余平仓数量>=剩余开仓数量
将当前CURSOR_CCLOSETODAY计入平仓明细表CLOSE_DETAIL,此时: 剩余开仓数量=0
CURSOR_COPEN指针往后移(此时指针序号为4) 剩余开仓数量=6 11. 当前CURSOR_COPEN对应的实体(客户:222222;合约:CU0908)与
CURSOR_CCLOSETODAY对应的实体(客户:222222;合约:CU0908)相同,走分支一 12. 剩余开仓数量=6,剩余平仓数量=2
剩余平仓数量
将当前CURSOR_CCLOSETODAY计入平仓明细表CLOSE_DETAIL,此时: 剩余开仓数量=6-2=4 剩余平仓数量=0
CURSOR_CCLOSETODAY指针往后移(此时指针序号为2) 剩余平仓数量=4 13. 当前CURSOR_COPEN对应的实体(客户:222222;合约:CU0908)与
CURSOR_CCLOSETODAY对应的实体(客户:222222;合约:CU0908)相同,走分支一 14. 剩余开仓数量=4,剩余平仓数量=4
剩余平仓数量>=剩余开仓数量
剩余平仓数量=4-4=0
剩余开仓数量=0
CURSOR_COPEN指针往后移(此时指针序号为5)
CURSOR_CCLOSETODAY指针往后移(此时指针序指向结尾EOF) 剩余开仓数量=7
15. 当前CURSOR_COPEN对应的实体(客户:222222;合约:CU0908),而
CURSOR_CCLOSETODAY已指向末尾,等同于持仓实体不同,并走分支B,
CURSOR_COPEN指针往后移(此时指针指向结尾EOF) 17. 循环结束
此时:
注:最后一行(绿色)为平昨仓明细,开仓价取昨结算价
1.2.2 今开仓明细和平仓明细结果
今开仓明细:
1.2.3 持仓盈亏和平仓盈亏
● 客户111111
⏹ 持仓盈亏
对于合约CU0907,持仓盈亏为:
(29900-30000)*2*5 + (29900-29500)*(5-2)*5=5000 对于合约CU0908,持仓盈亏为:
(30000-29600)*2*5 + (30000-29800)*(2-2)*5=4000 该客户的持仓盈亏为:5000+4000=9000
⏹ 平仓盈亏
对于合约CU0907,平仓盈亏为:
(29300-29500)*2*5 + 0 = -2000
对于合约CU0908,平仓盈亏为: 0 + 0 =0
该客户的平仓盈亏为: -2000 + 0 = -2000
● 客户222222
⏹ 持仓盈亏
对于合约CU0907,持仓盈亏为: 0 + (29900-29500)*(4-0)*5=8000
对于合约CU0908,持仓盈亏为:
(30000-29500)*7*5 + (30000-29800)*(13-7)*5=23500 该客户的持仓盈亏为:8000+23500=31500
⏹ 平仓盈亏
对于合约CU0907,平仓盈亏为:
0+ 0 = 0
对于合约CU0908,平仓盈亏为:
(29200-29000)*4*5+(29200-29000)*2*5+(29400-29000)*4*5 =14000
该客户的平仓盈亏为: 0 + 14000 = 14000