#include "stdafx.h"
#include "TradeApi.h"
#include "../NetMgr/SSLAgent.h"
#include "../NetMgr/TcpClient.h"
#include "json/json.h"
#include "crypto/md5.h"
#include "comdef.h"
#include "../crypto/CryptoTool.h"
#include "Common.h"
#include "../Log/LogMgr.h"
#include <stdio.h>  
#include "../NetMgr/MsgHandle.h"
#include <WinSock2.h>
#include <Iphlpapi.h>
#include <iostream>
using namespace std;
#pragma comment(lib,"Iphlpapi.lib") //需要添加Iphlpapi.lib库


#define GUID_LEN 64  
#define SHA1_LEN 128
#define MAX_BUFFER_SIZE 10240
#define MAX_BUFFER_SIZERECV 102400

CTradeApi*  CTradeApi::m_instance = nullptr;
CTradeApi::CTradeApi()
{
	m_bIsLogin = false;
	m_bTradeIsLogin = false;
	m_sGuid = generGuid();
	m_bodyLen = 0;
	m_nPakgeId=0;
	m_recvLen = 0;
	m_recvBuf=nullptr;
	m_recvBuf = new char[MAX_BUFFER_SIZERECV];//100K
	m_bSubPakage = false;
}


CTradeApi::~CTradeApi()
{
	delete[] m_recvBuf;
	m_recvBuf = nullptr;
}
void CTradeApi::OnReadData(const BYTE* pData, int iLength)
{
	MsgHead head;
	if (m_recvLen == 0)
		memset(m_recvBuf, 0, MAX_BUFFER_SIZERECV);
	memcpy_s(m_recvBuf+ m_recvLen, 102400, pData, iLength);
	m_recvLen += iLength;
	if(!MsgHandle::parseHeadMsg(m_recvBuf, HEAD_LEN, &head)) return;
	m_bodyLen = head.bodyLen;
	if (m_bodyLen + HEAD_LEN > m_recvLen)//分包
	{
		m_bSubPakage = true;
		return;
	}
	char *pBody= new char[m_bodyLen];
	memset(pBody, 0, m_bodyLen);
	if (m_bodyLen + HEAD_LEN < m_recvLen)//粘包
	{
		memcpy_s(pBody, m_bodyLen, m_recvBuf + HEAD_LEN, m_bodyLen);
		memcpy_s(m_recvBuf, MAX_BUFFER_SIZERECV, m_recvBuf+ m_bodyLen + HEAD_LEN, m_recvLen- m_bodyLen- HEAD_LEN);//把粘包后面的拷贝到前面去
		m_recvLen = m_recvLen - HEAD_LEN - m_bodyLen;
	}
	else {
		memcpy_s(pBody, m_bodyLen, m_recvBuf + HEAD_LEN, m_bodyLen);
		m_recvLen = m_recvLen - HEAD_LEN - m_bodyLen;
	}

	m_bSubPakage = false;
	string sOut;
	if(m_bodyLen>0)
	  sOut=MsgHandle::decryptBody(head, pBody, m_bodyLen, m_sSecretKey);
	if(pBody)
	   delete[] pBody;
	HeartBeat pbHeart;
	PBRequest pbReq;
	PBResponse pbRes;
	PBNotify pbNotify;
	switch (head.msgType)
	{
	case EN_MSGTYPE_HEARTBEAT:
		if (pbHeart.ParseFromString(sOut))
		{
			cout << "recv heartbeat" << endl;
		}
		else
		{
			cout << "parse req failure" << endl;
		}
		break;
	case EN_MSGTYPE_REQ:
		if (pbReq.ParseFromString(sOut))
		{
			cout << "parse req success" << endl;
		}
		else
		{
			cout << "parse req failure" << endl;
		}
		break;
	case EN_MSGTYPE_RESP:

		if (pbRes.ParseFromString(sOut))
		{
			string sCode = pbRes.responsecode();
			string sMsg = pbRes.responsemsg();
			string uMsg = CCommon::UTF8_To_CString(sMsg);
			if (sCode != SYS_CODE_SUCCESS)
			{
				string uMsg = CCommon::UTF8_To_CString(sMsg);
				cout << " error code:" << sCode << " error msg:" << uMsg << endl;
				return;
			}
			bool bRet = false;
			string sTmp;
			long nData = 0;
			ResponseMsgType msgType = pbRes.responsemsgtype();
			cout << "Handle MsgType:" << msgType << endl;
			switch (msgType)
			{
			case InitConnectResponseMsgType:
				HandleInitConnectResponse(pbRes);
				break;
			case CommonResponseMsgType:
				break;
			case CommonIntResponseMsgType:
				break;
			case CommonStringResponseMsgType://期货下单和改单
				sTmp = HandleCommonStringResponse(pbRes);
				cout << "委托编号:" << sTmp << endl;
				break;
			case CommonBoolResponseMsgType://期货撤单
				bRet=HandleCommonBoolResponse(pbRes);
				if (bRet)
					cout << "撤单成功" << endl;
				else
					cout << "撤单失败" << endl;
				break;
			case TrsStockQueryMarginBuyAmountResponseMsgType:
				break;
			case TrsStockQueryRealEntrustListResponseMsgType:
				break;
			case TrsStockQueryRealDeliverListResponseMsgType:
				break;
			case TrsStockQueryHistoryEntrustListResponseMsgType:
				break;
			case TrsStockQueryHistoryDeliverListResponseMsgType:
				break;
			case TrsStockQueryHoldsListResponseMsgType:
				break;
			case TrsStockQueryHoldsFundInfoResponseMsgType:
				break;
			case TrsStockQueryBasicFundInfoResponseMsgType:
				break;
			case TrsStockQueryPageHoldsListResponseMsgType:
				break;
			case TradeLoginResponseMsgType:
				m_bTradeIsLogin = HandleCommonBoolResponse(pbRes);
				if (m_bTradeIsLogin)
					cout << "交易登录成功" << endl;
				else
					cout << "交易登录失败" << endl;
				break;
			case TradeLogoutResponseMsgType:
				bRet= HandleCommonBoolResponse(pbRes);
				if (bRet)
					m_bTradeIsLogin = false;
				if (bRet)
					cout << "交易退出成功" << endl;
				else
					cout << "交易退出失败" << endl;
				break;
			case TradeEntrustResponseMsgType:
				sTmp=HandleCommonStringResponse(pbRes);
				cout << "下单 委托编号:" << sTmp << endl;
				break;
			case TradeChangeEntrustResponseMsgType:
				sTmp = HandleCommonStringResponse(pbRes);
				cout << "改单 委托编号:" << sTmp << endl;
				break;
			case TradeCancelEntrustResponseMsgType:
				sTmp = HandleCommonStringResponse(pbRes);
				cout << "撤单 委托编号:" << sTmp << endl;
				break;
			case TradeQueryHoldsListResponseMsgType://持仓列表
				cout << "持仓信息:" << endl;
				HandleStockQueryHoldsListResponse(pbRes);
				break;
			case TradeQueryBuyAmountResponseMsgType://最大可买
				nData = HandleCommonIntResponse(pbRes);
				cout << "最大可买数量:" << nData << endl;
				break;
			case TradeQuerySellAmountResponseMsgType://最大可卖
				nData = HandleCommonIntResponse(pbRes);
				cout << "最大可卖数量:" << nData << endl;
				break;
			case TradeQueryMarginFundInfoResponseMsgType://客户资金信息
				HandleTradeQueryMarginFundInfoResponse(pbRes);
				break;
			case TradeQueryRealEntrustListResponseMsgType://当日实时委托
				HandleTradeQueryRealEntrustListResponse(pbRes);
				break;
			case TradeQueryHistoryEntrustListResponseMsgType://历史委托
				HandleTradeQueryHistoryEntrustListResponse(pbRes);
				break;
			case TradeQueryRealDeliverListResponseMsgType://当日成交接
				HandleTradeQueryRealDeliverListResponse(pbRes);
				break;
			case TradeQueryHistoryDeliverListResponseMsgType://历史成交接
				HandleTradeQueryHistoryDeliverListResponse(pbRes);
				break;
			case TradeQueryRealFundJourListResponseMsgType://当日资金流水
				HandleTradeQueryRealFundJourListResponse(pbRes);
				break;
			case TradeQueryHistoryFundJourListResponseMsgType://历史资金流水
				HandleTradeQueryHistoryFundJourListResponse(pbRes);
				break;
			case TradeSubscribeResponseMsgType:
				bRet = HandleCommonBoolResponse(pbRes);
				if (bRet)
					cout << "订阅交易推送成功" << endl;
				else
					cout << "订阅交易推送失败" << endl;
				break;
			case TradeUnsubscribeResponseMsgType:
				bRet = HandleCommonBoolResponse(pbRes);
				if (bRet)
					cout << "取消订阅交易推送成功" << endl;
				else
					cout << "取消订阅交易推送失败" << endl;
				break;
			case ErrorResponseMsgType:
				break;
			case HQSubscribeResponseMsgType:
				break;
			case HQUnsubscribeResponseMsgType:
				break;
			case HQBasicQotResponseMsgType:
				break;
			case HQBrokerResponseMsgType:
				break;
			case HQOrderBookResponseMsgType:
				break;
			case HQTickerResponseMsgType:
				break;
			case HQKLResponseMsgType:
				break;
			case HQTimeShareResponseMsgType:
				break;
			case ResponseMsgType_INT_MIN_SENTINEL_DO_NOT_USE_:
				break;
			case ResponseMsgType_INT_MAX_SENTINEL_DO_NOT_USE_:
				break;
            //======期货================ 
			case FuturesQueryHoldsListResponseMsgType:
				HandleStockQueryHoldsListResponseFuture(pbRes);
				break;
			case FuturesQueryFundInfoResponseMsgType:
				HandleTradeQueryMarginFundInfoResponseFuture(pbRes);
				break;
			case FuturesQueryRealEntrustListResponseMsgType:
				HandleTradeQueryRealEntrustListResponseFuture(pbRes);
				break;
			case FuturesQueryRealDeliverListResponseMsgType:
				HandleTradeQueryRealDeliverListResponseFuture(pbRes);
				break;
			case FuturesQueryHistoryDeliverListResponseMsgType:
				HandleTradeQueryHistoryDeliverListResponseFuture(pbRes);
				break;
			case FuturesQueryHistoryEntrustListResponseMsgType:
				HandleTradeQueryHistoryEntrustListResponseFuture(pbRes);
				break;
			case FuturesQueryBuySellAmountResponseMsgType:
				HandleQueryBuySellAmountResponseFuture(pbRes);
				break;
			case FuturesEntrustResponseMsgType://期货下单
				sTmp = HandleCommonStringResponse(pbRes);
				cout << "期货下单 委托编号:" << sTmp << endl;
				break;
			case FuturesModifyEntrustResponseMsgType://期货改单
				sTmp = HandleCommonStringResponse(pbRes);
				cout << "期货改单 委托编号:" << sTmp << endl;
				break;
			case FuturesCancelEntrustResponseMsgType://期货撤单
				sTmp = HandleCommonStringResponse(pbRes);
				cout << "期货撤单 委托编号:" << sTmp << endl;
				break;
			default:
				break;
			}
		}
		else
		{
			cout << "parse resp failure" << endl;
		}
		break;
	case EN_MSGTYPE_PUSH:

		if (pbNotify.ParseFromString(sOut))
		{
			cout << "parse notify success" << endl;
		}
		else
		{
			cout << "parse notify failure" << endl;
		}
		break;
	default:
		break;
	}
}
string CTradeApi::generGuid()
{
	char buffer[GUID_LEN] = { 0 };
	GUID guid;
	if (CoCreateGuid(&guid))
	{
		fprintf(stderr, "create guid error\n");
		return "";
	}
	_snprintf(buffer, sizeof(buffer),
		"%08X-%04X-%04x-%02X%02X-%02X%02X%02X%02X%02X%02X",
		guid.Data1, guid.Data2, guid.Data3,
		guid.Data4[0], guid.Data4[1], guid.Data4[2],
		guid.Data4[3], guid.Data4[4], guid.Data4[5],
		guid.Data4[6], guid.Data4[7]);
	string sRet = buffer;
	return sRet;
}
string CTradeApi::onEncryptedMsgRSABase64(string strMsg)
{
	//加密
#ifdef TEST_DEV
	string sFilePub = PUB_FILE_PLAT_TEST;
#else
	string sFilePub = PUB_FILE_PLAT;
#endif
	string encryptedMsg = CCryptoTool::RSAEncryptString(sFilePub.c_str(), strMsg.c_str());
	return encryptedMsg;
}
string CTradeApi::onDecryptedMsgRSABase64(string strMsg)
{
	//解密
	string sFilePri = PRIVATE_FILE;
	string sSeed = "seed";
	string decryptedMsg = CCryptoTool::RSADecryptString(sFilePri.c_str(),strMsg.c_str());
	return decryptedMsg;
}
void byte2Hex(unsigned char bData, unsigned char hex[])
{
	int high = bData / 16, low = bData % 16;
	hex[0] = (high < 10) ? ('0' + high) : ('A' + high - 10);
	hex[1] = (low < 10) ? ('0' + low) : ('A' + low - 10);
}
vector<stMacInfo> CTradeApi::_GetMacInfo()
{
	vector<stMacInfo> vecMacInfo;
	unsigned char *mac = (unsigned char*)malloc(sizeof(char) * 150);
	ULONG ulSize = 0;
	PIP_ADAPTER_INFO pInfo = NULL;
	int temp = 0;
	temp = GetAdaptersInfo(pInfo, &ulSize);//第一处调用，获取缓冲区大小
	if (ulSize <= 0)
	{
		return vecMacInfo;
	}
	pInfo = (PIP_ADAPTER_INFO)malloc(ulSize);
	void* p = pInfo;
	temp = GetAdaptersInfo(pInfo, &ulSize);

	while (pInfo)//遍历每一张网卡
	{
		stMacInfo macInfo;
		////////////////////////检测是否是虚拟网卡
		{
			string sAddr;
			unsigned char chItem[10] = { 0 };
			for (int i = 0; i < (int)pInfo->AddressLength && i < 8; i++)
			{
				byte2Hex(pInfo->Address[i], &chItem[0]);
				sAddr += (const char*)chItem;
				sAddr += "-";
			}
			sAddr = sAddr.substr(0, sAddr.size() - 1);
			/////////////
			if (sAddr.find("00-05-69") != -1 ||
				sAddr.find("00-0C-29") != -1 ||
				sAddr.find("00-50-56") != -1 ||
				sAddr.find("00-1c-14") != -1 ||
				sAddr.find("00-1C-42") != -1 ||
				sAddr.find("00-03-FF") != -1 ||
				sAddr.find("00-0F-4B") != -1 ||
				sAddr.find("00-16-3E") != -1 ||
				sAddr.find("08-00-27") != -1 ||
				sAddr.find("0A-00-27") != -1)
			{
				macInfo.bVirtual = true;
			}
		}
		int iCount = 0;
		memset(mac, 0, 150);
		for (int i = 0; i < (int)pInfo->AddressLength; i++)
		{
			byte2Hex(pInfo->Address[i], &mac[iCount]);//Address为char型，8位数据转换成两位十进制的字符
			iCount += 2;
			if (i < (int)pInfo->AddressLength - 1)
			{
				mac[iCount++] = '-';
			}
			else
			{

				mac[iCount++] = '\0';
				break;
			}
		}
		macInfo.nType = pInfo->Type;
		macInfo.sIp = pInfo->IpAddressList.IpAddress.String;
		macInfo.sMac = string((const char*)mac);
		if (macInfo.sIp != "0.0.0.0")
		{
			cout << "==mac info==" << macInfo.sMac << " "<< macInfo.bVirtual << " " << macInfo.nType << " " << macInfo.sIp << endl;
			vecMacInfo.push_back(macInfo);
		}

		pInfo = pInfo->Next;
	}
	if (NULL != p)
	{
		free(p);
	}
	if (NULL != mac)
	{
		free(mac);
	}
	return vecMacInfo;
}
string CTradeApi::_GetLoaclMacInfo()
{
	string sDeviceNo;
	if (m_vecMac.size() == 0)
	{
		m_vecMac = _GetMacInfo();
	}
	if (m_vecMac.size() > 0)
	{
		vector<string> vecFind;
		for (int i = 0; i < m_vecMac.size(); i++)
		{
			stMacInfo info = m_vecMac[i];
			int nPos1 = info.sIp.find(".");
			string sFirst;
			if (nPos1 != -1)
				sFirst = info.sIp.substr(0, nPos1);
			cout << "===first" << sFirst<<" " <<info.bVirtual<< endl;
			if (!info.bVirtual)
			{
				vecFind.push_back(info.sMac);
				if (sFirst == "192")
				{
					sDeviceNo = info.sMac;
					break;
				}
			}

		}

		if (sDeviceNo.empty())
		{
			if (vecFind.size() > 0)
			{
				sDeviceNo = vecFind[0];
			}
			else {
				sDeviceNo = m_vecMac[0].sMac;
			}

		}
	}
	return sDeviceNo;
}
bool CTradeApi::onLogin(string sMobile, string sPwd, bool bHK)
{
	bool bRet = false;
	string encryptedPwd = onEncryptedMsgRSABase64(sPwd);
	//cout << "Encrypted Pwd:\t" << encryptedPwd << endl;
	/////////////////
	string sOut;
	string sUrl = URL_HEAD;
	//sUrl += "/hs/login";//旧接口 没有设备绑定
	sUrl += "/hs/v2/login";
	string sDeviceNo/* = DEVICE_NO*/;
	sDeviceNo = _GetLoaclMacInfo();
	cout << "deviceno:" << sDeviceNo << endl;
	string sCountryCode = "CHN";
	if(bHK)
		sCountryCode = "HKG";
	string sData = "countryCode="+ sCountryCode +"&mobile="+ sMobile+"&password="+ encryptedPwd/*+"&deviceNo=" + sDeviceNo*/;
	if (!sDeviceNo.empty())
	{
		sData += "&deviceNo=" + sDeviceNo;
	}
	HTTP_CLIENT->SendMsg(T_HTTPS_REQUEST_POST, sUrl, sData, sOut);
	//cout << sOut << endl;

	Json::Value root,data;
	Json::CharReaderBuilder builder;
	Json::Value mgv_obj;
	JSONCPP_STRING errs;

	auto reader = builder.newCharReader();
	if (reader->parse(sOut.c_str(), sOut.c_str()+ sOut.length(), &root, &errs))
	{
		if (root.isMember("respCode"))
		{
			string sRetCode = root["respCode"].asString();
			if (sRetCode == SYS_CODE_SUCCESS)
			{
				m_bIsLogin = true;
			}
			else {
				if (root.isMember("respMsg"))
				{
					string sRetMsg = CCommon::UTF8_To_CString(root["respMsg"].asString());
					cout << "login failed,code:" << sRetCode << " msg:" << sRetMsg<<endl;
				}
			}
		}
		if (root.isMember("data"))
		{
			data= root["data"];
			if (data.isMember("nickName"))
			{

			}
			if (data.isMember("mobile"))
			{
				
			}
			if (data.isMember("token") && data["token"].isString())
			{
				string sToken = data["token"].asString();
				m_sToken = onDecryptedMsgRSABase64(sToken);
				//cout << "Decrypted Token:\t" << m_sToken << endl;
			}
		}
	}
	return bRet;
}
void CTradeApi::onSendVerifyCode(string sMobile)
{
	string sOut;
	string sUrl = URL_HEAD;
	sUrl += "/hs/device/sendAuthCode";
	string sData = "countryCode=CHN&mobile=" + sMobile + "&token=" + m_sToken;
	HTTP_CLIENT->SendMsg(T_HTTPS_REQUEST_POST, sUrl, sData, sOut);
	//cout << sOut << endl;
	Json::Value root, data;
	Json::CharReaderBuilder builder;
	Json::Value mgv_obj;
	JSONCPP_STRING errs;
	auto reader = builder.newCharReader();
	if (reader->parse(sOut.c_str(), sOut.c_str() + sOut.length(), &root, &errs))
	{
		bool bSuccess = false;
		if (root.isMember("respCode"))
		{
			string sRetCode = root["respCode"].asCString();
			if (sRetCode == SYS_CODE_SUCCESS)
				bSuccess = true;
			else
				return;
		}
		if (root.isMember("data"))
		{

		}
	}
}
void CTradeApi::onBindDevice(string sMobile, string sDeviceNo, string sVerifyCode)
{
	string sOut;
	string sUrl = URL_HEAD;
	sUrl += "/hs/device/bind";
	sDeviceNo = DEVICE_NO;
	string sData = "countryCode=CHN&mobile=" + sMobile + "&token=" + m_sToken + "&code=" + sVerifyCode + "&deviceNo=" + sDeviceNo + "&deviceType=Windows10&deviceName=PCClient";
	HTTP_CLIENT->SendMsg(T_HTTPS_REQUEST_POST, sUrl, sData, sOut);
	//cout << sOut << endl;

	Json::Value root, data;
	Json::CharReaderBuilder builder;
	Json::Value mgv_obj;
	JSONCPP_STRING errs;
	auto reader = builder.newCharReader();
	if (reader->parse(sOut.c_str(), sOut.c_str() + sOut.length(), &root, &errs))
	{
		bool bSuccess = false;
		if (root.isMember("respCode"))
		{
			string sRetCode = root["respCode"].asCString();
			if (sRetCode == SYS_CODE_SUCCESS)
				bSuccess = true;
			else
				return;
		}
		if (root.isMember("data"))
		{

		}
	}
}
void CTradeApi::onGetServerList()
{
	string sOut;
	string sUrl = URL_HEAD;
	sUrl += "/hs/config/queryServer";
	string sData = "token=" + m_sToken;
	HTTP_CLIENT->SendMsg(T_HTTPS_REQUEST_POST, sUrl, sData, sOut);
	cout << sOut << endl;

	Json::Value root, data;
	Json::CharReaderBuilder builder;
	Json::Value mgv_obj;
	JSONCPP_STRING errs;
	auto reader = builder.newCharReader();
	if (reader->parse(sOut.c_str(), sOut.c_str() + sOut.length(), &root, &errs))
	{
		bool bSuccess = false;
		if (root.isMember("respCode"))
		{
			string sRetCode = root["respCode"].asCString();
			if (sRetCode == SYS_CODE_SUCCESS)
				bSuccess = true;
			else
				return;
		}
		if (root.isMember("data"))
		{
			data = root["data"];
			if (data.isMember("tradeServer") && data["tradeServer"].isString())
			{
				string sServer = data["tradeServer"].asString();
				int nPos = sServer.find(":");
				if (nPos >= 0)
				{
					m_sServerIp = sServer.substr(0, nPos);
					string sPort = sServer.substr(nPos + 1);
					m_nPort = atoi(sPort.c_str());
					InitSocket(m_sServerIp, m_nPort);
					testTradeInitConnect();
				}
			}
		}
	}
}

