Skip to content

配股逻辑示例代码

目录


1. 总体步骤说明

1.1. 继承Spi

代码通过#include "xtpx_trader_api.h",将xtpxtraderapi.lib中声明的类和数据类型包括进来,该头文件中有两个重要的基类:

TraderApi类提供交易相关的请求接口,本示例中调用查询持仓和报单接口。

TraderSpi类提供交易相关的回调接口,本示例需要继承该类并重写查询持仓数据的回调接口。

1.2. 初始化Api

在方法(initialize)里完成MyTraderApi的初始化,创建TraderSpi实例,并向TraderApi实例注册;

1.3. 登录交易服务器

登录交易服务器,登录前设置必要参数,包括设置软件开发版本号,软件开发Key,心跳检测时间间隔等,登录接口返回会话ID表示登录成功;

1.4. 调用查询持仓接口QueryPosition

查询持仓,调用api的QueryPosition方法发出查询全市场持仓的请求。 示例代码如下:

cpp
// 查询全市场持仓
void MyTraderApi::queryPosition()
{
	int request_id = 1;//用户自定义,可用来定位查询
	if (user_trade_api_) {
		int ret = user_trade_api_->QueryAllPosition(NULL, session_id_, request_id);
		if (ret != 0) {
			// 查询持仓发送失败,获取发送失败的错误码
			XTPRI *error_info = user_trade_api_->GetApiLastError();
			std::cout << " query position error, " << error_info->error_id << " : " << error_info->error_msg << std::endl;
		}
	}
}

1.5. 过滤持仓中的配股数据

根据查询结果筛出配股信息,在spi的回调函数OnQueryPosition中获取到持仓数据,根据持仓结构体中的持仓类型判断该股份是否为配售,并缓存配股数据至query_allotment_buffer_中。 示例代码如下:

cpp
// 配股缓存
std::vector<XTPQueryStkPositionRsp> query_allotment_buffer_;

void MyTraderSpi::OnQueryPosition(XTPQueryStkPositionRsp * investor_position, XTPRI *error_info, int request_id, bool is_last, uint64_t session_id)
{

	if ((error_info) && (error_info->error_id != 0)) {
		std::cout << "query position error, " << error_info->error_id << " : " << error_info->error_msg << std::endl;

		if (11000350 == error_info->error_id) {
			std::cout << "查询持仓结果无记录." << std::endl;
		}

		return;
	}
	
	if (investor_position) {
		// 配股缓存
		if (XTP_POSITION_SECURITY_PLACEMENT == investor_position->position_security_type)
			query_allotment_buffer_.push_back(*investor_position);
	}

	if (is_last) {
		/// TODO:缓存数据发送至UI线程

		// 示例代码只是spi实例通知parent去报单,方便api实例继续运行
		_f_insert_order();
		// 缓存使用后清空容器
		query_allotment_buffer_.clear();
	}
}

1.6. 报单

根据筛选出的配股信息调用InsertOrder接口报单。 示例代码如下:

cpp
//报送配股订单
void MyTraderApi::insertOrder()
{
	std::vector<XTPQueryStkPositionRsp>::iterator it;
	for (it = m_trader_spi->getAllotmentList()->begin(); it != m_trader_spi->getAllotmentList()->end(); it++)
	{

		// XTPOrderInsertInfo报单结构体初始化
		XTPOrderInsertInfo order_info;
		memset(&order_info, 0, sizeof(XTPOrderInsertInfo));
		// 参数赋值
		order_info.market = it->market;
		strcpy_s(order_info.ticker, XTP_TICKER_LEN, it->ticker);      // XTP_TICKER_LEN:存放证券代码的字符串长度
		order_info.business_type = XTP_BUSINESS_TYPE_ALLOTMENT;        // XTP_BUSINESS_TYPE_ALLOTMENT为配股业务类型
		order_info.side = XTP_SIDE_BUY;
		order_info.position_effect = XTP_POSITION_EFFECT_INIT;         // position_effect开平标志,除期权以外,都使用该值
		order_info.price_type = XTP_PRICE_LIMIT;                       // 价格类型
		order_info.quantity = it->sellable_qty;                       // 买股票的委托数量,最小数量是1股
		if (user_trade_api_ && session_id_ != 0)
		{
			// 调用InsertOrder下单接口报单
			uint64_t xtp_id = user_trade_api_->InsertOrder(&order_info, session_id_);
			if (0 == xtp_id)
			{
				// 下单发送失败,获取下单发送失败的错误信息,并输出打印
				XTPRI *error_info = user_trade_api_->GetApiLastError();
				std::cout << " insert allotment orders error, " << error_info->error_id << " : " << error_info->error_msg << std::endl;
			}
		}
	}
}

2. 完整示例代码

以下是MyTraderSpi.h文件

cpp
#include "xtpx_trader_api.h"

#include <iostream>
#include <Vector>
#include <functional>

using namespace std;
using namespace XTPX::API;

class MyTraderSpi : public TraderSpi
{
public:
	explicit MyTraderSpi();
	~MyTraderSpi();

