华锐交易执行平台标准网关API使用说明

发布于 2018-11-16 作者 luojian345 150次 浏览 版块 ATP-华锐核心交易平台

华锐交易执行平台标准网关API使用说明

文档目的

本文档是华锐金融技术股份有限公司ATP平台agw模块的api使用说明。

术语与缩略语

术语、缩写 解释
ATP 华锐交易执行平台
AGW 华锐标准网关

参考文档

  • 《可扩展二进制数据交换协议_0.10.docx》
  • 《华锐ATP交易数据接口协议_0.10.docx》

API说明

本api是连接华锐标准网关的API客户端,使用C++编写,运行环境为redhat7.2、boost_1_62_0,编译器为gcc 4.8.5。
windows 编译运行环境为windows7 64位, 使用visual studio 2017 编译。

调用api主要直接使用到以下几个头文件:

文件名 说明
agw_client.h AgwClient接口的定义和说明
agw_event.h 错误码以及回调接口的说明
messages_agw_external.h 业务消息的定义

AgwClient接口函数说明

Connect函数

项目 说明
函数声明 ErrorCode Connect(const Properties& properties,ClientHandler* handler)
函数说明 发起异步连接AGW
返回值 0[kSuccess]为成功,其他为失败
参数说明 properties[in] 连接参数设置
handler[in] 事件回调处理句柄,继承自agw::ClientHandler

properties 可以设置的参数有:

  • “User”: string,登录的用户名,必填
  • “PasswordSha256”:string 登录的密码,sha256散列后的密码,必填
  • “Locations”: 连接地址,vector,每个连接地址为”ip:port”形式,必填
  • “HeartbeatIntervalMilli”: 发心跳间隔时间,int32_t,单位:毫秒,默认值:5000
  • “HeartbeatTimeoutMilli”: 检测心跳超时时间,int32_t,单位:毫秒,默认值:HeartbeatInterval*3
  • “ConnectTimeoutMilli”: 连接超时时间,int32_t,单位:毫秒,默认值:5000
  • “ReconnectTime”: 重试连接次数,int32_t,默认值:连接地址数
  • “ReconnectDelayMilli”:重新连接延迟时间,int32_t,单位毫秒,默认值:5000
  • “ReportSync”: 回报同步数据,map,默认值:空

备注

  • Connect 中会校验参数(密码格式,ip等), 方法调用成功只是发起异步连接请求成功,连接是否成功建立,需要从事件回调中判断。
  • Connect 非线程安全,一个AgwClient只能建立一个连接。网络断开后会根据设置的重连次数自动重连,只有kEndOfConnection事件触发后才不会自动重连。这时候才可以再次调用Connect函数去连接。
  • agw::ClientHandler和函数返回值ErrorCode可以在api接口中的agw_event.h文件中查看。
  • 连接后会自动登录和发送同步回报消息。
  • 网络断开后会重连当前断开的地址,如果没有连接成功,才会连接Locations中下一个地址。如果到最后的位置,会从头开始重连,例如Locations中有192.168.102.10:32001,192.168.102.11:32001,192.168.102.12:32001三个地址,当前连接的地址为192.168.102.10:32001,连接断开后会重连192.168.102.10:32001,如果没有连接成功, 再次重连的地址为192.168.102.11:32001。
    连接成功后会重置连接次数,重新计数。

SendMessage函数

项目 说明
函数声明 ErrorCode SendMessage(const ExternalMessageType msg_type,const ExternalMessagePtr& message_ptr);
ErrorCode SendMessage(const ExternalMessageType msg_type,const ExternalMessage* message);
ErrorCode SendMessage(const std::string& msg);
函数说明 异步发送业务消息
返回值 0[kSuccess]为成功,其他为失败
参数说明 msg_type [in] 发送消息的类型;
Message_ptr [in]待编码消息的智能指针;
message [in]发送消息的数据指针,编码前的消息。Api内部会自动编码
msg [in]已编码消息的二进制数据,即已按照《华锐ATP交易数据接口协议》编码。