string CTradeApi::WritePbReqMsg(google::protobuf::Message* pm, string sReqID, RequestMsgType nMsgType)
{
	PBRequest rBase;
	rBase.set_requestmsgtype(nMsgType);
	rBase.set_requestid(sReqID.c_str());
	rBase.set_requesttime(time(0));
	rBase.set_token(m_sToken.c_str());

	string sRet;
	if (pm)
	{
		auto ay = new google::protobuf::Any();
		ay->PackFrom(*pm);
		rBase.set_allocated_payload(ay);
		sRet = rBase.SerializeAsString();
		ay->Clear();
	}
	else
	{
		sRet = rBase.SerializeAsString();
	}
	return sRet;
}
string CTradeApi::WritePbNotifyMsg(google::protobuf::Message* pm, string sNotifyID, NotifyMsgType nMsgType)
{
	PBNotify  rBase;
	rBase.set_notifymsgtype(nMsgType);
	rBase.set_notifyid(sNotifyID.c_str());
	rBase.set_notifytime(time(0) * 1000);

	string sRet;
	if (pm)
	{
		auto ay = new google::protobuf::Any();
		ay->PackFrom(*pm);
		rBase.set_allocated_payload(ay);
		sRet = rBase.SerializeAsString();
		ay->Clear();
	}
	else
	{
		sRet = rBase.SerializeAsString();
	}
	return sRet;
}

