CTP查询持仓和持仓明细的那些事儿

Posted shclbear

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CTP查询持仓和持仓明细的那些事儿相关的知识,希望对你有一定的参考价值。

很多CTP初学者遇到的一个头疼的事情, 就是持仓和持仓明细的查询. 这里简单介绍一下这二者的查询的处理, 希望有所帮助.

 

  • 查询持仓明细

     

持仓明细是开仓成交产生的逐笔持仓. 

 

CTP查询持仓明细的请求函数是 

int ReqQryInvestorPositionDetail

(CThostFtdcQryInvestorPositionDetailField*pQryInvestorPositionDetail, int nRequestID);

查询持仓明细的响应函数是 

void OnRspQryInvestorPositionDetail

(CThostFtdcInvestorPositionDetailField* pInvestorPositionDetail, 

CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast);

 

用户可以根据交易所代码和合约代码来查询持仓明细. 下面是一个示例:

 
查询持仓明细示例

 

        和其他查询类似, 查询持仓明细受到查询流控的影响, 在途查询仅能有一笔, 同时有两次查询时间间隔的限制(一般为间隔1秒), 同样的, 可以不填BrokerID和Investor, 若如此做, 则为默认查询登录的此账户的持仓明细. 查询时, 可以不填InstrumentID或ExchangeID, 若如此做, 则为InstrumentID或ExchangeID不做限制, 即查询满足其他条件的任意合约或任意交易所的合约的持仓明细.

        查询持仓明细的响应中, 若有多条满足条件的持仓明细, 则分成多次返回, 最后一条的记录bIsLast值为true, 若没有满足条件的持仓明细, 则仅返回一条, 其bIsLast值为true, 且pInvestorPositionDetail为空指针.

 

        持仓明细由开仓成交产生, 成交数量即为持仓明细的数量(Volume), 平仓会使得数量减少, 数量减少到0时, 表明此笔持仓数量被全部平掉, 查询时, 当天被全平的持仓明细也仍会出现在响应中, 因此, 有的查询到的持仓明细记录的数量(Volume)为0. 结算后, 平仓完的持仓明细将被清除, 无法再查询到.

 

        持仓明细的key是以下字段的组合: 

BrokerID(经纪公司代码) + InvestorID(投资者代码) + HedgeFlag(投机套保标志) + Direction(买卖方向) + OpenDate(开仓日期) + TradeID(成交编号) + TradeType(成交类型). 

        对于不涉及套期保值和组合合约交易的大部分投资者来说, 可以忽略HedgeFlag和TradeType字段. 如果不考虑自成交的情况, 可以忽略Direction字段. 因此对单个账户的持仓明细的key可以简化为:

OpenDate(开仓日期) + TradeID(成交编号). 

 

OpenDate: 开仓日期. 即此笔持仓明细开仓成交的日期(交易日).

TradeID: 成交编号. 即此笔持仓明细开仓成交的成交编号. 

由于CTP中不同的交易日的成交编号有可能重复, 因此OpenDate和TradeID需要合并作为key. 开发者可以根据此key, 来区分及储存持仓明细.

 

TIPS: 对于有条件维护保存成交数据的开发者, 建议将持仓明细的开仓时间也一并保存到持仓明细中. 因为CTP查询返回的同一天内的持仓明细无法判断开仓时间顺序(可用于确定平仓顺序, 这个以后会再讲), 引入开仓时间即可解决这一点,

 

 

  • 查询持仓

     

持仓即持仓汇总, 是持仓明细按合约, 买卖方向, 持仓日期类型等汇总而成的持仓数据. 

 

TIPS: 如果你动手能力够强, 可以自行由持仓明细合成出持仓汇总来.

 

CTP查询持仓的请求函数是 

int ReqQryInvestorPosition

(CThostFtdcQryInvestorPositionField *pQryInvestorPosition, 

int nRequestID);

查询持仓的响应函数是 

void OnRspQryInvestorPosition

(CThostFtdcInvestorPositionField *pInvestorPosition,

CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast);

 

用户可以根据交易所代码和合约代码来查询持仓. 下面是一个示例:

 
查询持仓示例

 

        和其他查询类似, 查询持仓受到查询流控的影响, 在途查询仅能有一笔, 同时有两次查询时间间隔的限制(一般为间隔1秒), 同样的, 可以不填BrokerID和Investor, 若如此做, 则为默认查询登录的此账户的持仓. 查询时, 可以不填InstrumentID或ExchangeID, 若如此做, 则为InstrumentID或ExchangeID不做限制, 即查询满足其他条件的任意合约或任意交易所的合约的持仓.

        查询持仓的响应中, 若有多条满足条件的持仓, 则分成多次返回, 最后一条的记录bIsLast值为true, 若没有满足条件的持仓, 则仅返回一条, 其bIsLast值为true, 且pInvestorPosition为空指针.

 

        持仓的数量减少到0时, 表明此笔持仓数量被全部平掉, 查询时, 当天被全平的持仓也仍会出现在响应中, 因此, 有的查询到的持仓记录的持仓数量(Position)为0. 结算后, 平仓完的持仓将被清除, 无法再查询到.

        持仓里统计的一些字段, 表示的含义是在这个持仓记录上产生的所有该字段数据的和, 比如Commission(手续费), 表示的这个买卖方向的持仓上的开仓和平仓的成交产生的手续费的和(CTP的成交记录中没有手续费, 手续费体现在成交相关的持仓中). 类似的还有CloseProfit, LongFrozen, OpenAmount等.

 