备注

  • 可以发送的消息在messages_agw_external.h文件中有定义,字段类型可以查看《华锐ATP交易数据接口协议_V0.10.docx》中的数据字典。业务消息中的ClientSeqID(用户系统消息序号)需要调用者保证唯一。
  • SendMessage 有两个版本,一个消息体为智能指针,一个为原始指针。原始指针版本内部会拷贝一份数据发送,智能指针版本会使用这个指针。

EncodeMessage函数

项目 说明
函数声明 static std::tuple < bool,std::string > EncodeMessage(const ExternalMessageType msg_type, const ExternalMessagePtr& message_ptr);
函数说明 将消息编码成二进制
返回值 0[bool: 编码是否成功,true:成功,false:失败 std::string :编码后的二进制
参数说明 msg_type [in]发送消息的类型; message_ptr [in] 待编码消息

DecodeMessage函数

项目 说明
函数声明 static std::tuple< bool,ExternalMessageType,ExternalMessagePtr > DecodeMessage(const std::string& message);
函数说明 将二进制解码成对应的消息
返回值 Std::tuple < bool,ExternalMessageType,ExternalMessagePtr > Bool: 解码是否成功,true:成功,false:失败;ExternalMessageType:解码后的消息类型;ExternalMessagePtr:解码后的消息
参数说明 message [in] 待解码的二进制

Close函数

项目 说明
函数声明 ErrorCode Close();
函数说明 异步关闭连接
返回值 0 [kSuccess]为成功,其他为失败
参数说明
备注 调用Close关闭后最终会触发kEndOfConnection事件,不会再自动重连

api 调用顺序

  1. Connect 连接,会自动登陆和发送同步回报请求
  2. SendMessage 连接成功并收到回报同步完成事件后即可发送消息
  3. Close 关闭连接


事件回调接口ClientHandler说明

OnEvent函数

项目 说明
函数声明 virtual void OnEvent(const Event& event)
函数说明 事件回调接口,api触发各种事件时通过该回调通知
返回值
参数说明 event事件,包括事件级别,事件类型,事件的描述
备注

事件类型有以下取值:

  • kConnected, ///< 已连接,连接agw成功触发
  • kConnectFailure, ///< 连接失败,连接agw失败触发
  • kConnectTimeout, ///< 连接超时,指定的的时间内没有成功连agw时触发
  • kLogout, ///< 登录失败触发。失败原因从事件的描述原因可以看到,有以下几种登录失败:1. 用户名或密码错误;2.当前用户已经登录3. 登录的网关非主网关;4.回报同步分区号或索引号错误;
  • kLogin, ///< 登录成功并同步回报完成
  • kEndOfConnection, ///< 连接结束,不会再自动发起连接
  • kError, ///< 错误,发生错误时触发。比如解码失败
  • kHeartbeatTimeout, ///< 接收心跳超时,指定时间内没有收到心跳触发
  • kClosed, ///< 连接关闭,socket连接关闭时触发

OnMessage函数

项目 说明
函数声明 virtual void OnMessage(const ExternalMessageType msg_type,const ExternalMessagePtr& message)
函数说明 消息回调接口,收到agw发来的业务消息会调用该接口
返回值
参数说明 msg_type消息类型;message 消息数据,已经解码后的消息
备注

OnMessage函数

项目 说明
函数声明 virtual void OnLog(LogLevel level,const std::string& message)
函数说明 日志回调接口,api处理的日志通过该接口打印
返回值
参数说明 level日志级别;message日志内容
备注 日志级别LogLevel有以下几种:kTrace,kDebug,kInfo,kWarn,kError,kFatal

AGW API 开发包信息

  1. 打包好后的api包文件名举例(日期为实际发布日期):
    ATP_SDK_20180801032558_V2.9.0.180730_rc2.0.tar.gz
  2. 执行命令tar -zxvf ATP_SDK_20180801032558_V2.9.0.180730_rc2.0.tar.gz
  3. 解压后可看到gw_api目录中有:include、lib、agw_api_demo。
  4. include中为api使用和依赖的头文件。
  5. lib中为api使用和依赖的库文件。
  6. agw_api_demo为demo程序。

编译运行demo

编译和运行demo程序(linux)

本文档提供了一个简单的demo程序,需要编译后运行api依赖boost库,版本为1.62.0 需要自己获取。
1. 设置BOOST_ROOT和AGW_API_ROOT 环境变量
BOOST_ROOT 为 boost库的根目录
AGW_API_ROOT 为API的根目录,就是从包中解压出的gw_api目录
比如在终端上这样设置:
export BOOST_ROOT=/home/archforce/3rd/boost_1_62_0
export AGW_API_ROOT=/home/archforce/gw_api
2. 使用make或者boost b2编译
在demo程序的根目录中执行make即可编译成功
编译好的文件在Release目录下,名称为agw_api_demo
使用boost b2编译的话,在demo程序目录下执行b2,需要先配置好b2的环境
3. 运行
运行需要设置LD_LIBRARY_PATH ,指向api的库文件目录
比如在终端上这样设置:
export LD_LIBRARY_PATH=/home/archforce/gw_api/lib
然后在Release目录下执行如下命令
./agw_api_demo –ip 127.0.0.1 –port 32001 –user user1 –password password1
其中
–ip 选项为demo程序连接的agw的ip地址
–port 选项为demo程序连接的agw的端口
–user 选项为登陆agw的用户
–password 选项为登陆agw的密码

demo代码示例

#include <stdio.h>
#include <string>
#include <thread>
#include <atomic>
#include <memory>
#include "boost/program_options.hpp"
#include "boost/algorithm/string.hpp"
#include "setvalue.h"
#include "agw_client.h"
#include "datautil.h"
#include "messages_agw_external.h"
#include "types_agw_external.h"
#include "properties.h"
using namespace agw;
using namespace boost::program_options;
//设置连接属性的key
const std::string kUser("User");
const std::string kPasswordSha256("PasswordSha256");
const std::string kLocations("Locations");
const std::string kHeartbeatIntervalMilli("HeartbeatIntervalMilli");
const std::string kHeartbeatTimeoutMilli("HeartbeatTimeoutMilli");
const std::string kConnectTimeoutMilli("ConnectTimeoutMilli");
const std::string kReconnectTime("ReconnectTime");
const std::string kReconnectDelayMilli("ReconnectDelayMilli");
const std::string kReportSync("ReportSync");
void SendCancelOrder(atp::gw::ClOrdNO_def);

//demo使用到的一些全局变量
agw::AgwClient  g_client;//AgwClient 对象
std::string g_user;                         //用户名
std::string g_password;                     //用户密码
std::map<int32_t, int32_t> g_partition_info;//保存同步回报信息
std::atomic<bool> g_login_succes{ false };//是否登录成功
std::atomic<bool> g_exit{ false };
std::map<atp::gw::SeqNum_def, std::shared_ptr<atp::gw::AgwMsgOrder>>  g_client_seq_order_map;
std::map<atp::gw::ClOrdNO_def, atp::gw::SeqNum_def> g_report_client_seq_map;
//Demo的回调处理,继承自agw::ClientHandler
class DemoClientHandler :public agw::ClientHandler
{
	//事件回调
	virtual void OnEvent(const Event& event)
	{
		//打印出事件信息
		std::cout << "OnEvent -> EventLevel:" << (int32_t)event.level << ",EventType:" << (int32_t)event.type << ",What:" << event.what << std::endl;
		switch (event.type)
		{
		case agw::EventType::kConnected://tcp连接建立成功
		{}
		break;
		case  agw::EventType::kConnectFailure://tcp连接建立失败
		{}
		break;
		case agw::EventType::kConnectTimeout:        ///连接超时
		{}
		break;
		case agw::EventType::kLogin:                 ///登录成功
		{
			g_login_succes = true;
		}
		break;
		case agw::EventType::kLogout:///登录失败退出
		{
			g_login_succes = false;
		}
		break;
		case  agw::EventType::kClosed://tcp 连接关闭
		{
			g_login_succes = false;
		}
		break;
		case  agw::EventType::kHeartbeatTimeout://心跳超时
		{}
		break;
		case agw::EventType::kError://发生错误
		{}
		case  agw::EventType::kEndOfConnection://连接次数用完,不会再自动重连
		{
			g_exit = true;
		}
		break;
		default:
			break;
		}
	}

	virtual void OnMessage(const agw::ExternalMessageType msg_type, const agw::ExternalMessagePtr& message)
	{
		//记录网关发来的分区号和索引号,下次发送同步请求的时候会用到
		if (msg_type == atp::gw::kAgwMsgOrderStatusAck) // 委托状态响应,存在多个状态响应(执行类型与订单状态)
		{
			auto p = std::dynamic_pointer_cast<atp::gw::AgwMsgOrderStatusAck>(message);
			if (p == nullptr)
			{
				std::cout << "dynamic pointer cast to nullptr." << std::endl;
				return;
			}
			g_partition_info[p->partition] = p->index;
			//std::cout<<p->ToString()<<std::endl;
			if (g_client_seq_order_map.find(p->client_seq_id) != g_client_seq_order_map.end())
			{
				g_report_client_seq_map[p->client_order_no] = p->client_seq_id;		//建立客户订单编号与原始委托的映射关系
				SendCancelOrder(p->client_order_no);// 测试撤单请求
			}

			//根据状态响应做相应的操作
			{
				auto agw_msg_order = g_client_seq_order_map[p->client_seq_id]; //找到原始委托
			     // 交易引擎内部状态
				if (p->exec_type == atp::gw::AgwExecType::kInternal)
				{
					std::cout << " client_order_no:" << p->client_order_no << " exec_type:" << "引擎内部状态 " << (int32_t)p->order_status << std::endl;
				}
				// 新订单
				else if (p->exec_type == atp::gw::AgwExecType::kNew)
				{
					// 交易所确认
					if (p->order_status == atp::gw::AgwOrdStatus::kNew)
					{
						std::cout << " client_order_no:" << p->client_order_no << " exec_type:" << "交易所确认 " << (int32_t)p->order_status << std::endl;
					}
				}
				// 已撤销
				else if (p->exec_type == atp::gw::AgwExecType::kCancelled)
				{
					std::cout << " client_order_no:" << p->client_order_no << " exec_type:" << "已撤销 " << (int32_t)p->order_status << std::endl;
				}
				// 已拒绝
				else if (p->exec_type == atp::gw::AgwExecType::kReject)
				{
					std::cout << " client_order_no:" << p->client_order_no << " exec_type:" << "已拒绝 "
						<< (int32_t)p->order_status << " 拒绝代码:" << p->reject_reason_code << std::endl;
				}
			}
		}

		if (msg_type == atp::gw::kAgwMsgCashAuctionTradeER) // 现货成交回报
		{
			auto p = std::dynamic_pointer_cast<atp::gw::AgwMsgCashAuctionTradeER>(message);
			if (p == nullptr)
			{
				std::cout << "dynamic pointer cast to nullptr." << std::endl;
				return;
			}
			g_partition_info[p->partition] = p->index;
			//std::cout<<p->ToString()<<std::endl;
			if (g_report_client_seq_map.end() == g_report_client_seq_map.find(p->client_order_no))
			{
				std::cout << "cannot find the origin order,please check out" << std::endl;
				return;
			}
			std::cout << " client_order_no:" << p->client_order_no << " (已成交)执行类型:" << p->exec_type << std::endl;

		}
		if (msg_type == atp::gw::kAgwMsgExtQueryResultFund) // 资金查询结果
		{
			auto p = std::dynamic_pointer_cast<atp::gw::AgwMsgExtQueryResultFund>(message);
			if (p == nullptr)
			{
				std::cout << "dynamic pointer cast to nullptr." << std::endl;
				return;
			}
		}
		if (msg_type == atp::gw::kAgwMsgExtQueryResultShare) //持仓查询结果
		{
			auto p = std::dynamic_pointer_cast<atp::gw::AgwMsgExtQueryResultShare>(message);
			if (p == nullptr)
			{
				std::cout << "dynamic pointer cast to nullptr." << std::endl;
				return;
			}
			std::cout << " total_num:" << p->total_num << std::endl;
			for (uint32_t i = 0; i < p->order_array.size(); ++i)
			{
				//atp::gw::AgwShareArray xxx = p->order_array[i] ;
				//xxx.security_id;
				//xxx.security_symbol
				//xxx.market_id
				//...
			}
		}
		if (msg_type == atp::gw::kAgwMsgExtQueryMaxOrderQtyResult) // 最大可委托数查询结果
		{
			auto p = std::dynamic_pointer_cast<atp::gw::AgwMsgExtQueryMaxOrderQtyResult>(message);
			if (p == nullptr)
			{
				std::cout << "dynamic pointer cast to nullptr." << std::endl;
				return;
			}
			std::cout << " QueryResultCode:" << p->query_result_code << " MaxOrderQty:" << p->max_order_qty << std::endl;
		}
		if (msg_type == atp::gw::kAgwMsgExtQueryResultOrder) // 订单查询结果
		{
			auto p = std::dynamic_pointer_cast<atp::gw::AgwMsgExtQueryResultOrder>(message);
			if (p == nullptr)
			{
				std::cout << "dynamic pointer cast to nullptr." << std::endl;
				return;
			}
			std::cout << " AgwMsgExtQueryResultOrder total number is:" << p->total_num << std::endl;
			for (uint32_t i = 0; i < p->order_array.size(); ++i)
			{
				std::cout << "cl_ord_no:" << p->order_array[i].cl_ord_no << std::endl;
			}
		}

		if (msg_type == atp::gw::kAgwMsgBizRejection) // 业务拒绝结果
		{
			auto p = std::dynamic_pointer_cast<atp::gw::AgwMsgBizRejection>(message);
			if (p == nullptr)
			{
				std::cout << "dynamic pointer cast to nullptr." << std::endl;
				return;
			}
			std::cout << " 外部业务拒绝消息:" << p->reject_reason_code << std::endl;
		}
	}

	//日志回调
	virtual void OnLog(LogLevel level, const std::string& message)
	{
		//打印日志信息
		std::cout << "OnLog -> level:" << (int32_t)level << ",message:" << message << std::endl;
	}
};

const std::string cust_id("00181226");
const std::string fund_account_id("00181226");
const std::string account_id("0199900001");
const std::string security_id("000001");

void SendQueryFund()
{
	//查询资金
	{
		auto p = std::make_shared<atp::gw::AgwMsgExtQueryFund>();
		agw::SetValue(p->cust_id, cust_id);
		agw::SetValue(p->fund_account_id, fund_account_id);
		agw::SetValue(p->account_id, account_id);
		agw::SetValue(p->client_seq_id, agw::AgwUtil::GenerateClientSeqID());
		agw::SetValue(p->client_feature_code, "agw_api_demo");
		agw::SetValue(p->currency, atp::gw::AgwCurrency::kCNY);
		std::cout << p->ToString() << std::endl;
		//发送查询资金消息
		auto ec = g_client.SendMessage(atp::gw::kAgwMsgExtQueryFund, p);
		if (ec != ErrorCode::kSuccess)
		{
			std::cout << "SendMessage Error:" << ec << std::endl;
			std::this_thread::sleep_for(std::chrono::seconds(5));
		}
	}
}

void SendQueryShare()
{
	//查询持仓
	{
		auto p = std::make_shared<atp::gw::AgwMsgExtQueryShare>();
		agw::SetValue(p->cust_id, cust_id);
		agw::SetValue(p->fund_account_id, cust_id);
		agw::SetValue(p->account_id, account_id);
		agw::SetValue(p->client_seq_id, agw::AgwUtil::GenerateClientSeqID());
		agw::SetValue(p->client_feature_code, "agw_api_demo");
		atp::gw::AgwAccountIDArray acount_id_arr;
		agw::SetValue(acount_id_arr.account_id, account_id);
		p->account_id_array.push_back(acount_id_arr);
		agw::SetValue(p->business_type, atp::gw::AgwBusinessType::kCashAuction);
		agw::SetValue(p->market_id, 0); //填0,查所有市场
		agw::SetValue(p->security_id, security_id); //
		agw::SetValue(p->query_index, 0); // 填0表示从头开始查
		agw::SetValue(p->return_num, 0);	// 填0表示不指定返回数量
		std::cout << p->ToString() << std::endl;
		//发送查询资金消息
		auto ec = g_client.SendMessage(atp::gw::kAgwMsgExtQueryShare, p);
		if (ec != ErrorCode::kSuccess)
		{
			std::cout << "SendMessage Error:" << ec << std::endl;
			std::this_thread::sleep_for(std::chrono::seconds(5));
		}
	}
}

void SendQueryMaxQty()
{
	//查询最大可委托数
	{
		auto p = std::make_shared<atp::gw::AgwMsgExtQueryMaxOrderQty>();
		agw::SetValue(p->cust_id, cust_id);
		agw::SetValue(p->fund_account_id, fund_account_id);
		agw::SetValue(p->account_id, account_id);
		agw::SetValue(p->client_seq_id, agw::AgwUtil::GenerateClientSeqID());
		agw::SetValue(p->client_feature_code, "agw_api_demo");
		agw::SetValue(p->market_id, atp::gw::AgwMarketID::kShenZhen);
		agw::SetValue(p->security_id, security_id);
		agw::SetValue(p->side, atp::gw::AgwSide::kBuy);
		agw::SetValue(p->business_type, 1);
		agw::SetValue(p->price, 10 * 10000);
		std::cout << p->ToString() << std::endl;

		//发送最大可委托查询消息
		auto ec = g_client.SendMessage(atp::gw::kAgwMsgExtQueryMaxOrderQty, p);
		if (ec != ErrorCode::kSuccess)
		{
			std::cout << "SendMessage Error:" << ec << std::endl;
			std::this_thread::sleep_for(std::chrono::seconds(5));
		}
	}
}
void SendCashOrder()
{
	//现货委托消息
	{
		atp::gw::SeqNum_def seq_id = agw::AgwUtil::GenerateClientSeqID();
		auto p = std::make_shared<atp::gw::AgwMsgCashAuctionOrder>();
		agw::SetValue(p->business_type, 1);
		agw::SetValue(p->security_id, security_id);
		agw::SetValue(p->market_id, atp::gw::AgwMarketID::kShenZhen);
		agw::SetValue(p->client_order_time, agw::AgwUtil::GetLocalTimeStamp());
		agw::SetValue(p->cust_id, cust_id);
		agw::SetValue(p->fund_account_id, fund_account_id);
		agw::SetValue(p->account_id, account_id);
		agw::SetValue(p->side, atp::gw::AgwSide::kBuy);
		agw::SetValue(p->order_type, atp::gw::AgwOrdType::kLocalOptimal);
		agw::SetValue(p->price, 0 * 10000);
		agw::SetValue(p->order_qty, 1000 * 100);
		agw::SetValue(p->client_seq_id, seq_id);
		agw::SetValue(p->client_feature_code, std::string("agw_api"));
		agw::SetValue(p->stop_px, 0);
		agw::SetValue(p->min_qty, 0);
		agw::SetValue(p->time_in_force, '0');
		agw::SetValue(p->cash_margin, atp::gw::AgwCashMargin::kCash);
		std::cout << p->ToString() << std::endl;
		g_client_seq_order_map[seq_id] = p;
		//发送现货集中竞价业务委托消息
		auto ec = g_client.SendMessage(atp::gw::kAgwMsgCashAuctionOrder, p);
		if (ec != ErrorCode::kSuccess)
		{
			std::cout << "SendMessage Error:" << ec << std::endl;
			std::this_thread::sleep_for(std::chrono::seconds(5));
		}
	}
}
void SendCancelOrder(atp::gw::ClOrdNO_def cl_ord_no)
{
	//撤单消息
	{
		auto p = std::make_shared<atp::gw::AgwMsgCancelOrder>();
		agw::SetValue(p->business_type, 1);
		agw::SetValue(p->security_id, security_id);
		agw::SetValue(p->market_id, atp::gw::AgwMarketID::kShenZhen);
		agw::SetValue(p->client_order_time, agw::AgwUtil::GetLocalTimeStamp());
		agw::SetValue(p->cust_id, cust_id);
		agw::SetValue(p->fund_account_id, fund_account_id);
		agw::SetValue(p->account_id, account_id);
		agw::SetValue(p->side, atp::gw::AgwSide::kBuy);
		agw::SetValue(p->order_type, atp::gw::AgwOrdType::kFixed);
		agw::SetValue(p->price, 0 * 1000);
		agw::SetValue(p->order_qty, 1000 * 100);
		agw::SetValue(p->client_seq_id, agw::AgwUtil::GenerateClientSeqID());
		agw::SetValue(p->client_feature_code, std::string("agw_api"));
		agw::SetValue(p->orig_cli_ord_no, cl_ord_no); // 被撤销客户订单编号
		std::cout << p->ToString() << std::endl;
		auto ec = g_client.SendMessage(atp::gw::kAgwMsgCancelOrder, p);
		if (ec != ErrorCode::kSuccess)
		{
			std::cout << "SendMessage Error:" << ec << std::endl;
			std::this_thread::sleep_for(std::chrono::seconds(5));
		}
	}
}
void SendExtQueryOrder()
{
	//订单查询消息
	{
		auto p = std::make_shared<atp::gw::AgwMsgExtQueryOrder>();
		agw::SetValue(p->cust_id, fund_account_id);
		agw::SetValue(p->fund_account_id, fund_account_id);
		agw::SetValue(p->account_id, account_id);
		agw::SetValue(p->client_seq_id, agw::AgwUtil::GenerateClientSeqID());
		agw::SetValue(p->client_feature_code, std::string("agw_api"));
		agw::SetValue(p->cl_ord_no, 0); // 客户订单号填0查所有
		agw::SetValue(p->market_id, 0); // 市场代码,填0查所有
		agw::SetValue(p->security_id, std::string("")); // 证券代码,填空查所有
		agw::SetValue(p->business_type, 0); // 业务类型,填0查所有
		agw::SetValue(p->side, atp::gw::AgwSide::kAll);
		agw::SetValue(p->order_query_condition, atp::gw::AgwOrderQueryCondition::kAll);
		agw::SetValue(p->query_index, 0);// 起始索引号,填0 表示从头开始查询
		agw::SetValue(p->return_num, 0);
		agw::SetValue(p->return_seq, atp::gw::AgwReturnSeq::kTimeOrder);
		std::cout << p->ToString() << std::endl;
		auto ec = g_client.SendMessage(atp::gw::kAgwMsgExtQueryOrder, p);
		if (ec != ErrorCode::kSuccess)
		{
			std::cout << "SendMessage Error:" << ec << std::endl;
			std::this_thread::sleep_for(std::chrono::seconds(5));
		}
	}
}
void EncodeDecode()
{
	auto p = std::make_shared<atp::gw::AgwMsgCashAuctionOrder>();
	agw::SetValue(p->business_type, 1);
	agw::SetValue(p->security_id, security_id);
	agw::SetValue(p->market_id, 102);
	agw::SetValue(p->client_order_time, agw::AgwUtil::GetLocalTimeStamp());
	agw::SetValue(p->cust_id, fund_account_id);
	agw::SetValue(p->fund_account_id, fund_account_id);
	agw::SetValue(p->account_id, account_id);
	agw::SetValue(p->side, '1');
	agw::SetValue(p->order_type, '2');
	agw::SetValue(p->price, 0 * 10000);
	agw::SetValue(p->order_qty, 0 * 100);
	agw::SetValue(p->client_seq_id, agw::AgwUtil::GenerateClientSeqID());
	agw::SetValue(p->client_feature_code, std::string("agw_api"));
	agw::SetValue(p->stop_px, 0);
	agw::SetValue(p->min_qty, 0);
	agw::SetValue(p->time_in_force, '0');
	agw::SetValue(p->cash_margin, '1');
	std::cout << p->ToString() << std::endl;
	auto ret_encode = agw::AgwClient::EncodeMessage(atp::gw::kAgwMsgCashAuctionOrder, p);
	if (!std::get<0>(ret_encode))
	{
		std::cout << " AgwClient::EncodeMessage is failed." << __FILE__
			<< " " << __LINE__ << std::endl;
		return;
	}
	auto ec_ret = g_client.SendMessage(std::get<1>(ret_encode));
	if (ec_ret != ErrorCode::kSuccess)
	{
		std::cout << "SendMessage Error:" << std::endl;
		std::this_thread::sleep_for(std::chrono::seconds(5));
		return;
	}
	auto ret_decode = agw::AgwClient::DecodeMessage(std::get<1>(ret_encode));
	if (!std::get<0>(ret_decode))
	{
		std::cout << " AgwClient::DecodeMessage is failed." << __FILE__ << " "
			<< __LINE__ << std::endl;
		return;
	}
	auto pp = std::dynamic_pointer_cast<atp::gw::AgwMsgCashAuctionOrder>(std::get<2>(ret_decode));
	agw::SetValue(pp->client_seq_id, agw::AgwUtil::GenerateClientSeqID());
	std::cout << std::get<0>(ret_decode) << std::endl;
	std::cout << std::get<1>(ret_decode) << std::endl;
	//std::cout<<pp->ToString()<<std::endl;
	std::cout << (std::get<2>(ret_decode))->ToString() << std::endl;
	auto ec = g_client.SendMessage(std::get<1>(ret_decode), std::get<2>(ret_decode));
	if (ec != ErrorCode::kSuccess)
	{
		std::cout << "SendMessage Error:" << ec << std::endl;
		std::this_thread::sleep_for(std::chrono::seconds(5));
		return;
	}
}
int main(int argc, char *argv[])
{
	//解析命令行参数
	std::string ip, user, password;
	uint16_t port = 32001;
	boost::program_options::options_description opts("clientdemo options");
	opts.add_options()
		("help,h", "help info")
		("ip,i", value<std::string>(&ip)->default_value("127.0.0.1"), "ip,default 127.0.0.1")
		("port,p", value<uint16_t>(&port)->default_value(32001), "port,default 32001")
		("user,u", value<std::string>(&user)->default_value("user1"), "user,default user1")
		("password,w", value<std::string>(&password)->default_value("password1"), "password,default password1");

	variables_map vm;
	try
	{
		store(parse_command_line(argc, argv, opts), vm);
	}
	catch (boost::program_options::error_with_no_option_name& ex)
	{
		std::cout << ex.what() << std::endl;
		return -1;
	}
	notify(vm);
	if (vm.count("help"))
	{
		std::cout << opts << std::endl;
		return -1;
	}
	std::cout << "ip:" << ip << "\n";
	std::cout << "port:" << port << "\n";
	std::cout << "user:" << user << "\n";
	std::cout << "password:" << password << "\n";
	std::cout << "start......" << std::endl;
	g_user = user;
	g_password = password;
	//ip和端口
	std::string remote_ip = ip + ":" + std::to_string(port);
	std::vector<std::string>  vLocations
	{
		remote_ip,
		"127.0.0.1:32002"
	};
	//设置连接信息
	Properties prop;
	prop.SetValue(kUser, g_user);//登录用户
	prop.SetValue(kPasswordSha256, agw::AgwUtil::GenerateSha256(g_password));//sha256密码
	prop.SetValue(kLocations, vLocations);//ip地址
	prop.SetValue(kHeartbeatIntervalMilli, int32_t(10 * 1000));//发送心跳间隔
	prop.SetValue(kConnectTimeoutMilli, int32_t(10 * 1000));//连接超时时间
	prop.SetValue(kReconnectTime, int32_t(10));//重连次数
	prop.SetValue(kReportSync, g_partition_info);//回报同步索引信息
	//连接agw
	ErrorCode ec = g_client.Connect(prop, new DemoClientHandler);
	if (ec != ErrorCode::kSuccess)
	{
		std::cout << "Connect error:" << ec << std::endl;
		return -1;
	}
	while (!g_exit)
	{
		if (g_login_succes)
		{
			int send_count = 1;
			int i = 0;
			for (; i < send_count; i++)
			{
				SendQueryFund();
				SendQueryShare();
				SendQueryMaxQty();
				SendCashOrder();
				SendExtQueryOrder();
				EncodeDecode();
			}
			if (i == send_count)
			{
				std::cout << "send finished\n";
			}
			else
			{
				std::cout << "send error\n";
			}
			break;
		}
	}
	while (!g_exit)
	{
		std::string line;
		std::cout << "Input quit/q/exit exit:" << std::endl;
		std::cin >> line;
		boost::algorithm::to_lower(line);
		boost::algorithm::trim(line);

		if (line == "quit" || line == "q" || line == "exit")
			break;
	}
	std::cout << "will close ," << g_exit << std::endl;
	g_client.Close();//主动关闭连接
	printf("agw api demo exit\n");
	return 0;
}
收藏
分享
暂无回复