void CTradeApi::InitSocket(string strHost, int nPort)
{
	m_tcpClient.Init(strHost, nPort);
}
///////////////////////////////////////////////////////////// Handle Response Msg
void CTradeApi::HandleInitConnectResponse(const PBResponse &pbResp)
{
	cout << "HandleInitConnectResponse" << endl;
	InitConnectResp resp;
	pbResp.payload().UnpackTo(&resp);
	string sKey = resp.encryptedkey();
	int nHeartBeatTime = resp.heartbeatintervalsec();
	cout << " SecretKey:" << sKey << endl;
	m_sSecretKey = CCryptoTool::DecodeBase64(sKey);
	cout << "SecretKey Len:" << m_sSecretKey.length()<<endl;
	cout << "初始化链接成功!" << endl;
	//m_sSecretKey = sKey;

}
bool CTradeApi::HandleCommonBoolResponse(const PBResponse &pbResp)
{
	cout << "HandleCommonBoolResponse\t" ;
	CommonBoolResponse resp;
	pbResp.payload().UnpackTo(&resp);
	bool bRet= resp.success();
	cout << bRet<<endl;
	return bRet;
}
long CTradeApi::HandleCommonIntResponse(const PBResponse &pbResp)
{
	cout << "HandleCommonIntResponse\t";
	CommonIntResponse resp;
	pbResp.payload().UnpackTo(&resp);
	long nRet = resp.data();
	cout << nRet << endl;
	return nRet;
}
string CTradeApi::HandleCommonStringResponse(const PBResponse &pbResp)
{
	cout << "HandleCommonStringResponse\t";
	CommonStringResponse resp;
	pbResp.payload().UnpackTo(&resp);
	string sRet = resp.data();
	cout << sRet << endl;
	return sRet;
}
void CTradeApi::HandleStockQueryHoldsListResponse(const PBResponse &pbResp)
{
	cout << "HandleStockQueryHoldsListResponse"<<endl;
	StockQueryHoldsListResponse resp;
	pbResp.payload().UnpackTo(&resp);
	int nSize = resp.holdslist_size();
	cout << "持仓条数:" << nSize << endl;
	for (int i = 0; i < nSize; i++)
	{
		HoldsVo *pItem = resp.mutable_holdslist(i);
		string stockCode = pItem->stockcode();
		string stockName = CCommon::UTF8_To_CString(pItem->stockname());
		string currentAmount = pItem->currentamount();
		string enableAmount = pItem->enableamount();
		string costPrice = pItem->costprice();
		string incomeBalance = pItem->incomebalance();
		string marketValue = pItem->marketvalue();
		cout <<"stockCode:"<< stockCode << "\t stockName:" << stockName << "\t currentAmount:" << currentAmount << "\t enableAmount:" << enableAmount << "\t costPrice:" << costPrice << "\t incomeBalance:" << incomeBalance << "\t marketValue:" << marketValue << endl;
	}
}
void CTradeApi::HandleTradeQueryMarginFundInfoResponse(const PBResponse &pbResp)
{
	cout << "HandleTradeQueryMarginFundInfoResponse" << endl;
	TradeQueryMarginFundInfoResponse resp;
	pbResp.payload().UnpackTo(&resp);
	string holdsBalance = resp.holdsbalance();
	string assetBalance = resp.assetbalance();
	string enableBalance = resp.enablebalance();
	string marketValue = resp.marketvalue();
	string spentRatio = resp.spentratio();
	string frozenBalance = resp.frozenbalance();
	string accountStatus = CCommon::UTF8_To_CString(resp.accountstatus());
	cout << "holdsBalance:" << holdsBalance << "\t assetBalance:" << assetBalance << "\t enableBalance:" << enableBalance << "\t marketValue:" << marketValue << "\t spentRatio:" << spentRatio << "\t frozenBalance:" << frozenBalance << "\t accountStatus:" << accountStatus << endl;
}
void CTradeApi::HandleTradeQueryRealEntrustListResponse(const PBResponse &pbResp)
{
	cout << "HandleTradeQueryRealEntrustListResponse" << endl;
	TradeQueryRealEntrustListResponse resp;
	pbResp.payload().UnpackTo(&resp);
	int nSize = resp.data_size();
	for (int i = 0; i < nSize; i++)
	{
		OrderVo *pItem = resp.mutable_data(i);
		string stockCode = pItem->stockcode();
		string stockName = CCommon::UTF8_To_CString(pItem->stockname());
		string entrustPrice = pItem->entrustprice();
		string entrustAmount = pItem->entrustamount();
		string entrustBs = pItem->entrustbs();
		string date = pItem->date();
		string status = pItem->status();
		string entrustId = pItem->entrustid();
		cout << "stockCode:" << stockCode << "\t stockName:" << stockName << "\t entrustPrice:" << entrustPrice << "\t entrustAmount:" << entrustAmount << "\t entrustBs:" << entrustBs << "\t date:" << date << "\t status:" << status << "\t entrustId:" << entrustId << endl;
	}
}
void CTradeApi::HandleTradeQueryHistoryEntrustListResponse(const PBResponse &pbResp)
{
	cout << "HandleTradeQueryHistoryEntrustListResponse" << endl;
	TradeQueryHistoryEntrustListResponse resp;
	pbResp.payload().UnpackTo(&resp);
	int nSize = resp.data_size();
	for (int i = 0; i < nSize; i++)
	{
		OrderVo *pItem = resp.mutable_data(i);
		string stockCode = pItem->stockcode();
		string stockName = pItem->stockname();
		string entrustPrice = pItem->entrustprice();
		string entrustAmount = pItem->entrustamount();
		string entrustBs = pItem->entrustbs();
		string date = pItem->date();
		string status = pItem->status();
		string entrustId = pItem->entrustid();
		cout << "stockCode:" << stockCode << "\t stockName:" << stockName << "\t entrustPrice:" << entrustPrice << "\t entrustAmount:" << entrustAmount << "\t entrustBs:" << entrustBs << "\t date:" << date << "\t status:" << status << "\t entrustId:" << entrustId << endl;
	}
}
void CTradeApi::HandleTradeQueryRealDeliverListResponse(const PBResponse &pbResp)
{
	cout << "HandleTradeQueryRealDeliverListResponse" << endl;
	TradeQueryRealDeliverListResponse resp;
	pbResp.payload().UnpackTo(&resp);
	int nSize = resp.data_size();
	for (int i = 0; i < nSize; i++)
	{
		OrderVo *pItem = resp.mutable_data(i);
		string stockCode = pItem->stockcode();
		string stockName = CCommon::UTF8_To_CString(pItem->stockname());
		string entrustPrice = pItem->entrustprice();
		string entrustAmount = pItem->entrustamount();
		string entrustBs = pItem->entrustbs();
		string date = pItem->date();
		string status = pItem->status();
		string entrustId = pItem->entrustid();
		cout << "stockCode:" << stockCode << "\t stockName:" << stockName << "\t entrustPrice:" << entrustPrice << "\t entrustAmount:" << entrustAmount << "\t entrustBs:" << entrustBs << "\t date:" << date << "\t status:" << status << "\t entrustId:" << entrustId << endl;
	}
}
void CTradeApi::HandleTradeQueryHistoryDeliverListResponse(const PBResponse &pbResp)
{
	cout << "HandleTradeQueryHistoryDeliverListResponse" << endl;
	TradeQueryHistoryEntrustListResponse resp;
	pbResp.payload().UnpackTo(&resp);
	int nSize = resp.data_size();
	for (int i = 0; i < nSize; i++)
	{
		OrderVo *pItem = resp.mutable_data(i);
		string stockCode = pItem->stockcode();
		string stockName = CCommon::UTF8_To_CString(pItem->stockname());
		string entrustPrice = pItem->entrustprice();
		string entrustAmount = pItem->entrustamount();
		string entrustBs = pItem->entrustbs();
		string date = pItem->date();
		string status = pItem->status();
		string entrustId = pItem->entrustid();
		cout << "stockCode:" << stockCode << "\t stockName:" << stockName << "\t entrustPrice:" << entrustPrice << "\t entrustAmount:" << entrustAmount << "\t entrustBs:" << entrustBs << "\t date:" << date << "\t status:" << status << "\t entrustId:" << entrustId << endl;
	}
}
void CTradeApi::HandleTradeQueryRealFundJourListResponse(const PBResponse &pbResp)
{
	cout << "HandleTradeQueryRealFundJourListResponse" << endl;
	TradeQueryRealFundJourListResponse resp;
	pbResp.payload().UnpackTo(&resp);
	int nSize = resp.data_size();
	for (int i = 0; i < nSize; i++)
	{
		FundJourVo  *pItem = resp.mutable_data(i);
		string businessBalance = pItem->businessbalance();
		string type = pItem->type();
		string typeDesc = pItem->typedesc();
		string fundJourParentType = pItem->fundjourparenttype();
		string time = pItem->time();
		string queryParamStr = pItem->queryparamstr();
		cout << "businessBalance:" << businessBalance << "\t type:" << type << "\t typeDesc:" << typeDesc << "\t fundJourParentType:" << fundJourParentType << "\t time:" << time << "\t queryParamStr:" << queryParamStr << endl;
	}
}
void CTradeApi::HandleTradeQueryHistoryFundJourListResponse(const PBResponse &pbResp)
{
	cout << "HandleTradeQueryHistoryFundJourListResponse" << endl;
	TradeQueryHistoryFundJourListResponse resp;
	pbResp.payload().UnpackTo(&resp);
	int nSize = resp.data_size();
	for (int i = 0; i < nSize; i++)
	{
		FundJourVo  *pItem = resp.mutable_data(i);
		string businessBalance = pItem->businessbalance();
		string type = pItem->type();
		string typeDesc = pItem->typedesc();
		string fundJourParentType = pItem->fundjourparenttype();
		string time = pItem->time();
		string queryParamStr = pItem->queryparamstr();
		cout << "businessBalance:" << businessBalance << "\t type:" << type << "\t typeDesc:" << typeDesc << "\t fundJourParentType:" << fundJourParentType << "\t time:" << time << "\t queryParamStr:" << queryParamStr << endl;
	}
}

