Appearance
配股逻辑示例代码
目录
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;
}