Skip to content

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

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