/////////////////////////////////////////////////////////API
void CTradeApi::TradeCommonReq(const string& sBody)
{
	MsgHead msgHead;
	msgHead.msgType = EN_MSGTYPE_REQ;
	msgHead.serialNo = m_nPakgeId;
	char* pBuf = new char[MAX_BUFFER_SIZE];
	memset(pBuf, MAX_BUFFER_SIZE, 0);
	int nLen = MsgHandle::encodeMsg(pBuf, sBody, msgHead, m_sSecretKey);
	m_tcpClient.SendMsg(pBuf, nLen);
	if (pBuf)
		delete pBuf;
}
void CTradeApi::TradeInitConnect(InitConnectReq &req)
{
	cout << "TradeInitConnect" << endl;
	m_nPakgeId = 0;
	string sBody;
	sBody = WritePbReqMsg(&req, m_sGuid, InitConnectRequestMsgType);
	MsgHead msgHead;
	msgHead.msgType = EN_MSGTYPE_REQ;
	msgHead.serialNo = m_nPakgeId;
	char* pBuf = new char[MAX_BUFFER_SIZE];
	memset(pBuf, MAX_BUFFER_SIZE, 0);
	int nLen = MsgHandle::encodeMsg(pBuf, sBody, msgHead, m_sSecretKey);
	m_tcpClient.SendMsg(pBuf, nLen);
	if (pBuf)
		delete pBuf;

}

