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.5.5. 跨节点转出融券卖出所得资金
cpp
/**XTP::API::TraderApi* pUserApi ;//交易api的创建示例在此忽略
uint64_t session_id_ ;//登录成功后得到的会话
*/
//从本节点转出到上海节点
void MyTraderSpi::requestFundTransfer(XTP::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_REPAY_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.6. 跨节点转入融券卖出所得资金
cpp
/**XTP::API::TraderApi* pUserApi ;//交易api的创建示例在此忽略
uint64_t session_id_ ;//登录成功后得到的会话
*/
//从深圳节点转入到本节点
void MyTraderSpi::requestFundTransfer(XTP::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_REPAY_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.5.7. 跨节点转出两融授信额度
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_CONTRACT_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.8. 跨节点转入两融授信额度
cpp
/**XTP::API::TraderApi* pUserApi ;//交易api的创建示例在此忽略
uint64_t session_id_ ;//登录成功后得到的会话
*/
//从深圳节点转入到本节点
void MyTraderSpi::requestFundTransfer(XTP::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_CONTRACT_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;
}2. 完整示例代码
以下是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;
}
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;
}