持仓的key是以下字段的组合: 

BrokerID(经纪公司代码) + InvestorID(投资者代码) + HedgeFlag(投机套保标志) + PosiDirection(持仓多空方向) + PositionDate(持仓日期类型).

 

 

目前, 上期所(SHFE)和能源中心(INE)这两个交易所区分今仓和昨仓(历史仓), 因此它们的持仓在PositionDate(持仓日期类型)上有区分. 其他交易所则不区分, PositionDate(持仓日期类型)的值无多大意义, 一般值是THOST_FTDC_PSD_Today(今仓).

 

TIPS: 判断合约是否区分今仓和昨仓, 也可以通过查询产品或合约获取信息, 查询产品或合约响应中的PositionDateType(持仓日期类型类型)字段值即表明此产品或合约是否区分今仓和昨仓.

 

举例1: 小明有rb2010(上期所合约)持仓, 其中多头今仓1手, 多头昨仓2手, 空头今仓3手, 空头昨仓4手, 则他查询rb2010的持仓, 会返回4条持仓记录, 分别对应这4条.

举例2: 小红有c2105(大商所合约)持仓, 其中多头今仓1手, 多头昨仓2手, 空头今仓3手, 空头昨仓4手, 则她查询c2105的持仓, 会返回2条持仓记录, 分别对应多头(1+2=)3手,空头(3+4=)7手.

 

部分字段的说明:

PositionProfit: (当日的)(逐日盯市)持仓盈亏. 期权没有持仓盈亏, 为0.

CloseProfit: (当日的)(逐日盯市)平仓盈亏. 例如, CF101的多头持仓4手, 平仓1手, 则这笔平仓成交产生的平仓盈亏会计入到剩下的这3手的CF101多头持仓记录中. 期权没有平仓盈亏, 为0.

Position: 表示当前持仓数量.

TodayPosition: 表示今日新开仓数量.

YdPosition: 表示昨日收盘时持仓数量(≠ 当前的昨仓数量, 静态, 日间不随着开平仓而变化)

YdStrikeFrozen: 该字段是给个股期权用的, 期货期权里一直保持为0.

OpenVolume: 当日开仓量.

CloseVolume: 当日平仓量.

OpenAmount: 当日开仓成交的成交额.

CloseAmount: 当日平仓成交的成交额.

LongFrozen: 多头冻结. 未成交的买入委托(含开仓和平仓)的未成交数量.

ShortFrozen: 空头冻结. 未成交的卖出委托(含开仓和平仓)的未成交数量.

OpenCost: 开仓成本, 等于汇总的各笔持仓明细的开仓成本的和.

PositionCost: 持仓成本, 等于汇总的各笔持仓明细的持仓成本的和. 

FrozenMargin: 冻结的保证金, 开仓未成交的委托占用的冻结的保证金.

 

CTP持仓字段中没有当前昨仓数量, 开仓均价, 持仓均价, 可用持仓(即可平持仓)数量等字段, 需要自己计算:

 

当前的昨仓数量 = Position - TodayPosition.

 

开仓均价 = OpenCost / (Position * 合约乘数).  

持仓均价 = PositionCost / (Position * 合约乘数). 

 

可用数量(对于多头持仓) = Position - ShortFrozen - CombShortFrozen.

可用数量(对于空头持仓) = Position - LongFrozen - CombLongFrozen.

 

TIPS: 开仓没有成交的委托, 如果此前没有此合约的持仓, 会产生一条持仓数量为0的持仓记录, 这条新持仓中的FrozenMargin等值有数据.

 

以上是关于CTP查询持仓和持仓明细的那些事儿的主要内容,如果未能解决你的问题,请参考以下文章

外盘持仓盈亏何时推送---ITapTradeAPINotify::OnRtnPositionProfit

SQL Server 查询以计算每日“持仓”未结订单

期货的交易量和持仓量(期货的持仓量和成交量)

清华教授教你用Python获取全部基金前十大持仓股并进行选股分析

碳交易系统逻辑功能设计

碳交易系统逻辑功能设计