void CTradeApi::TradeLogin(TradeLoginRequest &req)
{
	string sBody;
	sBody = WritePbReqMsg(&req, m_sGuid, TradeLoginRequestMsgType);
	MsgHead msgHead;
	msgHead.msgType = EN_MSGTYPE_REQ;
	msgHead.serialNo = m_nPakgeId;
	char* pBuf = new char[MAX_BUFFER_SIZE];
	memset(pBuf, MAX_BUFFER_SIZE, 0);
	int nLen = MsgHandle::encodeMsg(pBuf, sBody, msgHead, m_sSecretKey);
	m_tcpClient.SendMsg(pBuf, nLen);
	if (pBuf)
		delete pBuf;

}
void CTradeApi::TradeLogout()
{
	string sBody;
	sBody = WritePbReqMsg(nullptr, m_sGuid, TradeLogoutRequestMsgType);
	MsgHead msgHead;
	msgHead.msgType = EN_MSGTYPE_REQ;
	msgHead.serialNo = m_nPakgeId;
	char* pBuf = new char[MAX_BUFFER_SIZE];
	memset(pBuf, MAX_BUFFER_SIZE, 0);
	int nLen = MsgHandle::encodeMsg(pBuf, sBody, msgHead, m_sSecretKey);
	m_tcpClient.SendMsg(pBuf, nLen);
	if (pBuf)
		delete pBuf;
}
void CTradeApi::TradeEntrust(TradeEntrustRequest &req)//委托接口
{
	string sBody;
	sBody = WritePbReqMsg(&req, m_sGuid, TradeEntrustRequestMsgType);
	TradeCommonReq(sBody);
}
void CTradeApi::TradeChangeEntrust(TradeChangeEntrustRequest &req)//改单接口
{
	string sBody;
	sBody = WritePbReqMsg(&req, m_sGuid, TradeChangeEntrustRequestMsgType);
	TradeCommonReq(sBody);
}
void CTradeApi::TradeCancelEntrust(TradeCancelEntrustRequest &req)//撤单接口
{
	string sBody;
	sBody = WritePbReqMsg(&req, m_sGuid, TradeCancelEntrustRequestMsgType);
	TradeCommonReq(sBody);
}
void CTradeApi::TradeQueryHoldsList(TradeQueryHoldsListRequest &req)//查询持仓股票列表
{
	string sBody;
	sBody = WritePbReqMsg(&req, m_sGuid, TradeQueryHoldsListRequestMsgType);
	TradeCommonReq(sBody);
}
void CTradeApi::TradeQueryBuyAmount(TradeQueryBuyAmountRequest &req)//查询最大可买
{
	string sBody;
	sBody = WritePbReqMsg(&req, m_sGuid, TradeQueryBuyAmountRequestMsgType);
	TradeCommonReq(sBody);
}
void CTradeApi::TradeQuerySellAmount(TradeQuerySellAmountRequest &req)//查询最大可卖
{
	string sBody;
	sBody = WritePbReqMsg(&req, m_sGuid, TradeQuerySellAmountRequestMsgType);
	TradeCommonReq(sBody);
}
void CTradeApi::TradeQueryMarginFundInfo(TradeQueryMarginFundInfoRequest &req)//查询客户资金信息
{
	string sBody;
	sBody = WritePbReqMsg(&req, m_sGuid, TradeQueryMarginFundInfoRequestMsgType);
	TradeCommonReq(sBody);
}
void CTradeApi::TradeQueryRealEntrustList(TradeQueryRealEntrustListRequest &req)//查询客户当日委托信息
{
	string sBody;
	sBody = WritePbReqMsg(&req, m_sGuid, TradeQueryRealEntrustListRequestMsgType);
	TradeCommonReq(sBody);
}
void CTradeApi::TradeQueryHistoryEntrust(TradeQueryHistoryEntrustListRequest &req)//查询客户历史委托信息
{
	string sBody;
	sBody = WritePbReqMsg(&req, m_sGuid, TradeQueryHistoryEntrustListRequestMsgType);
	TradeCommonReq(sBody);
}
void CTradeApi::TradeQueryRealDeliverList(TradeQueryRealDeliverListRequest &req)//查询客户当日成交信息
{
	string sBody;
	sBody = WritePbReqMsg(&req, m_sGuid, TradeQueryRealDeliverListRequestMsgType);
	TradeCommonReq(sBody);
}
void CTradeApi::TradeQueryHistoryDeliverList(TradeQueryHistoryDeliverListRequest &req)//查询客户历史成交信息
{
	string sBody;
	sBody = WritePbReqMsg(&req, m_sGuid, TradeQueryHistoryDeliverListRequestMsgType);
	TradeCommonReq(sBody);
}
void CTradeApi::TradeQueryRealFundJourList(TradeQueryRealFundJourListRequest &req)//查询客户当日资金流水
{
	string sBody;
	sBody = WritePbReqMsg(&req, m_sGuid, TradeQueryRealFundJourListRequestMsgType);
	TradeCommonReq(sBody);
}
void CTradeApi::TradeQueryHistoryFundJourList(TradeQueryHistoryFundJourListRequest &req)//查询客户历史资金流水
{
	string sBody;
	sBody = WritePbReqMsg(&req, m_sGuid, TradeQueryHistoryFundJourListRequestMsgType);
	TradeCommonReq(sBody);
}
void CTradeApi::TradeSubscribe()//订阅交易推送
{
	string sBody;
	sBody = WritePbReqMsg(nullptr, m_sGuid, TradeSubscribeRequestMsgType);
	TradeCommonReq(sBody);
}
void CTradeApi::TradeUnsubscribe()//取消订阅交易推送
{
	string sBody;
	sBody = WritePbReqMsg(nullptr, m_sGuid, TradeUnsubscribeRequestMsgType);
	TradeCommonReq(sBody);
}
//////////////////////////////////////////////Test
void CTradeApi::testHeartBeat()
{
	MsgHead msgHead;
	msgHead.msgType = EN_MSGTYPE_HEARTBEAT;
	msgHead.serialNo = 0;
	msgHead.bodyLen = 0;
	char* pBuf = new char[HEAD_LEN];
	MsgHandle::writeHeadMsg(pBuf, msgHead);
	int nLen1 = strlen(pBuf);
	int nLen2 = sizeof(*pBuf);
	m_tcpClient.SendMsg(pBuf, HEAD_LEN);
	if (pBuf)
		delete pBuf;
	cout << "send heartbeat" << endl;
}
void CTradeApi::testTradeInitConnect()
{
	InitConnectReq req;
	req.set_deviceno(DEVICE_NO);
	TradeInitConnect(req);
}
void CTradeApi::testTradeLogin()
{
	TradeLoginRequest req;
	string sPwd= onEncryptedMsgRSABase64(USER_PWD_TRADE);
	req.set_password(sPwd);
	TradeLogin(req);
}
void CTradeApi::testTradeLogout()
{
	TradeLogout();
}
void CTradeApi::testTradeEntrust()//委托接口
{
	TradeEntrustRequest req;
	req.set_exchangetype("K");//'K'港股、'P'美股、'v'深股通、't'泸股通
	req.set_stockcode("00700");
	req.set_entrustamount("200");
	req.set_entrustprice("352.8");
	req.set_entrustbs("1");//'1'多头开仓、'2'多头平仓、'3'空头平仓、'4'空头开仓
	req.set_entrusttype("2");//港股：'0'竞价限价、'1'竞价、'2'增强限价盘、'3'限价盘、'4'特别限价盘、'6'暗盘。美股：'3'限价盘、'5'市价盘。A股：'3'限价盘。
	req.set_clienttype(0);//'0'internet
	TradeEntrust(req);
}
void CTradeApi::testTradeChangeEntrust()//改单接口
{
	string sId;
	cout << "输入委托Id:";
	cin >> sId;
	TradeChangeEntrustRequest req;
	req.set_exchangetype("K");//'K'港股、'P'美股、'v'深股通、't'泸股通
	req.set_stockcode("00700");
	req.set_entrustamount("100");//修改后的委托数量
	req.set_entrustprice("345.3");//修改后的委托价格
	req.set_entrustid(sId);//原始委托编号
	TradeChangeEntrust(req);
}
void CTradeApi::testTradeCancelEntrust()//撤单接口
{
	string sId;
	cout << "输入委托Id:";
	cin >> sId;
	TradeCancelEntrustRequest req;
	req.set_exchangetype("K");//'K'港股、'P'美股、'v'深股通、't'泸股通
	req.set_stockcode("00700");
	req.set_entrustamount("100");
	req.set_entrustprice("356.8");
	req.set_entrustid(sId);
	TradeCancelEntrust(req);
}
void CTradeApi::testTradeQueryHoldsList()//查询持仓股票列表
{
	TradeQueryHoldsListRequest req;
	req.set_exchangetype("K");//'K'港股、'P'美股、'v'深股通、't'泸股通
	TradeQueryHoldsList(req);
}
void CTradeApi::testTradeQueryBuyAmount()//查询最大可买
{
	TradeQueryBuyAmountRequest req;
	req.set_exchangetype("K");//'K'港股、'P'美股、'v'深股通、't'泸股通
	req.set_stockcode("00700");
	req.set_entrustprice("356.8");
	//req.set_querytype("356.8");//'0'默认、'1'Margin
	req.set_clienttype(0);//'0'internet
	TradeQueryBuyAmount(req);
}
void CTradeApi::testTradeQuerySellAmount()//查询最大可卖
{
	TradeQuerySellAmountRequest req;
	req.set_exchangetype("K");//'K'港股、'P'美股、'v'深股通、't'泸股通
	req.set_stockcode("00700");
	req.set_clienttype(0);//'0'internet
	TradeQuerySellAmount(req);
}
void CTradeApi::testTradeQueryMarginFundInfo()//查询客户资金信息
{
	TradeQueryMarginFundInfoRequest req;
	req.set_exchangetype("K");//'K'港股、'P'美股、'v'深股通、't'泸股通
	TradeQueryMarginFundInfo(req);
}
void CTradeApi::testTradeQueryRealEntrustList()//查询客户当日委托信息
{
	TradeQueryRealEntrustListRequest req;
	req.set_exchangetype("K");//'K'港股、'P'美股、'v'深股通、't'泸股通
	req.set_querycount(20);
	req.set_queryparamstr("0");//
	TradeQueryRealEntrustList(req);
}
void CTradeApi::testTradeQueryHistoryEntrust()//查询客户历史委托信息
{
	TradeQueryHistoryEntrustListRequest req;
	req.set_exchangetype("K");//'K'港股、'P'美股、'v'深股通、't'泸股通
	req.set_querycount(20);
	req.set_queryparamstr("0");//
	req.set_startdate("20200801");
	req.set_enddate("20200901");
	TradeQueryHistoryEntrust(req);
}
void CTradeApi::testTradeQueryRealDeliverList()//查询客户当日成交信息
{
	TradeQueryRealDeliverListRequest req;
	req.set_exchangetype("K");//'K'港股、'P'美股、'v'深股通、't'泸股通
	req.set_querycount(20);
	req.set_queryparamstr("0");//
	TradeQueryRealDeliverList(req);
}
void CTradeApi::testTradeQueryHistoryDeliverList()//查询客户历史成交信息
{
	TradeQueryHistoryDeliverListRequest req;
	req.set_exchangetype("K");//'K'港股、'P'美股、'v'深股通、't'泸股通
	req.set_querycount(20);
	req.set_queryparamstr("0");//
	req.set_startdate("20200801");
	req.set_enddate("20200901");
	TradeQueryHistoryDeliverList(req);
}
void CTradeApi::testTradeQueryRealFundJourList()//查询客户当日资金流水
{
	TradeQueryRealFundJourListRequest req;
	req.set_exchangetype("K");//'K'港股、'P'美股、'v'深股通、't'泸股通
	req.set_querycount(20);
	req.set_queryparamstr("0");//
	TradeQueryRealFundJourList(req);
}
void CTradeApi::testTradeQueryHistoryFundJourList()//查询客户历史资金流水
{
	TradeQueryHistoryFundJourListRequest req;
	req.set_exchangetype("K");//'K'港股、'P'美股、'v'深股通、't'泸股通
	req.set_querycount(20);
	req.set_queryparamstr("0");//
	req.set_startdate(20200801);
	req.set_enddate(20200901);
	TradeQueryHistoryFundJourList(req);
}
void CTradeApi::testTradeSubscribe()//订阅交易推送
{
	TradeSubscribe();
}
void CTradeApi::testTradeUnsubscribe()//取消订阅交易推送
{

	TradeUnsubscribe();
}

