Appearance
XTP Pro交易分页查询示例代码
目录
XTP Pro XTrader API 中有很多查询函数,针对某些用户的一次性查询结果特别多的情况,提供了分页查询函数供用户使用。目前有如下几个分页查询函数:
(1)int QueryOrdersByPage(const XTPQueryOrderByPageReq *query_param, uint64_t session_id, int request_id);
(2)int QueryTradesByPage(const XTPQueryTraderByPageReq *query_param, uint64_t session_id, int request_id);
(3)int QueryFundTransferByPage(const XTPQueryFundTransferByPageReq *query_param, uint64_t session_id, int request_id);
下面将以分页查询普通报单函数为例,向大家展示如何分页查询用户的所有报单,其余分页查询函数的使用可以参考该用法进行适当修改并应用。
1. 分页请求查询所有报单
1.1. 总体步骤说明
1.1.1. 继承Spi
代码通过#include "xtpx_trader_api.h",将xtpxtraderapi.lib中声明的类和数据类型包括进来,该头文件中有两个重要的基类:和。
(1) TraderApi类提供交易相关的请求接口,本示例中调用分页查询接口。
(2) TraderSpi类提供交易相关的回调接口,本示例需要继承该类并重写分页查询信息的回调接口。
1.1.2. 初始化Api
在方法(initialize)里完成MyTraderApi的初始化,创建TraderSpi实例,并向TraderApi实例注册;
1.1.3. 登录交易服务器
登录交易服务器,登录前设置必要参数,包括设置软件开发版本号,软件开发Key,心跳检测时间间隔等,登录接口返回会话ID表示登录成功;
1.1.4. 调用分页查询接口
在调用分页查询接口之前,先调用接口GetMaxReqNumOfPagedQuery(),获取系统允许的最大分页查询数量,控制每次分页查询订单条数不超过最大分页查询数量。
初始化分页查询订单请求结构体XTPQueryOrderByPageReq,将索引参数reference置0,表示从头查询,设置需要查询的订单条数req_count后,调用QueryOrdersByPage()方法开始查询。 示例代码如下:
cpp
// 查询报单
void MyTraderApi::queryOrdersByPage(int64_t req_count, int64_t ref)
{
if (user_trade_api_)
{
// 分页查询订单请求结构体
XTPQueryOrderByPageReq query_param;
memset(&query_param, 0, sizeof(XTPQueryOrderByPageReq));
// 需要查询的订单条数
query_param.req_count = req_count;
// 上一次收到的查询订单结果中带回来的索引,如果是从头查询,请置0
query_param.reference = ref;
int request_id = 1; //用户自定义的查询ID,用来定位
// 从索引初始开始分页查询count条报单
int ret = user_trade_api_->QueryOrdersByPage(&query_param, session_id_, request_id);
if (0 != ret)
{
//查询请求发送失败,打印失败原因
XTPRI* error_info = user_trade_api_->GetApiLastError();
std::cout << "query orders by pages error, " << error_info->error_id << " : " << error_info->error_msg
<< ", req_count: " << req_count
<< ", reference: " << ref
<< std::endl;
}
}
}1.1.5. 重写分页查询回调接口
根据分页查询报单响应方法OnQueryOrderByPage()获取此页订单数据,若order_sequence为0,表明当次查询没有查到任何记录;
当is_last为true时,表示本次分页查询完成,缓存当前参数order_sequence和query_reference,或缓存收到的报单信息;
如果缓存参数order_sequence等于请求数量req_count,那么表示还有报单。将缓存的query_reference参数设为下次查询的结构体索引参数reference,再次分页查询(参考示例中queryOrdersByPage方法);
直至查询完所有报单。
示例代码如下:
cpp
// 分页查询报单数据缓存
std::vector<XTPQueryOrderRsp> query_order_page_buffer_;
void MyTraderSpi::OnQueryOrderByPage(XTPQueryOrderRsp *order_info, int64_t req_count, int64_t order_sequence, int64_t query_reference, int request_id, bool is_last, uint64_t session_id)
{
if (NULL == order_info || 0 == order_sequence) {
// 表明本次查询没有查到任何数据,可以通知其他线程
return;
}
query_order_page_buffer_.push_back(*order_info);
if (is_last) {
// 当次查询请求的最后一条回应消息
if (req_count != order_sequence)
{
// 所有订单都查询完毕
// TODO:可以将缓存通知UI线程
// 缓存发送后可以清空缓存容器
query_order_page_buffer_.clear();
return;
}
// 还有后续的订单,需要通知进行下一次分页查询
_f_query_order_by_page(req_count, query_reference);
}
}1.2. 完整示例代码
以下是MyTraderSpi.h文件
cpp
#include "xtpx_trader_api.h"
#include "xoms_x_api_struct.h"
#include <iostream>
#include <Vector>
#include <functional>
using namespace std;
using namespace XTPX::API;
typedef void(*QryOrderByPageFunc)(int req_count, int ref);
class MyTraderSpi : public TraderSpi
{
public:
explicit MyTraderSpi();
~MyTraderSpi();
// 分页请求查询报单响应
void OnQueryOrderByPage(XTPQueryOrderRsp *order_info, int64_t req_count, int64_t order_sequence, int64_t query_reference, int request_id, bool is_last, uint64_t session_id)
// 单次分页请求完成通知
void bindTraderFunc(std::function<void(int64_t, int64_t)> f) { _f_query_order_by_page = f; }
private:
// 分页查询得到的报单数据缓存
std::vector<XTPQueryOrderRsp> query_order_page_buffer_;
std::function<void(int64_t, int64_t)> _f_query_order_by_page;
};以下是MyTraderSpi.cpp文件
cpp
#include "MyTraderSpi.h"
MyTraderSpi::MyTraderSpi()
{
}
MyTraderSpi::~MyTraderSpi() { }
void MyTraderSpi::OnQueryOrderByPage(XTPQueryOrderRsp *order_info, int64_t req_count, int64_t order_sequence, int64_t query_reference, int request_id, bool is_last, uint64_t session_id)
{
if (NULL == order_info || 0 == order_sequence) {
// 表明本次查询没有查到任何数据,可以通知其他线程
return;
}
query_order_page_buffer_.push_back(*order_info);
if (is_last) {
// 当次查询请求的最后一条回应消息
if (req_count != order_sequence)
{
// 所有订单都查询完毕
// TODO:可以将缓存通知UI线程或者其他作用
// 订单缓存使用后可以清空缓存容器(也可选择在下一次查询开始的时候清空)
query_order_page_buffer_.clear();
return;
}
// 还有后续的订单,需要通知进行下一次分页查询
_f_query_order_by_page(req_count, query_reference);
}
}以下是MyTraderApi.h文件
cpp
#include "xtpx_trader_api.h"
#include "MyTraderSpi.h"
using namespace XTPX::API;
class MyTraderApi
{
public:
explicit MyTraderApi();
~MyTraderApi();
// 初始化
bool initialize();
// 释放
void release();
// 登录
uint64_t login();
// 分页请求查询报单
// req_count - 一次分页查询的最大数量
// ref - 分页查询的起始参数
void queryOrdersByPage(int64_t req_count, int64_t ref);
private:
TraderApi *user_trade_api_;
MyTraderSpi *m_trader_spi;
uint64_t session_id_;
};以下是MyTraderApi.cpp文件
cpp
#include "MyTraderApi.h"
MyTraderApi::MyTraderApi()
{
user_trade_api_ = NULL;
m_trader_spi = NULL;
session_id_ = 0;
}
MyTraderApi::~MyTraderApi()
{
if (user_trade_api_ != NULL) {
user_trade_api_->Logout(session_id_);
user_trade_api_->Release();
}
}
bool MyTraderApi::initialize()
{
// 创建并初始化交易API
user_trade_api_ = XTPX::API::TraderApi::CreateTraderApi(1, "./", XTP_LOG_LEVEL_DEBUG);
if (user_trade_api_)
{
// 注册回调接口
m_trader_spi = new MyTraderSpi();
user_trade_api_->RegisterSpi(m_trader_spi);
// 在spi实例化后绑定再次分页查询函数指针
m_trader_spi->bindTraderFunc(std::bind(&MyTraderApi::queryOrdersByPage, this, std::placeholders::_1, std::placeholders::_2));
// 登录前参数设置
user_trade_api_->SetHeartBeatInterval(15);
user_trade_api_->SetSoftwareKey("xxxxxxxxxx");
user_trade_api_->SetSoftwareVersion("xx.xx.xx.xx");
// 设置公有流(订单响应、成交回报)重传方式
user_trade_api_->SubscribePublicTopic(XTP_TERT_QUICK);
return true;
}
return false;
}
// 释放
void MyTraderApi::release()
{
if (user_trade_api_ != NULL) {
user_trade_api_->Logout(session_id_);
}
}
// 登录
uint64_t MyTraderApi::login()
{
//以下参数需要用户去根据实际情况修改
std::string trade_server_ip = "xxx.xxx.xxx.xxx";
int trade_server_port = xx;
std::string account_name = "xxxxxxxx";
std::string account_pw = "xxxxxx";
uint64_t ret = user_trade_api_->Login(trade_server_ip.c_str(), trade_server_port, account_name.c_str(), account_pw.c_str(), XTP_PROTOCOL_TCP);
if (ret != 0) // 登录成功
{
session_id_ = ret;
}
else // 登录失败
{
XTPRI* error_info = user_trade_api_->GetApiLastError();
std::cout << "login to server error, " << error_info->error_id << " : " << error_info->error_msg << std::endl;
}
return ret;
}
// 查询报单
void MyTraderApi::queryOrdersByPage(int64_t req_count, int64_t ref)
{
if (user_trade_api_)
{
// 分页查询订单请求结构体
XTPQueryOrderByPageReq query_param;
memset(&query_param, 0, sizeof(XTPQueryOrderByPageReq));
// 需要查询的订单条数
query_param.req_count = req_count;
// 上一次收到的查询订单结果中带回来的索引,如果是从头查询,请置0
query_param.reference = ref;
int request_id = 1; //用户自定义的查询ID,用来定位
// 从索引初始开始分页查询count条报单
int ret = user_trade_api_->QueryOrdersByPage(&query_param, session_id_, request_id);
if (0 != ret)
{
//查询请求发送失败,打印失败原因
XTPRI* error_info = user_trade_api_->GetApiLastError();
std::cout << "query orders by pages error, " << error_info->error_id << " : " << error_info->error_msg
<< ", req_count: " << req_count
<< ", reference: " << ref
<< std::endl;
}
}
}以下是main.cpp文件
cpp
#include <iostream>
#include "MyTraderApi.h"
#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif
using namespace std;
int main(int argc, char *argv[])
{
MyTraderApi *pTraderApi = new MyTraderApi();
if (pTraderApi)
{
bool b_ret = pTraderApi->initialize();
if (! b_ret)
{
// 初始化失败程序退出
return -1;
}
uint64_t session_id = pTraderApi->login();
if (session_id != 0)
{
//获取系统允许的最大分页查询数量
int64_t maxReq = pTraderApi->GetMaxReqNumOfPagedQuery(session_id);
// 示例代码只做分页查询所有报单,并未展示查询到的报单数据
// 发起第一次分页查询,后续的查询将根据查询结果触发
pTraderApi->queryOrdersByPage(maxReq, 0);
}
//主线程循环,防止进程退出
while (true)
{
#ifdef _WIN32
Sleep(1000);
#else
sleep(1);
#endif
}
}
return 0;
}