Appearance
XTP Pro资金划拨接口的示例代码
目录
XTP Pro版本的资金划拨是在资金划拨服务里完成操作的,用户发出资金划拨请求之前,需确保当前资金划拨服务是可用状态。 下面实例代码从Login开始,到收到资金划拨服务的通知OnServerStatusNotification(),再做资金划拨,以及资金划拨各种情况下的参数设置示例。
1. 登录后立即操作资金划拨的示例
1.1. 继承Spi
代码通过#include "xtpx_trader_api.h",将xtpxtraderapi.lib中声明的类和数据类型包括进来,该头文件中有两个重要的基类:和。
TraderApi类提供交易相关的请求接口,本示例中调用登录接口和资金划拨接口。
TraderSpi类提供交易相关的回调接口,本示例需要继承该类并重写OnServerStatusNotification()回调接口和OnFundTransfer()回调接口。
1.2. 初始化Api
在主函数main()里完成MyTraderApi的初始化,创建TraderSpi实例,并向TraderApi实例注册;
1.3. 登录交易服务器
登录交易服务器,登录前设置必要参数,包括设置软件开发版本号,软件开发Key,心跳检测时间间隔等,登录接口返回会话ID表示登录成功;
1.4. 监测资金划拨服务是否可用
登录交易服务器后,api端内部会自动连接资金划拨服务,如果连接成功,会收到服务状态变化的通知。示例如下:
cpp
void MyTraderSpi::OnServerStatusNotification(uint64_t session_id, uint32_t server_type, bool status)
{
if (1 == server_type && status)//server_type:1表示资金划拨服务,2表示查询服务
{
requestFundTransfer(pUserApi, session_id);//资金划拨服务可用时,发起资金划拨请求
}
}注意:
1.5. 调用资金划拨接口FundTransfer
登录交易服务器后,并收到OnServerStatusNotification()的资金划拨服务可用状态后,就可以用api调用资金划拨请求接口。
各种资金划拨参数设置示例代码:
1.5.1. 从XTP转出到柜台
cpp
/**XTPX::API::TraderApi* pUserApi ;//交易api的创建示例在此忽略
uint64_t session_id_ ;//登录成功后得到的会话
*/
void MyTraderSpi::requestFundTransfer(XTPX::API::TraderApi* pUserApi, uint64_t session_id_)
{
XTPFundTransferReq fund_transfer;
memset(&fund_transfer, 0, sizeof(XTPFundTransferReq));
std::string stdstr_fund_account = "xxxxxxxxxxxxx";// 用户资金账户
strcpy_s(fund_transfer.fund_account, XTP_ACCOUNT_NAME_LEN, stdstr_fund_account.c_str());// 用户资金账户的字符串长度
fund_transfer.amount = 1000.0;//划转金额
fund_transfer.transfer_type = XTP_FUND_TRANSFER_OUT;//从XTP转出到柜台
uint64_t xtp_serial_id = pUserApi->FundTransfer(&fund_transfer, session_id_);//调用资金划转的接口,资金从XTP转出到主柜台
if (xtp_serial_id == 0)
{
//TODO:表示发送失败,可以使用GetApiLastError()获取失败原因
}
else
{
//TODO:资金划拨请求发送成功,可以记录下资金划拨订单号xtp_serial_id,以备使用
}
}1.5.2. 从柜台转入到XTP
cpp
/**XTPX::API::TraderApi* pUserApi ;//交易api的创建示例在此忽略
uint64_t session_id_ ;//登录成功后得到的会话
*/
void MyTraderSpi::requestFundTransfer(XTPX::API::TraderApi* pUserApi, uint64_t session_id_)
{
XTPFundTransferReq fund_transfer;
memset(&fund_transfer, 0, sizeof(XTPFundTransferReq));
std::string stdstr_fund_account = "xxxxxxxxxxxxx";// 用户资金账户
strcpy_s(fund_transfer.fund_account, XTP_ACCOUNT_NAME_LEN, stdstr_fund_account.c_str());// 用户资金账户的字符串长度
fund_transfer.amount = 1000.0;//划转金额
fund_transfer.transfer_type = XTP_FUND_TRANSFER_IN;// 从柜台转入到XTP
uint64_t xtp_serial_id = pUserApi->FundTransfer(&fund_transfer, session_id_);// 调用资金划转的接口,资金从主柜台转入到XTP柜台
if (xtp_serial_id == 0)
{
//TODO:表示发送失败,可以使用GetApiLastError()获取失败原因
}
else
{
//TODO:资金划拨请求发送成功,可以记录下资金划拨订单号xtp_serial_id,以备使用
}
}1.5.3. 跨节点转出
cpp
/**XTPX::API::TraderApi* pUserApi ;//交易api的创建示例在此忽略
uint64_t session_id_ ;//登录成功后得到的会话
*/
//假设从本节点转出到上海节点
void MyTraderSpi::requestFundTransfer(XTPX::API::TraderApi* pUserApi, uint64_t session_id_)
{
XTPFundTransferReq fund_transfer;
memset(&fund_transfer, 0, sizeof(XTPFundTransferReq));
std::string stdstr_fund_account = "xxxxxxxxxxxxx";// 用户资金账户
strcpy_s(fund_transfer.fund_account, XTP_ACCOUNT_NAME_LEN, stdstr_fund_account.c_str());// 用户资金账户的字符串长度
fund_transfer.amount = 1000.0;//划转金额,请先确认本节点的可用资金
fund_transfer.transfer_type = XTP_FUND_INTER_TRANSFER_OUT;// 跨节点转出 从本XTP节点1,转出到对端XTP节点2,XTP服务器之间划拨,只能是开通“一账号两中心”用户使用
fund_transfer.site = XTP_TRANSFER_SITE_SH;//目标节点是上海
uint64_t xtp_serial_id = pUserApi->FundTransfer(&fund_transfer, session_id_);// 调用资金划转的接口,资金从本服务器节点转出到双中心另一个节点
if (xtp_serial_id == 0)
{
//TODO:表示发送失败,可以使用GetApiLastError()获取失败原因
}
else
{
//TODO:资金划拨请求发送成功,可以记录下资金划拨订单号xtp_serial_id,以备使用
}
}1.5.4. 跨节点转入
cpp
/**XTPX::API::TraderApi* pUserApi ;//交易api的创建示例在此忽略
uint64_t session_id_ ;//登录成功后得到的会话
*/
//假设从深圳节点转入到本节点
void MyTraderSpi::requestFundTransfer(XTPX::API::TraderApi* pUserApi, uint64_t session_id_)
{
XTPFundTransferReq fund_transfer;
memset(&fund_transfer, 0, sizeof(XTPFundTransferReq));
std::string stdstr_fund_account = "xxxxxxxxxxxxx";// 用户资金账户
strcpy_s(fund_transfer.fund_account, XTP_ACCOUNT_NAME_LEN, stdstr_fund_account.c_str());// 用户资金账户的字符串长度
fund_transfer.amount = 1000.0;//划转金额(最好先通过QueryOtherServerFund()查询对方节点的可用资金)
fund_transfer.transfer_type = XTP_FUND_INTER_TRANSFER_IN;// 跨节点转入 从对端XTP节点2,转入到本XTP节点1,XTP服务器之间划拨,只能是开通“一账号两中心”用户使用
fund_transfer.site = XTP_TRANSFER_SITE_SZ;
uint64_t xtp_serial_id = pUserApi->FundTransfer(&fund_transfer, session_id_);// 调用资金划转的接口,资金从双中心另一个节点转入到本服务器节点
if (xtp_serial_id == 0)
{
//TODO:表示发送失败,可以使用GetApiLastError()获取失败原因
}
else
{
//TODO:资金划拨请求发送成功,可以记录下资金划拨订单号xtp_serial_id,以备使用
}
}1.6. 重写资金划转的回调函数逻辑
资金划拨成功后,划拨结果通过回调函数OnFundTransfer()返回,用户根据自己的策略重写该回调函数。
cpp
void MyTraderSpi::OnFundTransfer(XTPFundTransferNotice *fund_transfer_info, XTPRI *error_info, uint64_t session_id)
{
string message;
if (error_info != NULL && error_info->error_id != 0)
{
//划转失败
message = string(" fund transfer is failed:") + to_string(error_info->error_id) + ": " + error_info->error_msg + "\n";
}
else
{
//TODO:可以根据GetClientIDByXTPID() == client_id来过滤自己的订单
uint8_t temp_client_id = pUserApi->GetClientIDByXTPID(fund_transfer_info->serial_id);
if (temp_client_id == client_id)//注意client_id为本程序中创建TraderApi时传入的client_id,用户需要自己定义修改
{
//TODO:此资金划拨订单由本程序发起的
}
else
{
//TODO:此资金划拨订单非本程序发起
}
//根据资金划拨订单的状态来处理自己的资金逻辑
switch(fund_transfer_info->oper_status)
{
case XTP_FUND_OPER_SUCCESS:
{
//TODO:根据资金划拨的方向,去做后续处理
if(fund_transfer_info->transfer_type == XTP_FUND_INTER_TRANSFER_IN)
message = string(" internal fund transfer is success: fund amount:") + to_string(fund_transfer_info->amount) + "\n";
break;
}
case XTP_FUND_OPER_FAILED:
{
message = string(" fund transfer is failed.\n");
break;
}
case XTP_FUND_OPER_PROCESSING:
{
message = string(" fund transfer is processing.\n");
break;
}
case XTP_FUND_OPER_SUBMITTED:
{
message = string(" fund transfer is arrived at the counter to centralized process.\n");
break;
}
default:
break;
}
}
cout << message;
}1.7. 完整示例代码
以下是MyTraderSpi.h文件。
cpp
#pragma once
#include "xtpx_trader_api.h"
#include <fstream>
using namespace XTPX::API;
class MyTraderSpi : public TraderSpi
{
public:
MyTraderSpi();
~MyTraderSpi();
///当登录成功后,中途出现某个服务(资金划拨或者查询)服务状态改变时,该方法将被调用。
virtual void OnServerStatusNotification(uint64_t session_id, uint32_t server_type, bool status);
virtual void OnFundTransfer(XTPFundTransferNotice *fund_transfer_info, XTPRI *error_info, uint64_t session_id);
void setUserAPI(XTPX::API::TraderApi* pApi) { pUserApi = pApi; }
private:
void requestFundTransfer(XTPX::API::TraderApi* pUserApi, uint64_t session_id_);
private:
XTPX::API::TraderApi* pUserApi;
};以下是MyTraderSpi.cpp文件.
cpp
#include "MyTraderSpi.h"
#include <iostream>
#include <cstring>
#include <iomanip>
#include <stdio.h>
using namespace std;
extern int client_id;
MyTraderSpi::MyTraderSpi()
{
}
MyTraderSpi::~MyTraderSpi()
{
}
void MyTraderSpi::OnServerStatusNotification(uint64_t session_id, uint32_t server_type, bool status)
{
if (1 == server_type && status)//server_type:1表示资金划拨服务,2表示查询服务
{
requestFundTransfer(pUserApi, session_id);//资金划拨服务可用时,发起资金划拨请求
}
}
void MyTraderSpi::OnFundTransfer(XTPFundTransferNotice *fund_transfer_info, XTPRI *error_info, uint64_t session_id)
{
string message;
if (error_info != NULL && error_info->error_id != 0)
{
//划转失败
message = string(" fund transfer is failed:") + to_string(error_info->error_id) + ": " + error_info->error_msg + "\n";
}
else
{
//TODO:可以根据GetClientIDByXTPID() == client_id来过滤自己的订单
uint8_t temp_client_id = pUserApi->GetClientIDByXTPID(fund_transfer_info->serial_id);
if (temp_client_id == client_id)//注意client_id为本程序中创建TraderApi时传入的client_id,用户需要自己定义修改
{
//TODO:此资金划拨订单由本程序发起的
}
else
{
//TODO:此资金划拨订单非本程序发起
}
//根据资金划拨订单的状态来处理自己的资金逻辑
switch(fund_transfer_info->oper_status)
{
case XTP_FUND_OPER_SUCCESS:
{
//TODO:根据资金划拨的方向,去做后续处理
if(fund_transfer_info->transfer_type == XTP_FUND_INTER_TRANSFER_IN)
message = string(" internal fund transfer is success: fund amount:") + to_string(fund_transfer_info->amount) + "\n";
break;
}
case XTP_FUND_OPER_FAILED:
{
message = string(" fund transfer is failed.\n");
break;
}
case XTP_FUND_OPER_PROCESSING:
{
message = string(" fund transfer is processing.\n");
break;
}
case XTP_FUND_OPER_SUBMITTED:
{
message = string(" fund transfer is arrived at the counter to centralized process.\n");
break;
}
default:
break;
}
}
cout << message;
}
//本文示例请求资金划拨是从XTP转出到柜台
void MyTraderSpi::requestFundTransfer(XTPX::API::TraderApi* pUserApi, uint64_t session_id_)
{
XTPFundTransferReq fund_transfer;
memset(&fund_transfer, 0, sizeof(XTPFundTransferReq));
std::string stdstr_fund_account = "xxxxxxxxxxxxx";// 用户资金账户
strcpy_s(fund_transfer.fund_account, XTP_ACCOUNT_NAME_LEN, stdstr_fund_account.c_str());// 用户资金账户的字符串长度
fund_transfer.amount = 1000.0;//划转金额
fund_transfer.transfer_type = XTP_FUND_TRANSFER_OUT;//从XTP转出到柜台
uint64_t xtp_serial_id = pUserApi->FundTransfer(&fund_transfer, session_id_);//调用资金划转的接口,资金从XTP转出到主柜台
if (xtp_serial_id == 0)
{
//TODO:表示发送失败,可以使用GetApiLastError()获取失败原因
}
else
{
//TODO:资金划拨请求发送成功,可以记录下资金划拨订单号xtp_serial_id,以备使用
}
}以下是main.cpp文件
cpp
#include <string>
#include <iostream>
#include <cstdlib>
#include <thread>
#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif // _WIN32
#include "MyTraderSpi.h"
int client_id = 1;
int main()
{
XTPX::API::TraderApi* pUserApi = XTPX::API::TraderApi::CreateTraderApi(client_id,"./", XTP_LOG_LEVEL_DEBUG);
if(pUserApi)
{
// 注册回调接口
MyTraderSpi* pUserSpi = new MyTraderSpi();
pUserApi->RegisterSpi(pUserSpi);
pUserSpi->setUserAPI(pUserApi);
// 登录前参数设置
pUserApi->SetHeartBeatInterval(20);
pUserApi->SetSoftwareKey("xxxxxxxxxx");
pUserApi->SetSoftwareVersion("xx.xx.xx.xx");
// 设置公有流(订单响应、成交回报)重传方式
pUserApi->SubscribePublicTopic(XTP_TERT_QUICK);
// 用户请根据实际情况修改登录参数
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 temp_session_ = pUserApi->Login(trade_server_ip.c_str(), trade_server_port, account_name.c_str(), account_pw.c_str(), XTP_PROTOCOL_TCP);
if(temp_session_ == 0)
{
//登录失败,获取登录失败原因
XTPRI* error_info = pUserApi->GetApiLastError();
std::cout << account_name << " login to server error, " << error_info->error_id << " : " << error_info->error_msg << std::endl;
}
//主线程循环,防止进程退出
while (true)
{
#ifdef _WIN32
Sleep(1000);
#else
sleep(1);
#endif // _WIN32
}
}
return 0;
}2. 查询资金后操作资金划拨的示例
2.1. 继承Spi
代码通过#include "xtpx_trader_api.h",将xtpxtraderapi.lib中声明的类和数据类型包括进来,该头文件中有两个重要的基类:和。
TraderApi类提供交易相关的请求接口,本示例中调用登录接口、查询其他节点的可用资金和资金划拨接口。
TraderSpi类提供交易相关的回调接口,本示例需要继承该类并重写OnServerStatusNotification()回调接口和OnQueryOtherServerFund()回调接口,以及OnFundTransfer()回调接口。
2.2. 初始化Api
在主函数main()里完成MyTraderApi的初始化,创建TraderSpi实例,并向TraderApi实例注册;
2.3. 登录交易服务器
登录交易服务器,登录前设置必要参数,包括设置软件开发版本号,软件开发Key,心跳检测时间间隔等,登录接口返回会话ID表示登录成功;
2.4. 监测资金划拨服务是否可用
查询其他节点的可用资金接口QueryOtherServerFund()受资金划拨服务器是否可用的影响,只有资金划拨服务器处于可用状态,才能请求调用接口QueryOtherServerFund(),否则会请求失败。登录交易服务器后,api端内部会自动连接资金划拨服务,如果连接成功,会收到服务状态变化的通知。示例如下:
cpp
void MyTraderSpi::OnServerStatusNotification(uint64_t session_id, uint32_t server_type, bool status)
{
if (1 == server_type)//server_type:1表示资金划拨服务,2表示查询服务
{
//实时保存资金划拨服务状态
m_serverStatus= status;
asset_condition.notify_one();//通知查询资金的等待线程
}
}注意:
2.5. 调用查询其他节点的可用资金接口QueryOtherServerFund
主程序中登录交易服务器后,并收到OnServerStatusNotification()的资金划拨服务可用状态通知后,就可以用api调用资金查询接口QueryOtherServerFund()。
以双中心账号为例,登录上海节点后,去查询深圳节点的可用资金示例代码如下:
cpp
int client_id = 1;
mutex server_mutex;
condition_variable asset_condition;
bool m_serverStatus = false;
int main()
{
XTPX::API::TraderApi* pUserApi = XTPX::API::TraderApi::CreateTraderApi(client_id,"./", XTP_LOG_LEVEL_DEBUG);
if(pUserApi)
{
// 注册回调接口
MyTraderSpi* pUserSpi = new MyTraderSpi();
pUserApi->RegisterSpi(pUserSpi);
pUserSpi->setUserAPI(pUserApi);
// 登录前参数设置
pUserApi->SetHeartBeatInterval(20);
pUserApi->SetSoftwareKey("xxxxxxxxxx");
pUserApi->SetSoftwareVersion("xx.xx.xx.xx");
// 设置公有流(订单响应、成交回报)重传方式
pUserApi->SubscribePublicTopic(XTP_TERT_QUICK);
// 用户请根据实际情况修改登录参数
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 session_id = pUserApi->Login(trade_server_ip.c_str(), trade_server_port, account_name.c_str(), account_pw.c_str(), XTP_PROTOCOL_TCP);
if(session_id == 0)
{
//登录失败,获取登录失败原因
XTPRI* error_info = pUserApi->GetApiLastError();
std::cout << account_name << " login to server error, " << error_info->error_id << " : " << error_info->error_msg << std::endl;
}
else
{
//session_id为登录后得到的session_id
unique_lock<mutex> assetLock(server_mutex);
auto now = std::chrono::system_clock::now();
asset_condition.wait_until(assetLock, now + 30000ms, [&] {//条件等待资金划拨服务可用时,再进行资金划拨
return m_serverStatus;
});
if(m_serverStatus)
{
XTPFundQueryReq fundQuery;
memset(&fundQuery, 0, sizeof(XTPFundQueryReq));
std::string stdstr_fund_account = "xxxxxxx";
strncpy(fundQuery.fund_account, stdstr_fund_account.c_str(), XTP_ACCOUNT_NAME_LEN);
fundQuery.query_type = XTP_FUND_QUERY_INTERNAL;
fundQuery.query_site = XTP_TRANSFER_SITE_SZ;//双中心账户查询必填
pUserApi->QueryOtherServerFund(&fundQuery, session_id, 1);//查询其他节点的可用资金
}
else
{
std::cout << "The fund transfer service is unavailable, or the waiting time has expired." <<std::endl;
}
}
//主线程循环,防止进程退出
while (true)
{
#ifdef _WIN32
Sleep(1000);
#else
sleep(1);
#endif // _WIN32
}
}
return 0;
}2.6. 重写查询资金回调函数OnQueryOtherServerFund()
调用查询资金接口QueryOtherServerFund()后,会收到资金查询结果的回调通知,重写基类TraderSpi的回调接口OnQueryOtherServerFund(),示例如下:
cpp
/**XTPX::API::TraderApi* pUserApi ;//创建的交易api实例
*/
void MyTraderSpi::OnQueryOtherServerFund(XTPFundQueryRsp *fund_info, XTPRI *error_info, int request_id, uint64_t session_id)
{
if(error_info && error_info->error_id != 0)
{
std::cout <<"OnQueryOtherServerFund is error:"<< error_info->error_id <<std::endl;
return;
}
if(fund_info && fund_info->amount > 0)
requestFundTransfer(pUserApi, session_id, fund_info->amount);//根据查询到的资金,发起资金划拨请求
}2.7. 调用资金划拨接口FundTransfer
发出查询资金QueryOtherServerFund()的请求后,等待查询资金OnQueryOtherServerFund()的回调通知,用户根据查询到的资金结果进行资金划拨,资金划拨请求的示例如下:
cpp
/**XTPX::API::TraderApi* pUserApi ;//交易api的创建示例在此忽略
uint64_t session_id_ ;//登录成功后得到的会话
*/
//假设从深圳节点转入到本节点(上海节点)
void MyTraderSpi::requestFundTransfer(XTPX::API::TraderApi* pUserApi, uint64_t session_id_, double amount)
{
XTPFundTransferReq fund_transfer;
memset(&fund_transfer, 0, sizeof(XTPFundTransferReq));
std::string stdstr_fund_account = "xxxxxxxxx";// 用户资金账户
strcpy_s(fund_transfer.fund_account, XTP_ACCOUNT_NAME_LEN, stdstr_fund_account.c_str());// 用户资金账户的字符串长度
fund_transfer.amount = amount;//划转金额(最好先通过QueryOtherServerFund()查询对方节点的可用资金)
fund_transfer.transfer_type = XTP_FUND_INTER_TRANSFER_IN;// 跨节点转入 从对端XTP节点2,转入到本XTP节点1,XTP服务器之间划拨,只能是开通“一账号两中心”用户使用
fund_transfer.site = XTP_TRANSFER_SITE_SZ;
uint64_t xtp_serial_id = pUserApi->FundTransfer(&fund_transfer, session_id_);// 调用资金划转的接口,资金从双中心另一个节点转入到本服务器节点
if (xtp_serial_id == 0)
{
//TODO:表示发送失败,可以使用GetApiLastError()获取失败原因
}
else
{
//TODO:资金划拨请求发送成功,可以记录下资金划拨订单号xtp_serial_id,以备使用
}
}2.8. 重写资金划转的回调函数逻辑
资金划拨成功后,划拨结果通过回调函数OnFundTransfer()返回,用户根据自己的策略重写该回调函数。
cpp
void MyTraderSpi::OnFundTransfer(XTPFundTransferNotice *fund_transfer_info, XTPRI *error_info, uint64_t session_id)
{
string message;
if (error_info != NULL && error_info->error_id != 0)
{
//划转失败
message = string(" fund transfer is failed:") + to_string(error_info->error_id) + ": " + error_info->error_msg + "\n";
}
else
{
//TODO:可以根据GetClientIDByXTPID() == client_id来过滤自己的订单
uint8_t temp_client_id = pUserApi->GetClientIDByXTPID(fund_transfer_info->serial_id);
if (temp_client_id == client_id)//注意client_id为本程序中创建TraderApi时传入的client_id,用户需要自己定义修改
{
//TODO:此资金划拨订单由本程序发起的
}
else
{
//TODO:此资金划拨订单非本程序发起
}
//根据资金划拨订单的状态来处理自己的资金逻辑
switch(fund_transfer_info->oper_status)
{
case XTP_FUND_OPER_SUCCESS:
{
//TODO:根据资金划拨的方向,去做后续处理
if(fund_transfer_info->transfer_type == XTP_FUND_INTER_TRANSFER_IN)
message = string(" internal fund transfer is success: fund amount:") + to_string(fund_transfer_info->amount) + "\n";
break;
}
case XTP_FUND_OPER_FAILED:
{
message = string(" fund transfer is failed.\n");
break;
}
case XTP_FUND_OPER_PROCESSING:
{
message = string(" fund transfer is processing.\n");
break;
}
case XTP_FUND_OPER_SUBMITTED:
{
message = string(" fund transfer is arrived at the counter to centralized process.\n");
break;
}
default:
break;
}
}
cout << message;
}2.9. 完整示例代码
以下是MyTraderSpi.h文件。
cpp
#pragma once
#include "xtpx_trader_api.h"
#include <fstream>
using namespace XTPX::API;
class MyTraderSpi : public TraderSpi
{
public:
MyTraderSpi();
~MyTraderSpi();
///当登录成功后,中途出现某个服务(资金划拨或者查询)服务状态改变时,该方法将被调用。
virtual void OnServerStatusNotification(uint64_t session_id, uint32_t server_type, bool status);
virtual void OnFundTransfer(XTPFundTransferNotice *fund_transfer_info, XTPRI *error_info, uint64_t session_id);
virtual void OnQueryOtherServerFund(XTPFundQueryRsp *fund_info, XTPRI *error_info, int request_id, uint64_t session_id);
void setUserAPI(XTPX::API::TraderApi* pApi) { pUserApi = pApi; }
private:
void requestFundTransfer(XTPX::API::TraderApi* pUserApi, uint64_t session_id_, double amount);
private:
XTPX::API::TraderApi* pUserApi;
};以下是MyTraderSpi.cpp文件。
cpp
#include "MyTraderSpi.h"
#include <iostream>
#include <cstring>
#include <iomanip>
#include <stdio.h>
#include <condition_variable>
using namespace std;
extern int client_id;
extern condition_variable asset_condition;
extern bool m_serverStatus;
MyTraderSpi::MyTraderSpi()
{
}
MyTraderSpi::~MyTraderSpi()
{
}
void MyTraderSpi::OnServerStatusNotification(uint64_t session_id, uint32_t server_type, bool status)
{
if (1 == server_type)//server_type:1表示资金划拨服务,2表示查询服务
{
//实时保存资金划拨服务状态
m_serverStatus= status;
asset_condition.notify_one();//通知查询资金的等待线程
}
}
void MyTraderSpi::OnFundTransfer(XTPFundTransferNotice *fund_transfer_info, XTPRI *error_info, uint64_t session_id)
{
string message;
if (error_info != NULL && error_info->error_id != 0)
{
//划转失败
message = string(" fund transfer is failed:") + to_string(error_info->error_id) + ": " + error_info->error_msg + "\n";
}
else
{
//TODO:可以根据GetClientIDByXTPID() == client_id来过滤自己的订单
uint8_t temp_client_id = pUserApi->GetClientIDByXTPID(fund_transfer_info->serial_id);
if (temp_client_id == client_id)//注意client_id为本程序中创建TraderApi时传入的client_id,用户需要自己定义修改
{
//TODO:此资金划拨订单由本程序发起的
}
else
{
//TODO:此资金划拨订单非本程序发起
}
//根据资金划拨订单的状态来处理自己的资金逻辑
switch(fund_transfer_info->oper_status)
{
case XTP_FUND_OPER_SUCCESS:
{
//TODO:根据资金划拨的方向,去做后续处理
if(fund_transfer_info->transfer_type == XTP_FUND_INTER_TRANSFER_IN)
message = string(" internal fund transfer is success: fund amount:") + to_string(fund_transfer_info->amount) + "\n";
break;
}
case XTP_FUND_OPER_FAILED:
{
message = string(" fund transfer is failed.\n");
break;
}
case XTP_FUND_OPER_PROCESSING:
{
message = string(" fund transfer is processing.\n");
break;
}
case XTP_FUND_OPER_SUBMITTED:
{
message = string(" fund transfer is arrived at the counter to centralized process.\n");
break;
}
default:
break;
}
}
cout << message;
}
void MyTraderSpi::OnQueryOtherServerFund(XTPFundQueryRsp *fund_info, XTPRI *error_info, int request_id, uint64_t session_id)
{
if(error_info && error_info->error_id != 0)
{
std::cout <<"OnQueryOtherServerFund is error:"<< error_info->error_id <<std::endl;
return;
}
if(fund_info && fund_info->amount > 0)
requestFundTransfer(pUserApi, session_id, fund_info->amount);//根据查询到的资金,发起资金划拨请求
}
//本示例是将资金从深圳节点转入到本节点(上海节点)
void MyTraderSpi::requestFundTransfer(XTPX::API::TraderApi* pUserApi, uint64_t session_id_, double amount)
{
XTPFundTransferReq fund_transfer;
memset(&fund_transfer, 0, sizeof(XTPFundTransferReq));
std::string stdstr_fund_account = "xxxxxxxxx";// 用户资金账户
strcpy_s(fund_transfer.fund_account, XTP_ACCOUNT_NAME_LEN, stdstr_fund_account.c_str());// 用户资金账户的字符串长度
fund_transfer.amount = amount;//划转金额(通过QueryOtherServerFund()查询到的对方节点的可用资金)
fund_transfer.transfer_type = XTP_FUND_INTER_TRANSFER_IN;// 跨节点转入 从对端XTP节点2,转入到本XTP节点1,XTP服务器之间划拨,只能是开通“一账号两中心”用户使用
fund_transfer.site = XTP_TRANSFER_SITE_SZ;//双中心用户跨节点划拨时必填
uint64_t xtp_serial_id = pUserApi->FundTransfer(&fund_transfer, session_id_);// 调用资金划转的接口,资金从双中心另一个节点转入到本服务器节点
if (xtp_serial_id == 0)
{
//TODO:表示发送失败,可以使用GetApiLastError()获取失败原因
}
else
{
//TODO:资金划拨请求发送成功,可以记录下资金划拨订单号xtp_serial_id,以备使用
}
}以下是main.cpp文件。
cpp
#include <string>
#include <iostream>
#include <cstdlib>
#include <thread>
#include <condition_variable>
#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif // _WIN32
#include "MyTraderSpi.h"
using namespace std;
int client_id = 1;
mutex server_mutex;
condition_variable asset_condition;
bool m_serverStatus = false;
int main()
{
XTPX::API::TraderApi* pUserApi = XTPX::API::TraderApi::CreateTraderApi(client_id,"./", XTP_LOG_LEVEL_DEBUG);
if(pUserApi)
{
// 注册回调接口
MyTraderSpi* pUserSpi = new MyTraderSpi();
pUserApi->RegisterSpi(pUserSpi);
pUserSpi->setUserAPI(pUserApi);
// 登录前参数设置
pUserApi->SetHeartBeatInterval(20);
pUserApi->SetSoftwareKey("xxxxxxxxxx");
pUserApi->SetSoftwareVersion("xx.xx.xx.xx");
// 设置公有流(订单响应、成交回报)重传方式
pUserApi->SubscribePublicTopic(XTP_TERT_QUICK);
// 用户请根据实际情况修改登录参数
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 session_id = pUserApi->Login(trade_server_ip.c_str(), trade_server_port, account_name.c_str(), account_pw.c_str(), XTP_PROTOCOL_TCP);
if(session_id == 0)
{
//登录失败,获取登录失败原因
XTPRI* error_info = pUserApi->GetApiLastError();
std::cout << account_name << " login to server error, " << error_info->error_id << " : " << error_info->error_msg << std::endl;
}
else
{
unique_lock<mutex> assetLock(server_mutex);
auto now = std::chrono::system_clock::now();
asset_condition.wait_until(assetLock, now + 30000ms, [&] {//条件等待资金划拨服务可用时,再查询其他节点的资金
return m_serverStatus;
});
if(m_serverStatus)
{
XTPFundQueryReq fundQuery;
memset(&fundQuery, 0, sizeof(XTPFundQueryReq));
std::string stdstr_fund_account = "xxxxxxx";
strncpy(fundQuery.fund_account, stdstr_fund_account.c_str(), XTP_ACCOUNT_NAME_LEN);
fundQuery.query_type = XTP_FUND_QUERY_INTERNAL;
fundQuery.query_site = XTP_TRANSFER_SITE_SZ;//双中心账户查询必填
pUserApi->QueryOtherServerFund(&fundQuery, session_id, 1);//查询其他节点的可用资金
}
else
{
std::cout << "The fund transfer service is unavailable, or the waiting time has expired." <<std::endl;
}
}
//主线程循环,防止进程退出
while (true)
{
#ifdef _WIN32
Sleep(1000);
#else
sleep(1);
#endif // _WIN32
}
}
return 0;
}