//=======================期货test================
string sCodeFutures = "CUSH2.HK";
void CTradeApi::testTradeEntrustFuture()//委托接口
{
	FuturesEntrustRequest req;
	req.set_stockcode(sCodeFutures);//ZFZ1 HSIM0.HK CUSH2.HK
	req.set_entrustamount("1");
	req.set_entrustprice("5.3983");
	req.set_entrustbs("1");//'1'多头开仓、'2'多头平仓、'3'空头平仓、'4'空头开仓
	req.set_entrusttype("0");// 0 限价单、1 竞价单、2 市价单、3 条件单
	req.set_validtimetype("0");// 0 即日有效、1 成交并取消、2 全额或取消、3 到期日有效、4 指定日期有效
	req.set_validtime("20211230");//当validTimeType==4 必填yyyyMMdd
	req.set_orderoptions("0");////0:默认 1:T+1
	TradeEntrustFuture(req);
}
void CTradeApi::testTradeChangeEntrustFuture()//改单接口
{
	string sId;
	cout << "输入委托Id:";
	cin >> sId;
	FuturesModifyEntrustRequest req;
	req.set_entrustid(sId);
	req.set_stockcode(sCodeFutures);//ZFZ1 HSIM0.HK
	req.set_entrustamount("2");
	req.set_entrustprice("6.3842");
	req.set_entrustbs("1");//'1'多头开仓、'2'多头平仓、'3'空头平仓、'4'空头开仓
	req.set_validtimetype("0");// 0 即日有效、1 成交并取消、2 全额或取消、3 到期日有效、4 指定日期有效
	//req.set_validtime("20211230");//当validTimeType==4 必填yyyyMMdd
	//req.set_orderoptions("0");////0:默认 1:T+1
	TradeChangeEntrustFuture(req);
}
void CTradeApi::testTradeCancelEntrustFuture()//撤单接口
{
	string sId,sCode;
	cout << "输入委托Id:";
	cin >> sId;
	FuturesCancelEntrustRequest req;
	req.set_stockcode(sCodeFutures);
	req.set_entrustid(sId);
	TradeCancelEntrustFuture(req);
}
void CTradeApi::testTradeQueryHoldsListFuture()//查询持仓股票列表
{
	FuturesQueryHoldsListRequest req;
	TradeQueryHoldsListFuture(req);
}
void CTradeApi::testTradeQueryBuySellAmountFuture()//查询最大可买
{
	FuturesQueryMaxBuySellAmountRequest req;
	req.set_stockcode(sCodeFutures);
	TradeQueryBuySellAmountFuture(req);
}

