Skip to content

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;
}

鲁ICP备09057662号 | 鲁公网安备 37010302000722号