	// 请求查询投资者持仓响应
	void OnQueryPosition(XTPQueryStkPositionRsp * investor_position, XTPRI *error_info, int request_id, bool is_last, uint64_t session_id);
	// 查询持仓请求完成通知
	void bindTraderInsertAllotOrderFunc(std::function<void(void)> f) { _f_insert_order = f; }
	// 返回配股数据
	std::vector<XTPQueryStkPositionRsp> *getAllotmentList() { return &query_allotment_buffer_; }

private:
	//缓存的配股信息
	std::vector<XTPQueryStkPositionRsp> query_allotment_buffer_;

	std::function<void(void)> _f_insert_order;
};

以下是MyTraderSpi.cpp文件

cpp
#include "MyTraderSpi.h"

MyTraderSpi::MyTraderSpi() { }
MyTraderSpi::~MyTraderSpi() { }

void MyTraderSpi::OnQueryPosition(XTPQueryStkPositionRsp * investor_position, XTPRI *error_info, int request_id, bool is_last, uint64_t session_id)
{

	if ((error_info) && (error_info->error_id != 0)) {
		std::cout << "query position error, " << error_info->error_id << " : " << error_info->error_msg << std::endl;

		if (11000350 == error_info->error_id) {
			printf("查询持仓结果无记录");
		}

		return;
	}
	
	if (investor_position) {
		// 配股缓存
		if (XTP_POSITION_SECURITY_PLACEMENT == investor_position->position_security_type)
			query_allotment_buffer_.push_back(*investor_position);
	}

	if (is_last) {
		/// TODO:缓存数据发送至UI线程

		// 示例代码只是spi实例通知parent去报单,方便api实例继续运行
		_f_insert_order();
		// 缓存使用后清空容器
		query_allotment_buffer_.clear();
	}
}

以下是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();
	// 请求查询投资者持仓
	void queryPosition();
	// 报单
	void insertOrder();

private:
	TraderApi *user_trade_api_;
	MyTraderSpi *m_trader_spi;

	uint64_t session_id_;

};

以下是MyTraderApi.cpp文件

cpp
#include "MyTraderApi.h"

MyTraderApi::MyTraderApi()
{
	user_trade_api_ = nullptr;
	m_trader_spi = nullptr;

	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);
		m_trader_spi->bindTraderInsertAllotOrderFunc(std::bind(&MyTraderApi::insertOrder, this));
		// 登录前参数设置
		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::queryPosition()
{
	int request_id = 1;//用户自定义,可用来定位查询
	if (user_trade_api_) {
		int ret = user_trade_api_->QueryAllPosition(NULL, session_id_, request_id);
		if (ret != 0) {
			// 查询持仓发送失败,获取发送失败的错误码
			XTPRI *error_info = user_trade_api_->GetApiLastError();
			std::cout << " query position error, " << error_info->error_id << " : " << error_info->error_msg << std::endl;
		}
	}
}

//报送配股订单
void MyTraderApi::insertOrder()
{
	std::vector<XTPQueryStkPositionRsp>::iterator it;
	for (it = m_trader_spi->getAllotmentList()->begin(); it != m_trader_spi->getAllotmentList()->end(); it++)
	{

		// XTPOrderInsertInfo报单结构体初始化
		XTPOrderInsertInfo order_info;
		memset(&order_info, 0, sizeof(XTPOrderInsertInfo));  //必须要先初始化为空
		// 参数赋值
		order_info.market = it->market;
		strcpy_s(order_info.ticker, XTP_TICKER_LEN, it->ticker);      // XTP_TICKER_LEN:存放证券代码的字符串长度
		order_info.business_type = XTP_BUSINESS_TYPE_ALLOTMENT;        // XTP_BUSINESS_TYPE_ALLOTMENT为配股业务类型
		order_info.side = XTP_SIDE_BUY;
		order_info.position_effect = XTP_POSITION_EFFECT_INIT;         // position_effect开平标志,除期权以外,都使用该值
		order_info.price_type = XTP_PRICE_LIMIT;                       // 价格类型
		order_info.quantity = it->sellable_qty;                       // 买股票的委托数量,最小数量是1股
		if (user_trade_api_ && session_id_ != 0)
		{
			// 调用InsertOrder下单接口报单
			uint64_t xtp_id = user_trade_api_->InsertOrder(&order_info, session_id_);
			if (0 == xtp_id)
			{
				// 下单发送失败,获取下单发送失败的错误信息,并输出打印
				XTPRI *error_info = user_trade_api_->GetApiLastError();
				std::cout << " insert allotment orders error, " << error_info->error_id << " : " << error_info->error_msg << 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 ret = pTraderApi->login();
		if (ret != 0)
		{
			// 查询持仓中的配股信息
			pTraderApi->queryPosition();
			// 报单方法在查询数据返回方法内被调用
		}
		//主线程循环,防止进程退出
		while (true)
		{
#ifdef _WIN32
			Sleep(1000);
#else
			sleep(1);
#endif
		}
	}

	return 0;
}

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