void CTradeApi::testTradeQueryMarginFundInfoFuture()//查询客户资金信息
{
	FuturesQueryFundInfoRequest req;
	TradeQueryMarginFundInfoFuture(req);
}
void CTradeApi::testTradeQueryRealEntrustListFuture()//查询客户当日委托信息
{
	FuturesQueryRealEntrustListRequest req;
	TradeQueryRealEntrustListFuture(req);
}
void CTradeApi::testTradeQueryHistoryEntrustFuture()//查询客户历史委托信息
{
	FuturesQueryHistoryEntrustListRequest req;
	req.set_pagesize(20);
	req.set_pageno(1);//
	req.set_startdate("202101201");
	req.set_enddate("20220130");
	TradeQueryHistoryEntrustFuture(req);
}
void CTradeApi::testTradeQueryRealDeliverListFuture()//查询客户当日成交信息
{
	FuturesQueryRealDeliverListRequest req;
	TradeQueryRealDeliverListFuture(req);
}
void CTradeApi::testTradeQueryHistoryDeliverListFuture()//查询客户历史成交信息
{
	FuturesQueryHistoryDeliverListRequest req;
	req.set_pagesize(20);
	req.set_pageno(1);//
	req.set_startdate("202101201");
	req.set_enddate("20220130");
	TradeQueryHistoryDeliverListFuture(req);
}

//=======================期货API=============
void CTradeApi::TradeEntrustFuture(FuturesEntrustRequest &req)//委托接口
{
	string sBody;
	sBody = WritePbReqMsg(&req, m_sGuid, FuturesEntrustRequestMsgType);
	TradeCommonReq(sBody);
}
void CTradeApi::TradeChangeEntrustFuture(FuturesModifyEntrustRequest &req)//改单接口
{
	string sBody;
	sBody = WritePbReqMsg(&req, m_sGuid, FuturesModifyEntrustRequestMsgType);
	TradeCommonReq(sBody);
}
void CTradeApi::TradeCancelEntrustFuture(FuturesCancelEntrustRequest &req)//撤单接口
{
	string sBody;
	sBody = WritePbReqMsg(&req, m_sGuid, FuturesCancelEntrustRequestMsgType);
	TradeCommonReq(sBody);
}
void CTradeApi::TradeQueryHoldsListFuture(FuturesQueryHoldsListRequest &req)//查询持仓股票列表
{
	string sBody;
	sBody = WritePbReqMsg(&req, m_sGuid, FuturesQueryHoldsListRequestMsgType);
	TradeCommonReq(sBody);
}
void CTradeApi::TradeQueryBuySellAmountFuture(FuturesQueryMaxBuySellAmountRequest &req)//查询最大可买
{
	string sBody;
	sBody = WritePbReqMsg(&req, m_sGuid, FuturesQueryMaxBuySellAmountRequestMsgType);
	TradeCommonReq(sBody);
}
void CTradeApi::TradeQueryMarginFundInfoFuture(FuturesQueryFundInfoRequest &req)//查询客户资金信息
{
	string sBody;
	sBody = WritePbReqMsg(&req, m_sGuid, FuturesQueryFundInfoRequestMsgType);
	TradeCommonReq(sBody);
}
void CTradeApi::TradeQueryRealEntrustListFuture(FuturesQueryRealEntrustListRequest &req)//查询客户当日委托信息
{
	string sBody;
	sBody = WritePbReqMsg(&req, m_sGuid, FuturesQueryRealEntrustListRequestMsgType);
	TradeCommonReq(sBody);
}
void CTradeApi::TradeQueryHistoryEntrustFuture(FuturesQueryHistoryEntrustListRequest &req)//查询客户历史委托信息
{
	string sBody;
	sBody = WritePbReqMsg(&req, m_sGuid, FuturesQueryHistoryEntrustListRequestMsgType);
	TradeCommonReq(sBody);
}
void CTradeApi::TradeQueryRealDeliverListFuture(FuturesQueryRealDeliverListRequest &req)//查询客户当日成交信息
{
	string sBody;
	sBody = WritePbReqMsg(&req, m_sGuid, FuturesQueryRealDeliverListRequestMsgType);
	TradeCommonReq(sBody);
}
void CTradeApi::TradeQueryHistoryDeliverListFuture(FuturesQueryHistoryDeliverListRequest &req)//查询客户历史成交信息
{
	string sBody;
	sBody = WritePbReqMsg(&req, m_sGuid, FuturesQueryHistoryDeliverListRequestMsgType);
	TradeCommonReq(sBody);
}

