Appearance
XTP Pro关于L2行情数据回补功能的使用说明
目录
1. 回补功能的函数
1.1. QuoteAPI回补请求接口
cpp
///请求回补指定行情,包括快照和逐笔
///@return 请求回补指定频道的逐笔行情接口调用是否成功,“0”表示接口调用成功,非“0”表示接口调用出错
///@param rebuild_param 指定回补的参数信息,注意一次性回补最多1000个数据,超过1000需要分批次请求,一次只能指定一种类型的数据
///@remark 仅在逐笔行情丢包时或者确实快照行情时使用,回补的行情数据将从OnRebuildTickByTick或者OnRebuildMarketData()接口回调提供,与订阅的行情数据不在同一个线程内
virtual int RequestRebuildQuote(XTPQuoteRebuildReq* rebuild_param) = 0;1.2. QuoteSpi回调函数
cpp
///请求回补指定行情的总体结果应答
///@param rebuild_result 当回补结束时被调用,如果回补结果失败,则msg参数表示失败原因
///@remark 需要快速返回,仅在回补数据发送结束后调用,如果请求数据太多,一次性无法回补完,那么rebuild_result.result_code = XTP_REBUILD_RET_PARTLY,此时需要根据回补结果继续发起回补数据请求
virtual void OnRequestRebuildQuote(XTPQuoteRebuildResultRsp* rebuild_result) {};
///回补的逐笔行情数据
///@param tbt_data 回补的逐笔行情数据
///@remark 需要快速返回,此函数调用与OnTickByTick不在一个线程内,会在OnRequestRebuildQuote()之前回调
virtual void OnRebuildTickByTick(XTPTBT *tbt_data) {};
///回补的快照行情数据
///@param md_data 回补的逐笔行情数据
///@remark 需要快速返回,此函数调用与OnDepthMarketData不在一个线程内,会在OnRequestRebuildQuote()之前回调
virtual void OnRebuildMarketData(XTPMD *md_data) {};2. 接口说明及使用示例
2.1. RequestRebuildQuote
请求回补指定行情,包括快照和逐笔。
◇ 1.函数原型
cpp
virtual int RequestRebuildQuote(XTPQuoteRebuildReq* rebuild_param) = 0;◇ 2.参数
rebuild_param: 指定的需要回补数据的参数信息。
cpp
///实时行情回补请求结构体
typedef struct XTPQuoteRebuildReq
{
///请求id 请求端自行管理定义
int32_t request_id;
///请求数据类型 1-快照 2-逐笔 3-指定股票逐笔
XTP_QUOTE_REBUILD_DATA_TYPE data_type;
///请求市场 1-上海 2-深圳
XTP_EXCHANGE_TYPE exchange_id;
///data_type=逐笔或者指定股票逐笔时,表示逐笔通道号
int16_t channel_number;
///预留
char unuse[2];
///合约代码 以'\0'结尾 沪深A股6位 期权8位,当data_type=为快照或者指定股票逐笔时使用
char ticker[16];
///data_type=逐笔或者指定股票逐笔时 表示序列号begin; =快照 表示时间begin(格式为YYYYMMDDHHMMSSsss)
int64_t begin;
///data_type=逐笔或者指定股票逐笔时 表示序列号end; =快照 表示时间end(格式为YYYYMMDDHHMMSSsss) 逐笔区间:[begin, end]前后闭区间 快照区间:[begin, end) 前闭后开区间
int64_t end;
}XTPQuoteRebuildReq;◇ 3.返回
请求回补指定频道的逐笔行情接口调用是否成功,“0”表示接口调用成功,非“0”表示接口调用出错。
◇ 4.调用示例
(1) 请求回补快照数据
下面以请求回补沪市600000快照数据为例:
cpp
//请求回补沪市600000快照数据
if (user_quote_api_)
{
//回补请求参数赋值
XTPQuoteRebuildReq req;
memset(&req, 0, sizeof(XTPQuoteRebuildReq));
req.request_id = 1;//用户自定义,用来标识此次查询请求
req.data_type = XTP_QUOTE_REBUILD_MD;//回补数据类型
req.exchange_id = XTP_EXCHANGE_SH;//交易所类型,用户根据实际情况修改
std::string reqticker = "600000";//请求回补的股票代码,此处以600000为例
strcpy_s(req.ticker, XTP_QUOTE_TICKER_LEN, reqticker.c_str());
req.channel_number = 0;//仅逐笔订阅时生效,对于快照可不赋值
req.begin = YYYYMMDDHHMMSSsss;//快照开始时间,闭区间,用户根据实际情况修改
req.end = YYYYMMDDHHMMSSsss;//快照结束时间,开区间,用户根据实际情况修改
// 发送请求
int ret = user_quote_api_->RequestRebuildQuote(&req);
}(2) 请求指定频道号的回补逐笔数据
下面以请求回补沪市频道号为2011,逐笔序列号在[20,78]区间内的逐笔数据为例:
cpp
//请求回补沪市频道号为2011,逐笔序列号在[20,78]区间内的逐笔数据
if (user_quote_api_)
{
//回补请求参数赋值
XTPQuoteRebuildReq req;
memset(&req, 0, sizeof(XTPQuoteRebuildReq));
req.request_id = 1;//用户自定义,用来标识此次查询请求
req.data_type = XTP_QUOTE_REBUILD_TBT;//回补数据类型
req.exchange_id = XTP_EXCHANGE_SH;//交易所类型,用户根据实际情况修改
req.channel_number = 2011;//仅逐笔订阅时生效,对于快照可不赋值,用户根据实际情况修改
req.begin = 20;//逐笔开始的序列号,闭区间,用户根据实际情况修改
req.end = 78;//逐笔结束的序列号,闭区间,用户根据实际情况修改
// 发送请求
int ret = user_quote_api_->RequestRebuildQuote(&req);
}(3) 请求指定合约的回补逐笔数据
下面是从头开始请求回补股票000001.sz的逐笔行情代码示例:
cpp
if(user_quote_api)
{
//回补指定股票的逐笔行情
XTPX::API::XTPQuoteRebuildReq req;
memset(&req, 0, sizeof(XTPX::API::XTPQuoteRebuildReq));
req.request_id = 1;
req.exchange_id = XTPX::API::XTP_EXCHANGE_SZ;
strcpy(req.ticker, "000001");
req.data_type = XTPX::API::XTP_QUOTE_REBUILD_TICKER_TBT;
req.channel_number = 0;//第一次从头开始查可以填0,后面再次查询的时候,需要根据查询结果填入正常的channel_number
req.begin = 0;//第一次不知道seq区间,可填0
req.end = 1000000;//第一次不知道seq区间,可随意填一个超大值
int ret = user_quote_api->RequestRebuildQuote(&req);
}◇ 5.响应函数
cpp
virtual void OnRequestRebuildQuote(XTPQuoteRebuildResultRsp* rebuild_result);◇ 6.通知函数
cpp
virtual void OnRebuildTickByTick(XTPTBT *tbt_data);
virtual void OnRebuildMarketData(XTPMD *md_data);2.2. OnRequestRebuildQuote
请求回补指定行情的总体结果应答。
仅在回补数据发送结束后调用。 由于行情回补服务器对于每次请求的数据有数量上限限制,因此如果一次性请求数据太多,会导致行情数据无法一次性回补完,那么此时收到的应答消息中 ,用户需要根据回补结果继续发起回补数据请求。
◇ 1.函数原型
cpp
virtual void OnRequestRebuildQuote(XTPQuoteRebuildResultRsp* rebuild_result);◇ 2.参数
rebuild_result: 当回补结束时被调用,如果回补结果失败,则msg参数表示失败原因
cpp
///实时行情回补响应结构体
typedef struct XTPQuoteRebuildResultRsp
{
///请求id 请求包带过来的id
int32_t request_id;
///市场类型 上海 深圳
XTP_EXCHANGE_TYPE exchange_id;
///总共返回的数据条数
uint32_t size;
///逐笔数据 通道号
int16_t channel_number;
///逐笔 表示序列号begin; 快照 表示时间begin(格式为YYYYMMDDHHMMSSsss)
int64_t begin;
///逐笔 表示序列号end; 快照 表示时间end(格式为YYYYMMDDHHMMSSsss)
int64_t end;
///结果类型码
XTP_REBUILD_RET_TYPE result_code;
///结果信息文本
char msg[64];
}XTPQuoteRebuildResultRsp;
///@brief XTP_EXCHANGE_TYPE是交易所类型
////////////////////////////////////////////////////////////////////////
typedef uint32_t XTP_EXCHANGE_TYPE;
///<上证
constexpr uint32_t XTP_EXCHANGE_SH = 1;
///<深证
constexpr uint32_t XTP_EXCHANGE_SZ = 2;
///<新三板,全国中小企业股份转让系统
constexpr uint32_t XTP_EXCHANGE_NQ = 3;
///<港交所
constexpr uint32_t XTP_EXCHANGE_HK = 4;
///<不存在的交易所类型
constexpr uint32_t XTP_EXCHANGE_UNKNOWN = 5;
///@brief XTP_REBUILD_RET_TYPE 实时行情回补返回结果类型
/////////////////////////////////////////////////////////////////////////
typedef uint32_t XTP_REBUILD_RET_TYPE;
///<全部数据
constexpr uint32_t XTP_REBUILD_RET_COMPLETE = 1;
///<部分数据
constexpr uint32_t XTP_REBUILD_RET_PARTLY = 2;
///<没有数据
constexpr uint32_t XTP_REBUILD_RET_NO_DATA = 3;
///<参数错误
constexpr uint32_t XTP_REBUILD_RET_PARAM_ERR = 4;
///<请求频繁
constexpr uint32_t XTP_REBUILD_RET_FREQUENTLY = 5;◇ 3.返回
无
◇ 4.触发函数
cpp
virtual int RequestRebuildQuote(XTPQuoteRebuildReq* rebuild_param) = 0;◇ 5.示例代码
cpp
void MyQuoteSpi::OnRequestRebuildQuote(XTPQuoteRebuildResultRsp * rebuild_result)
{
//请求的回补数据是否已经完全回补完,如果没有完全的话,可以再次发起请求
switch (rebuild_result->result_code)
{
case XTP_REBUILD_RET_COMPLETE:
{
//此时回补数据完全
}
break;
case XTP_REBUILD_RET_PARTLY:
{
//TODO:此时回补数据不完整,需要再次发起请求
}
break;
case XTP_REBUILD_RET_NO_DATA:
{
//TODO:此时服务器也没有回补数据,此时可能服务器也缺少数据,需要等待一会儿再请求看看
}
break;
case XTP_REBUILD_RET_PARAM_ERR:
{
//TODO:此时请求的回补数据查询参数错误,需要检查查询参数是否正确,并重新发起查询
}
break;
case XTP_REBUILD_RET_FREQUENTLY:
{
//TODO:此时回补数据请求因为请求太频繁,而被服务器限频,请降低请求频率或者等待一会儿再请求
}
break;
default:
break;
}
}2.3. OnRebuildTickByTick
回补的逐笔行情数据通知。
◇ 1.函数原型
cpp
virtual void OnRebuildTickByTick(XTPTBT *tbt_data);◇ 2.参数
tbt_data: 回补的逐笔行情数据
cpp
///逐笔委托
struct XTPTickByTickEntrust {
///频道代码
int32_t channel_no;
///SH: 'B':买; 'S':卖
///SZ: '1':买; '2':卖; 'G':借入; 'F':出借
char side;
///SH: 'A': 增加; 'D': 删除
///SZ: 订单类别: '1': 市价; '2': 限价; 'U': 本方最优
char ord_type;
///预留
char unused[2];
///SH: 委托序号(委托单独编号, 同一channel_no内连续)
///SZ: 委托序号(委托成交统一编号, 同一channel_no内连续)
int64_t seq;
///委托价格
double price;
///SH: 剩余委托数量(balance)
///SZ: 委托数量
int64_t qty;
///SH: 原始订单号
///SZ: 无意义
int64_t order_no;
};
///逐笔成交
struct XTPTickByTickTrade {
///频道代码
int32_t channel_no;
/// SH: 内外盘标识('B':主动买; 'S':主动卖; 'N':未知)
/// SZ: 成交标识('4':撤; 'F':成交)
char trade_flag;
///预留
char unused[3];
///SH: 成交序号(委托单独编号, 同一channel_no内连续)
///SZ: 成交序号(委托成交统一编号, 同一channel_no内连续)
int64_t seq;
///成交价格
double price;
///成交量
int64_t qty;
///成交金额(仅适用上交所)
double money;
///买方订单号
int64_t bid_no;
///卖方订单号
int64_t ask_no;
};
///逐笔状态订单
struct XTPTickByTickStatus {
///频道代码
int32_t channel_no;
///预留1
int32_t unused1;
///同一channel_no内连续
int64_t seq;
///状态信息
char flag[8];
};
///逐笔数据信息
typedef struct XTPTickByTickStruct {
///合约代码(不包含交易所信息),不带空格,以'\0'结尾
char ticker[XTP_QUOTE_TICKER_LEN];
///交易所代码
XTP_EXCHANGE_TYPE exchange_id;
///委托 or 成交
XTP_TBT_TYPE type;
/// SH: 业务序号(委托成交统一编号,同一个channel_no内连续)
/// SZ: 无意义
int64_t seq;
///委托时间 or 成交时间
int64_t data_time;
union {
XTPTickByTickEntrust entrust;
XTPTickByTickTrade trade;
XTPTickByTickStatus state;
};
} XTPTBT;
///@brief XTP_EXCHANGE_TYPE是交易所类型
////////////////////////////////////////////////////////////////////////
typedef uint32_t XTP_EXCHANGE_TYPE;
///<上证
constexpr uint32_t XTP_EXCHANGE_SH = 1;
///<深证
constexpr uint32_t XTP_EXCHANGE_SZ = 2;
///<新三板,全国中小企业股份转让系统
constexpr uint32_t XTP_EXCHANGE_NQ = 3;
///<港交所
constexpr uint32_t XTP_EXCHANGE_HK = 4;
///<不存在的交易所类型
constexpr uint32_t XTP_EXCHANGE_UNKNOWN = 5;
///@brief XTP_TBT_TYPE是一个逐笔回报类型
/////////////////////////////////////////////////////////////////////////
typedef uint32_t XTP_TBT_TYPE;
///<逐笔委托
constexpr uint32_t XTP_TBT_ENTRUST = 1;
///<逐笔成交
constexpr uint32_t XTP_TBT_TRADE = 2;
///<逐笔状态订单
constexpr uint32_t XTP_TBT_STATE = 3;◇ 3.返回
无
◇ 4.请求函数
cpp
virtual int RequestRebuildQuote(XTPQuoteRebuildReq* rebuild_param) = 0;2.4. OnRebuildMarketData
回补的逐笔行情数据通知。
◇ 1.函数原型
cpp
virtual void OnRebuildMarketData(XTPMD *md_data);◇ 2.参数
md_data: 回补的快照行情数据
cpp
///股票、基金 等额外数据
struct XTPMarketDataStockExData {
///委托买入总量(SH,SZ)
int64_t total_bid_qty;
///委托卖出总量(SH,SZ)
int64_t total_ask_qty;
///加权平均委买价格(SH,SZ)
double ma_bid_price;
///加权平均委卖价格(SH,SZ)
double ma_ask_price;
///债券加权平均委买价格(SH)
double ma_bond_bid_price;
///债券加权平均委卖价格(SH)
double ma_bond_ask_price;
///债券到期收益率(SH)
double yield_to_maturity;
///基金实时参考净值(SH,SZ)
double iopv;
///ETF申购笔数(SH)
int32_t etf_buy_count;
///ETF赎回笔数(SH)
int32_t etf_sell_count;
///ETF申购数量(SH)
double etf_buy_qty;
///ETF申购金额(SH)
double etf_buy_money;
///ETF赎回数量(SH)
double etf_sell_qty;
///ETF赎回金额(SH)
double etf_sell_money;
///权证执行的总数量(SH)
double total_warrant_exec_qty;
///权证跌停价格(元)(SH)
double warrant_lower_price;
///权证涨停价格(元)(SH)
double warrant_upper_price;
///买入撤单笔数(SH)
int32_t cancel_buy_count;
///卖出撤单笔数(SH)
int32_t cancel_sell_count;
///买入撤单数量(SH)
double cancel_buy_qty;
///卖出撤单数量(SH)
double cancel_sell_qty;
///买入撤单金额(SH)
double cancel_buy_money;
///卖出撤单金额(SH)
double cancel_sell_money;
///买入总笔数(SH)
int64_t total_buy_count;
///卖出总笔数(SH)
int64_t total_sell_count;
///买入委托成交最大等待时间(SH)
int32_t duration_after_buy;
///卖出委托成交最大等待时间(SH)
int32_t duration_after_sell;
///买方委托价位数(SH)
int32_t num_bid_orders;
///卖方委托价位数(SH)
int32_t num_ask_orders;
///基金T-1日净值(SZ)
double pre_iopv;
///预留
int64_t r1;
///预留
int64_t r2;
};
///债券额外数据
struct XTPMarketDataBondExData {
///委托买入总量(SH,SZ)
int64_t total_bid_qty;
///委托卖出总量(SH,SZ)
int64_t total_ask_qty;
///加权平均委买价格(SZ)
double ma_bid_price;
///加权平均委卖价格(SZ)
double ma_ask_price;
///债券加权平均委买价格(SH)
double ma_bond_bid_price;
///债券加权平均委卖价格(SH)
double ma_bond_ask_price;
///债券到期收益率(SH)
double yield_to_maturity;
///匹配成交最近价(SZ)
double match_lastpx;
///债券加权平均价格(SH)
double ma_bond_price;
///匹配成交成交量(SZ)
int64_t match_qty;
///匹配成交成交金额(SZ)
double match_turnover;
///预留
double r4;
///预留
double r5;
///预留
double r6;
///预留
double r7;
///预留
double r8;
///买入撤单笔数(SH)
int32_t cancel_buy_count;
///卖出撤单笔数(SH)
int32_t cancel_sell_count;
///买入撤单数量(SH)
double cancel_buy_qty;
///卖出撤单数量(SH)
double cancel_sell_qty;
///买入撤单金额(SH)
double cancel_buy_money;
///卖出撤单金额(SH)
double cancel_sell_money;
///买入总笔数(SH)
int64_t total_buy_count;
///卖出总笔数(SH)
int64_t total_sell_count;
///买入委托成交最大等待时间(SH)
int32_t duration_after_buy;
///卖出委托成交最大等待时间(SH)
int32_t duration_after_sell;
///买方委托价位数(SH)
int32_t num_bid_orders;
///卖方委托价位数(SH)
int32_t num_ask_orders;
///时段(SHL2)
char instrument_status[8];
};
// 期权额外数据
struct XTPMarketDataOptionExData {
///波段性中断参考价(SH)
double auction_price;
///波段性中断集合竞价虚拟匹配量(SH)
int64_t auction_qty;
///最近询价时间(SH)
int64_t last_enquiry_time;
};
///@brief XTP_MARKETDATA_TYPE_V2是快照数据中的Union类型
//////////////////////////////////////////////////////////////////////////
typedef uint32_t XTP_MARKETDATA_TYPE_V2;
// 指数
constexpr uint32_t XTP_MARKETDATA_V2_INDEX = 0;
// 期权
constexpr uint32_t XTP_MARKETDATA_V2_OPTION = 1;
// 现货(股票/基金等)
constexpr uint32_t XTP_MARKETDATA_V2_ACTUAL = 2;
// 债券
constexpr uint32_t XTP_MARKETDATA_V2_BOND = 3;
///行情
typedef struct XTPMarketDataStruct
{
// 代码
///合约代码(不包含交易所信息),不带空格,以'\0'结尾
char ticker[XTP_QUOTE_TICKER_LEN];
///交易所代码
XTP_EXCHANGE_TYPE exchange_id;
/// 决定了union是哪种数据类型
XTP_MARKETDATA_TYPE_V2 data_type_v2;
// 价格
///最新价
double last_price;
///昨收盘
double pre_close_price;
///今开盘
double open_price;
///最高价
double high_price;
///最低价
double low_price;
///今收盘
double close_price;
// 期权数据
///昨日持仓量(张)(目前未填写)
int64_t pre_total_long_positon;
///持仓量(张)
int64_t total_long_positon;
///昨日结算价
double pre_settl_price;
///今日结算价
double settl_price;
// 涨跌停
///SH:上交所涨跌停价赋值为0
///涨停价
double upper_limit_price;
///跌停价
double lower_limit_price;
///预留
double pre_delta;
///预留
double curr_delta;
/// 时间类,格式为YYYYMMDDHHMMSSsss
int64_t data_time;
// 量额数据
///数量,为总成交量(单位股,与交易所一致)
int64_t qty;
///成交金额,为总成交金额(单位元,与交易所一致)
double turnover;
///预留(无意义)
double avg_price;
// 买卖盘
///十档申买价
double bid[10];
///十档申卖价
double ask[10];
///十档申买量
int64_t bid_qty[10];
///十档申卖量
int64_t ask_qty[10];
// 额外数据
///成交笔数
int64_t trades_count;
///当前交易状态说明,参见官网常见问题说明
char ticker_status[8];
///数据
union {
XTPMarketDataStockExData stk;
XTPMarketDataOptionExData opt;
XTPMarketDataBondExData bond;
};
int64_t r1; // 预留字段,Rebuild查询md时为首次更新时间
} XTPMD;◇ 3.返回
无
◇ 4.请求函数
cpp
virtual int RequestRebuildQuote(XTPQuoteRebuildReq* rebuild_param) = 0;3. 行情回补数据逻辑
当用户在UDP连接下订阅行情发现行情丢包时,可以将丢失的数据补回。具体逻辑如下:
- (1)调用请求回补数据。
- (2)回补数据通过或者回调给用户。
- (3)回补结果通过通知结果。
- (4)当回补结果失败,且时,再次发起回补数据请求。
4. 注意事项
- 请仅在UDP连接下发生行情丢包时进行回补。
- 一次请求不要请求太多数据,行情回补有请求数据上限。