//=======================期货================
void CTradeApi::HandleStockQueryHoldsListResponseFuture(const PBResponse &pbResp)
{
	cout << "HandleStockQueryHoldsListResponseFuture(期货查询持仓股票列表)" << endl;
	FuturesQueryHoldsListResponse resp;
	pbResp.payload().UnpackTo(&resp);
	int nSize = resp.holdslist_size();
	cout << "持仓条数:" << nSize << endl;
	for (int i = 0; i < nSize; i++)
	{
		FuturesHoldsVo *pItem = resp.mutable_holdslist(i);
		string stockCode = pItem->stockcode();
		string stockName = CCommon::UTF8_To_CString(pItem->stockname());
		string lastDayQty = pItem->lastdayqty();// 上日持仓数量
		string lastDayPrice = pItem->lastdayprice();// 上日持仓成本
		string depQty = pItem->depqty();// 存储仓位
		string dayLongQty = pItem->daylongqty();// 今日长仓数量
		string dayLongPrice = pItem->daylongprice();// 今日长仓均价
		string dayShortQty = pItem->dayshortqty();// 今日短仓数量
		string dayShortPrice = pItem->dayshortprice();// 今日短仓均价
		string dayNetQty = pItem->daynetqty();//  今日净仓数量
		string dayNetPrice = pItem->daynetprice();//  今日净仓均价
		string currentQty = pItem->currentqty();//持仓 上日持仓数量 ＋ 今日净仓数量 ＝ 净仓数量
		string costPrice = pItem->costprice(); // 成本价
		string lastPrice = pItem->lastprice();// 现价
		string preClosePrice = pItem->precloseprice(); // 昨收价
		string profitLoss = pItem->profitloss();// 盈亏
		string ccyRate = pItem->ccyrate();// 参考兑换率
		string contractValue = pItem->contractvalue();// 合约值
		string profitLossBaseCcy = pItem->profitlossbaseccy(); // 盈亏(基本货币)
		string dataType = pItem->datatype(); //期货类型
		string ccy = pItem->ccy();//产品系列的交易币种
		string closeProfit = pItem->closeprofit();// 已实现盈亏
		string closeProfitHKD = pItem->closeprofithkd();// 已实现盈亏(HKD)

		cout << "index:" << i << "\t stockCode:" << stockCode << "\t stockName:" << stockName << "\t currentQty:" << currentQty << "\t costPrice:" << costPrice << "\t profitLoss:" << profitLoss << "\t closeProfit:" << closeProfit << endl;
	}
}
void CTradeApi::HandleTradeQueryMarginFundInfoResponseFuture(const PBResponse &pbResp)
{
	cout << "HandleTradeQueryMarginFundInfoResponseFuture(期货查询客户资金信息)" << endl;
	FuturesQueryFundInfoResponse resp;
	pbResp.payload().UnpackTo(&resp);
	FuturesFundInfoVo *pItem = resp.mutable_fundinfo();
	string assetBalance = pItem->assetbalance();// 资产净值
	string enableBalance = pItem->enablebalance();//可用金额(购买力)
	string marginCall = pItem->margincall();//追缴保证金
	string incomeBalance = pItem->incomebalance();//持仓盈亏
	string cashBal = pItem->cashbal();// 现金结余
	string iMargin = pItem->imargin();// 基本保证金
	string mMargin = pItem->mmargin();// 维持保证金
	string marginLevel = pItem->marginlevel();// 保证金水平
	string maxMargin = pItem->maxmargin();// 最高保证金
	string creditLimit = pItem->creditlimit();//  信贷限额
	string ctrlLevel = pItem->ctrllevel();// 控制级数
	string marginClass = pItem->marginclass();// 保证金类型
	string aeId = pItem->aeid();// 经纪
	string cashBalHKD = pItem->cashbalhkd();// 港币现金结余
	string cashBalUSD = pItem->cashbalusd();// 美元现金结余
	string cycRateUSDtoHSD = pItem->cycrateusdtohsd();// 美元兑港币汇率
	string marginStatus = pItem->marginstatus();// 风险状态  //1:安全 2:预警 3：危险 4：平仓
	string statusPercent = pItem->statuspercent();//风险状态画图百分比
	string closeProfit = pItem->closeprofit();//已实现盈亏
	string cashBalCNH = pItem->cashbalcnh();//人民币现金结余

	cout << "assetBalance:" << assetBalance << "\t enableBalance:" << enableBalance << "\t marginCall:" << marginCall << "\t incomeBalance:" << incomeBalance << "\t cashBal:" << cashBal << "\t closeProfit:" << closeProfit << "\t marginStatus:" << marginStatus << endl;
}
void CTradeApi::HandleTradeQueryRealEntrustListResponseFuture(const PBResponse &pbResp)
{
	cout << "HandleTradeQueryRealEntrustListResponseFuture(期货查询客户当日委托信息)" << endl;
	FuturesQueryRealEntrustListResponse resp;
	pbResp.payload().UnpackTo(&resp);
	int nSize = resp.data_size();
	cout << "委托条数:" << nSize << endl;
	for (int i = 0; i < nSize; i++)
	{
		FuturesOrderVo *pItem = resp.mutable_data(i);
		string stockCode = pItem->stockcode();
		string stockName = CCommon::UTF8_To_CString(pItem->stockname());
		string entrustPrice = pItem->entrustprice();
		string entrustAmount = pItem->entrustamount();
		string entrustBs = pItem->entrustbs();
		string date = pItem->date();
		string status = pItem->status();//0:未报 1:待报 2:已报 3:已报待撤 4:部成待撤 5:部分撤销 6:已撤销 7:部分成交 8:已成交 9:废单 
		string entrustId = pItem->entrustid();
		int canBeCanceled = pItem->canbecanceled();//可撤单  1 可撤单， 0 不可撤单
		int canBeUpdated = pItem->canbeupdated();// 是否可改单 1 可改单，0 不可改单
		cout << "index:" << i << "\t stockCode:" << stockCode << "\t stockName:" << stockName << "\t entrustPrice:" << entrustPrice << "\t entrustAmount:" << entrustAmount << "\t entrustBs:" << entrustBs << "\t date:" << date << "\t status:" << status << "\t entrustId:" << entrustId << endl;
	}
}
void CTradeApi::HandleTradeQueryHistoryEntrustListResponseFuture(const PBResponse &pbResp)
{
	cout << "HandleTradeQueryHistoryEntrustListResponseFuture(期货查询客户历史委托信息)" << endl;
	FuturesQueryHistoryEntrustListResponse resp;
	pbResp.payload().UnpackTo(&resp);
	int nSize = resp.data_size();
	cout << "委托条数:" << nSize << endl;
	for (int i = 0; i < nSize; i++)
	{
		FuturesOrderVo *pItem = resp.mutable_data(i);
		string stockCode = pItem->stockcode();
		string stockName = CCommon::UTF8_To_CString(pItem->stockname());
		string entrustPrice = pItem->entrustprice();
		string entrustAmount = pItem->entrustamount();
		string entrustBs = pItem->entrustbs();
		string date = pItem->date();
		string status = pItem->status();
		string entrustId = pItem->entrustid();
		int canBeCanceled = pItem->canbecanceled();//可撤单  1 可撤单， 0 不可撤单
		int canBeUpdated = pItem->canbeupdated();// 是否可改单 1 可改单，0 不可改单
		cout << "index:" << i << "\t stockCode:" << stockCode << "\t stockName:" << stockName << "\t entrustPrice:" << entrustPrice << "\t entrustAmount:" << entrustAmount << "\t entrustBs:" << entrustBs << "\t date:" << date << "\t status:" << status << "\t entrustId:" << entrustId << endl;
	}
}
void CTradeApi::HandleTradeQueryRealDeliverListResponseFuture(const PBResponse &pbResp)
{
	cout << "HandleTradeQueryRealDeliverListResponseFuture(期货查询客户当日成交信息)" << endl;
	FuturesQueryRealDeliverListResponse resp;
	pbResp.payload().UnpackTo(&resp);
	int nSize = resp.data_size();
	cout << "成交条数:" << nSize << endl;
	for (int i = 0; i < nSize; i++)
	{
		FuturesOrderVo *pItem = resp.mutable_data(i);
		string stockCode = pItem->stockcode();
		string stockName = CCommon::UTF8_To_CString(pItem->stockname());
		string entrustPrice = pItem->entrustprice();
		string entrustAmount = pItem->entrustamount();
		string entrustBs = pItem->entrustbs();
		string date = pItem->date();
		string status = pItem->status();
		string entrustId = pItem->entrustid();
		int canBeCanceled = pItem->canbecanceled();//可撤单  1 可撤单， 0 不可撤单
		int canBeUpdated = pItem->canbeupdated();// 是否可改单 1 可改单，0 不可改单
		cout << "index:" << i << "\t stockCode:" << stockCode << "\t stockName:" << stockName << "\t entrustPrice:" << entrustPrice << "\t entrustAmount:" << entrustAmount << "\t entrustBs:" << entrustBs << "\t date:" << date << "\t status:" << status << "\t entrustId:" << entrustId << endl;
	}
}
void CTradeApi::HandleTradeQueryHistoryDeliverListResponseFuture(const PBResponse &pbResp)
{
	cout << "HandleTradeQueryHistoryDeliverListResponseFuture(期货查询客户历史成交信息)" << endl;
	FuturesQueryHistoryEntrustListResponse resp;
	pbResp.payload().UnpackTo(&resp);
	int nSize = resp.data_size();
	cout << "成交条数:" << nSize << endl;
	for (int i = 0; i < nSize; i++)
	{
		FuturesOrderVo *pItem = resp.mutable_data(i);
		string stockCode = pItem->stockcode();
		string stockName = CCommon::UTF8_To_CString(pItem->stockname());
		string entrustPrice = pItem->entrustprice();
		string entrustAmount = pItem->entrustamount();
		string entrustBs = pItem->entrustbs();
		string date = pItem->date();
		string status = pItem->status();
		string entrustId = pItem->entrustid();
		int canBeCanceled = pItem->canbecanceled();//可撤单  1 可撤单， 0 不可撤单
		int canBeUpdated = pItem->canbeupdated();// 是否可改单 1 可改单，0 不可改单
		cout <<"index:"<< i << "\tstockCode:" << stockCode << "\t stockName:" << stockName << "\t entrustPrice:" << entrustPrice << "\t entrustAmount:" << entrustAmount << "\t entrustBs:" << entrustBs << "\t date:" << date << "\t status:" << status << "\t entrustId:" << entrustId << endl;
	}
}
void CTradeApi::HandleQueryBuySellAmountResponseFuture(const PBResponse &pbResp)
{
	cout << "HandleQueryBuySellAmountResponseFuture(期货查询最大可买可卖)" << endl;
	FuturesQueryBuySellAmountResponse resp;
	pbResp.payload().UnpackTo(&resp);
	INT32 positionStatus = resp.positionstatus();//持仓头寸状态：0未建仓，1正仓，2负仓
	INT64 maxbuyamount = resp.maxbuyamount();//最大可买
	INT64 maxsellamount = resp.maxsellamount();//最大可卖
	string initialmargin = resp.initialmargin();//开仓按金
	string ccy = resp.ccy();//币种
	cout << "positionStatus:" << positionStatus << "\t maxbuyamount:" << maxbuyamount << "\t maxsellamount:" << maxsellamount << "\t initialmargin:" << initialmargin << "\t ccy:" << ccy<< endl;
}

