期货homes平台以及仿ctp接口
实盘账户或者模拟账户可以下挂多个子账户
子账户也可以是homes母账户,理论上可以一层一层套下去。
所有交易细节全部保存,收盘定时结算。
功能很强大,并且还有很多拓展空间。
连接homes平台,需要用到仿ctp交易接口,声明和ctp一模一样,贴上核心代码:
#pragma once #include <ascs/ext/tcp.h> #include <ascs/tcp/client_socket.h> #include <ascs/service_pump.h> #include "ThostFtdcUserApiStruct.h" #include <queue> #include <fstream> #include "../FutureHomes/UtilityFunctions.h" using namespace ascs::tcp; //消息最小长度:body=0 #define REQ_MSG_MIN_SIZE 20 #define RSP_MSG_MIN_SIZE 12 //消息头/尾 #define MSG_HEAD (char)0xDA #define MSG_END (char)0xDF enum enumRspMsgType { OnFrontConnected = 0x01, OnFrontDisconnected, OnHeartBeatWarning, OnRspAuthenticate, OnRspUserLogin, OnRspUserLogout, OnRspUserPasswordUpdate, OnRspTradingAccountPasswordUpdate, OnRspOrderInsert, OnRspParkedOrderInsert, OnRspParkedOrderAction, OnRspOrderAction, OnRspQueryMaxOrderVolume, OnRspSettlementInfoConfirm, OnRspRemoveParkedOrder, OnRspRemoveParkedOrderAction, OnRspQryOrder, OnRspQryTrade, OnRspQryInvestorPosition, OnRspQryTradingAccount, OnRspQryInvestor, OnRspQryTradingCode, OnRspQryInstrumentMarginRate, OnRspQryInstrumentCommissionRate, OnRspQryExchange, OnRspQryInstrument, OnRspQryDepthMarketData, OnRspQrySettlementInfo, OnRspQryTransferBank, OnRspQryInvestorPositionDetail, OnRspQryNotice, OnRspQrySettlementInfoConfirm, OnRspQryInvestorPositionCombineDetail, OnRspQryCFMMCTradingAccountKey, OnRspQryEWarrantOffset, OnRspQryInvestorProductGroupMargin, OnRspQryExchangeMarginRate, OnRspQryExchangeMarginRateAdjust, OnRspQryTransferSerial, OnRspQryAccountregister, OnRspError, OnRtnOrder, OnRtnTrade, OnErrRtnOrderInsert, OnErrRtnOrderAction, OnRtnInstrumentStatus, OnRtnTradingNotice, OnRtnErrorConditionalOrder, OnRspQryContractBank, OnRspQryParkedOrder, OnRspQryParkedOrderAction, OnRspQryTradingNotice, OnRspQryBrokerTradingParams, OnRspQryBrokerTradingAlgos, OnRtnFromBankToFutureByBank, OnRtnFromFutureToBankByBank, OnRtnRepealFromBankToFutureByBank, OnRtnRepealFromFutureToBankByBank, OnRtnFromBankToFutureByFuture, OnRtnFromFutureToBankByFuture, OnRtnRepealFromBankToFutureByFutureManual, OnRtnRepealFromFutureToBankByFutureManual, OnRtnQueryBankBalanceByFuture, OnErrRtnBankToFutureByFuture, OnErrRtnFutureToBankByFuture, OnErrRtnRepealBankToFutureByFutureManual, OnErrRtnRepealFutureToBankByFutureManual, OnErrRtnQueryBankBalanceByFuture, OnRtnRepealFromBankToFutureByFuture, OnRtnRepealFromFutureToBankByFuture, OnRspFromBankToFutureByFuture, OnRspFromFutureToBankByFuture, OnRspQueryBankAccountMoneyByFuture, OnRtnOpenAccountByBank, OnRtnCancelAccountByBank, OnRtnChangeAccountByBank, //v2 OnRspExecOrderInsert, OnRspExecOrderAction, OnRspForQuoteInsert, OnRspQuoteInsert, OnRspQuoteAction, OnRspBatchOrderAction, OnRspOptionSelfCloseInsert, OnRspOptionSelfCloseAction, OnRspCombActionInsert, OnRspQryProduct, OnRspQryExchangeRate, OnRspQrySecAgentACIDMap, OnRspQryProductExchRate, OnRspQryProductGroup, OnRspQryMMInstrumentCommissionRate, OnRspQryMMOptionInstrCommRate, OnRspQryInstrumentOrderCommRate, OnRspQrySecAgentTradingAccount, OnRspQrySecAgentCheckMode, OnRspQryOptionInstrTradeCost, OnRspQryOptionInstrCommRate, OnRspQryExecOrder, OnRspQryForQuote, OnRspQryQuote, OnRspQryOptionSelfClose, OnRspQryInvestUnit, OnRspQryCombInstrumentGuard, OnRspQryCombAction, OnRtnBulletin, OnRtnExecOrder, OnErrRtnExecOrderInsert, OnErrRtnExecOrderAction, OnErrRtnForQuoteInsert, OnRtnQuote, OnErrRtnQuoteInsert, OnErrRtnQuoteAction, OnRtnForQuoteRsp, OnRtnCFMMCTradingAccountToken, OnErrRtnBatchOrderAction, OnRtnOptionSelfClose, OnErrRtnOptionSelfCloseInsert, OnErrRtnOptionSelfCloseAction, OnRtnCombAction, OnErrRtnCombActionInsert, OnRspQueryCFMMCTradingAccountToken, OnGetTradingDay = 0xC8 }; class CThostFtdcTraderSpi; struct CThostFtdcReqUserLoginFieldEx { CThostFtdcReqUserLoginField field; THOST_TE_RESUME_TYPE publicTopic; //公有流 THOST_TE_RESUME_TYPE privateTopic; //私有流 }; #define MSG_UNWRAPPER(func,t1,length)\ assert(length == sizeof(t1)+sizeof(CThostFtdcRspInfoField)+4);\ t1 cmp;memset(&cmp, 0, sizeof(t1));\ auto pMain = memcmp(pBody, &cmp, sizeof(t1))==0 ? nullptr : (t1*)pBody;\ m_pSpi->func((t1*)pMain, (CThostFtdcRspInfoField*)(pBody + sizeof(t1)), *(int*)(pBody + sizeof(t1) + sizeof(CThostFtdcRspInfoField)), *(bool*)(pBody + sizeof(t1) + sizeof(CThostFtdcRspInfoField) + 4)); #define MSG_UNWRAPPER_0(func,t1,length)\ assert(length == sizeof(t1));\ m_pSpi->func((t1*)pBody) #define MSG_UNWRAPPER_1(func,t1,length)\ assert(length == sizeof(t1)+sizeof(CThostFtdcRspInfoField));\ m_pSpi->func((t1*)pBody, (CThostFtdcRspInfoField*)(pBody + sizeof(t1))) class my_client_socket : public client_socket_base<ASCS_DEFAULT_PACKER, ASCS_DEFAULT_UNPACKER> { public: my_client_socket(asio::io_context& s) : client_socket_base(s), m_pSpi(nullptr){} void set_spi_layer(CThostFtdcTraderSpi* p) { m_pSpi = p; } protected: virtual void on_connect() { ofs_order.open("./socket_rsp.txt", std::ios_base::app); } #if ASCS_VER > 10300 virtual bool on_msg_handle(out_msg_type& msg) #else virtual bool on_msg(out_msg_type& msg) #endif { m_strBuffer.append(msg.data(), msg.size()); parse_msg(); return true; } void parse_msg() { char chType; char* pBody; int nLength; bool bLast; //检测消息格式 while (check_msg(chType, &pBody, nLength, bLast)) { distribute(chType, pBody, nLength-RSP_MSG_MIN_SIZE, bLast); m_strBuffer = m_strBuffer.substr(nLength); } } //检测消息 bool check_msg(char& chType, char** ppBody, int& nLength, bool& bLast) { if (m_strBuffer[0] != MSG_HEAD) { int nPos = m_strBuffer.find(MSG_HEAD); if (nPos >= 0) m_strBuffer = m_strBuffer.substr(nPos); else return false; } //缓存大小 < MSG_MIN_SIZE,数据未接收全返回 if (m_strBuffer.size() < RSP_MSG_MIN_SIZE) return false; chType = m_strBuffer[1]; nLength = *(int*)(&m_strBuffer[2]); //消息长度 < MSG_MIN_SIZE,计算长度不对返回 if (nLength < RSP_MSG_MIN_SIZE && nLength>0) return false; //消息长度==0,错误数据返回 if (nLength == 0) { m_strBuffer = m_strBuffer.substr(2); return false; } //消息长度 < nLength,大消息未接收全返回 if (m_strBuffer.size() < nLength) return false; //消息尾不对,返回 if (m_strBuffer[nLength - 1] != MSG_END) { m_strBuffer = m_strBuffer.substr(nLength); return false; } *ppBody = &(m_strBuffer[6]); //nLength-1起向前推4+4+1个字符 bLast = m_strBuffer[nLength - 6]; unsigned int nIndex = *(unsigned int*)(&m_strBuffer[nLength - 5]); return true; } //派发消息 void distribute(char chType, char* pBody, int nLength, bool& bLast) { switch (chType) { case OnFrontConnected: { m_pSpi->OnFrontConnected(); break; } case OnFrontDisconnected: { m_pSpi->OnFrontDisconnected(*(int*)pBody); break; } case OnHeartBeatWarning: { m_pSpi->OnHeartBeatWarning(*(int*)pBody); break; } case OnRspAuthenticate: { MSG_UNWRAPPER(OnRspAuthenticate, CThostFtdcRspAuthenticateField, nLength); break; } case OnRspUserLogin: { MSG_UNWRAPPER(OnRspUserLogin, CThostFtdcRspUserLoginField, nLength); break; } case OnRspUserLogout: { MSG_UNWRAPPER(OnRspUserLogout, CThostFtdcUserLogoutField, nLength); break; } case OnRspUserPasswordUpdate: { MSG_UNWRAPPER(OnRspUserPasswordUpdate, CThostFtdcUserPasswordUpdateField, nLength); break; } case OnRspTradingAccountPasswordUpdate: { MSG_UNWRAPPER(OnRspTradingAccountPasswordUpdate, CThostFtdcTradingAccountPasswordUpdateField, nLength); break; } case OnRspOrderInsert: { MSG_UNWRAPPER(OnRspOrderInsert, CThostFtdcInputOrderField, nLength); break; } case OnRspParkedOrderInsert: { MSG_UNWRAPPER(OnRspParkedOrderInsert, CThostFtdcParkedOrderField, nLength); break; } case OnRspParkedOrderAction: { MSG_UNWRAPPER(OnRspParkedOrderAction, CThostFtdcParkedOrderActionField, nLength); break; } case OnRspOrderAction: { MSG_UNWRAPPER(OnRspOrderAction, CThostFtdcInputOrderActionField, nLength); break; } case OnRspQueryMaxOrderVolume: { MSG_UNWRAPPER(OnRspQueryMaxOrderVolume, CThostFtdcQueryMaxOrderVolumeField, nLength); break; } case OnRspSettlementInfoConfirm: { MSG_UNWRAPPER(OnRspSettlementInfoConfirm, CThostFtdcSettlementInfoConfirmField, nLength); break; } case OnRspRemoveParkedOrder: { MSG_UNWRAPPER(OnRspRemoveParkedOrder, CThostFtdcRemoveParkedOrderField, nLength); break; } case OnRspRemoveParkedOrderAction: { MSG_UNWRAPPER(OnRspRemoveParkedOrderAction, CThostFtdcRemoveParkedOrderActionField, nLength); break; } case OnRspQryOrder: { MSG_UNWRAPPER(OnRspQryOrder, CThostFtdcOrderField, nLength); break; } case OnRspQryTrade: { MSG_UNWRAPPER(OnRspQryTrade, CThostFtdcTradeField, nLength); break; } case OnRspQryInvestorPosition: { MSG_UNWRAPPER(OnRspQryInvestorPosition, CThostFtdcInvestorPositionField, nLength); break; } case OnRspQryTradingAccount: { MSG_UNWRAPPER(OnRspQryTradingAccount, CThostFtdcTradingAccountField, nLength); break; } case OnRspQryInvestor: { MSG_UNWRAPPER(OnRspQryInvestor, CThostFtdcInvestorField, nLength); break; } case OnRspQryTradingCode: { MSG_UNWRAPPER(OnRspQryTradingCode, CThostFtdcTradingCodeField, nLength); break; } case OnRspQryInstrumentMarginRate: { MSG_UNWRAPPER(OnRspQryInstrumentMarginRate, CThostFtdcInstrumentMarginRateField, nLength); break; } case OnRspQryInstrumentCommissionRate: { MSG_UNWRAPPER(OnRspQryInstrumentCommissionRate, CThostFtdcInstrumentCommissionRateField, nLength); break; } case OnRspQryExchange: { MSG_UNWRAPPER(OnRspQryExchange, CThostFtdcExchangeField, nLength); break; } case OnRspQryInstrument: { MSG_UNWRAPPER(OnRspQryInstrument, CThostFtdcInstrumentField, nLength); break; } case OnRspQryDepthMarketData: { MSG_UNWRAPPER(OnRspQryDepthMarketData, CThostFtdcDepthMarketDataField, nLength); break; } case OnRspQrySettlementInfo: { MSG_UNWRAPPER(OnRspQrySettlementInfo, CThostFtdcSettlementInfoField, nLength); break; } case OnRspQryTransferBank: { MSG_UNWRAPPER(OnRspQryTransferBank, CThostFtdcTransferBankField, nLength); break; } case OnRspQryInvestorPositionDetail: { MSG_UNWRAPPER(OnRspQryInvestorPositionDetail, CThostFtdcInvestorPositionDetailField, nLength); break; } case OnRspQryNotice: { MSG_UNWRAPPER(OnRspQryNotice, CThostFtdcNoticeField, nLength); break; } case OnRspQrySettlementInfoConfirm: { MSG_UNWRAPPER(OnRspQrySettlementInfoConfirm, CThostFtdcSettlementInfoConfirmField, nLength); break; } case OnRspQryInvestorPositionCombineDetail: { MSG_UNWRAPPER(OnRspQryInvestorPositionCombineDetail, CThostFtdcInvestorPositionCombineDetailField, nLength); break; } case OnRspQryCFMMCTradingAccountKey: { MSG_UNWRAPPER(OnRspQryCFMMCTradingAccountKey, CThostFtdcCFMMCTradingAccountKeyField, nLength); break; } case OnRspQryEWarrantOffset: { MSG_UNWRAPPER(OnRspQryEWarrantOffset, CThostFtdcEWarrantOffsetField, nLength); break; } case OnRspQryInvestorProductGroupMargin: { MSG_UNWRAPPER(OnRspQryInvestorProductGroupMargin, CThostFtdcInvestorProductGroupMarginField, nLength); break; } case OnRspQryExchangeMarginRate: { MSG_UNWRAPPER(OnRspQryExchangeMarginRate, CThostFtdcExchangeMarginRateField, nLength); break; } case OnRspQryExchangeMarginRateAdjust: { MSG_UNWRAPPER(OnRspQryExchangeMarginRateAdjust, CThostFtdcExchangeMarginRateAdjustField, nLength); break; } case OnRspQryTransferSerial: { MSG_UNWRAPPER(OnRspQryTransferSerial, CThostFtdcTransferSerialField, nLength); break; } case OnRspQryAccountregister: { MSG_UNWRAPPER(OnRspQryAccountregister, CThostFtdcAccountregisterField, nLength); break; } case OnRspError: { assert(nLength == sizeof(CThostFtdcRspInfoField) + sizeof(CThostFtdcRspInfoField) + 5); m_pSpi->OnRspError((CThostFtdcRspInfoField*)pBody, *(int*)(pBody + sizeof(CThostFtdcRspInfoField)), *(bool*)(pBody + sizeof(CThostFtdcRspInfoField) + 4)); break; } case OnRtnOrder: { MSG_UNWRAPPER_0(OnRtnOrder, CThostFtdcOrderField, nLength); ofs_order << "order" << ((CThostFtdcOrderField*)pBody)->OrderSysID << "," << ((CThostFtdcOrderField*)pBody)->InsertTime << std::endl; break; } case OnRtnTrade: { MSG_UNWRAPPER_0(OnRtnTrade, CThostFtdcTradeField, nLength); ofs_order << "trade" << ((CThostFtdcTradeField*)pBody)->OrderSysID << "," <<((CThostFtdcTradeField*)pBody)->TradeID << "," << ((CThostFtdcTradeField*)pBody)->TradeTime << std::endl; break; } case OnErrRtnOrderInsert: { MSG_UNWRAPPER_1(OnErrRtnOrderInsert, CThostFtdcInputOrderField, nLength); break; } case OnErrRtnOrderAction: { MSG_UNWRAPPER_1(OnErrRtnOrderAction, CThostFtdcOrderActionField, nLength); break; } case OnRtnInstrumentStatus: { MSG_UNWRAPPER_0(OnRtnInstrumentStatus, CThostFtdcInstrumentStatusField, nLength); break; } case OnRtnTradingNotice: { MSG_UNWRAPPER_0(OnRtnTradingNotice, CThostFtdcTradingNoticeInfoField, nLength); break; } case OnRtnErrorConditionalOrder: { MSG_UNWRAPPER_0(OnRtnErrorConditionalOrder, CThostFtdcErrorConditionalOrderField, nLength); break; } case OnRspQryContractBank: { MSG_UNWRAPPER(OnRspQryContractBank, CThostFtdcContractBankField, nLength); break; } case OnRspQryParkedOrder: { MSG_UNWRAPPER(OnRspQryParkedOrder, CThostFtdcParkedOrderField, nLength); break; } case OnRspQryParkedOrderAction: { MSG_UNWRAPPER(OnRspQryParkedOrderAction, CThostFtdcParkedOrderActionField, nLength); break; } case OnRspQryTradingNotice: { MSG_UNWRAPPER(OnRspQryTradingNotice, CThostFtdcTradingNoticeField, nLength); break; } case OnRspQryBrokerTradingParams: { MSG_UNWRAPPER(OnRspQryBrokerTradingParams, CThostFtdcBrokerTradingParamsField, nLength); break; } case OnRspQryBrokerTradingAlgos: { MSG_UNWRAPPER(OnRspQryBrokerTradingAlgos, CThostFtdcBrokerTradingAlgosField, nLength); break; } case OnRtnFromBankToFutureByBank: { MSG_UNWRAPPER_0(OnRtnFromBankToFutureByBank, CThostFtdcRspTransferField, nLength); break; } case OnRtnFromFutureToBankByBank: { MSG_UNWRAPPER_0(OnRtnFromFutureToBankByBank, CThostFtdcRspTransferField, nLength); break; } case OnRtnRepealFromBankToFutureByBank: { MSG_UNWRAPPER_0(OnRtnRepealFromBankToFutureByBank, CThostFtdcRspRepealField, nLength); break; } case OnRtnRepealFromFutureToBankByBank: { MSG_UNWRAPPER_0(OnRtnRepealFromFutureToBankByBank, CThostFtdcRspRepealField, nLength); break; } case OnRtnFromBankToFutureByFuture: { MSG_UNWRAPPER_0(OnRtnFromBankToFutureByFuture, CThostFtdcRspTransferField, nLength); break; } case OnRtnFromFutureToBankByFuture: { MSG_UNWRAPPER_0(OnRtnFromFutureToBankByFuture, CThostFtdcRspTransferField, nLength); break; } case OnRtnRepealFromBankToFutureByFutureManual: { MSG_UNWRAPPER_0(OnRtnRepealFromBankToFutureByFutureManual, CThostFtdcRspRepealField, nLength); break; } case OnRtnRepealFromFutureToBankByFutureManual: { MSG_UNWRAPPER_0(OnRtnRepealFromFutureToBankByFutureManual, CThostFtdcRspRepealField, nLength); break; } case OnRtnQueryBankBalanceByFuture: { MSG_UNWRAPPER_0(OnRtnQueryBankBalanceByFuture, CThostFtdcNotifyQueryAccountField, nLength); break; } case OnErrRtnBankToFutureByFuture: { MSG_UNWRAPPER_1(OnErrRtnBankToFutureByFuture, CThostFtdcReqTransferField, nLength); break; } case OnErrRtnFutureToBankByFuture: { MSG_UNWRAPPER_1(OnErrRtnFutureToBankByFuture, CThostFtdcReqTransferField, nLength); break; } case OnErrRtnRepealBankToFutureByFutureManual: { MSG_UNWRAPPER_1(OnErrRtnRepealBankToFutureByFutureManual, CThostFtdcReqRepealField, nLength); break; } case OnErrRtnRepealFutureToBankByFutureManual: { MSG_UNWRAPPER_1(OnErrRtnRepealFutureToBankByFutureManual, CThostFtdcReqRepealField, nLength); break; } case OnErrRtnQueryBankBalanceByFuture: { MSG_UNWRAPPER_1(OnErrRtnQueryBankBalanceByFuture, CThostFtdcReqQueryAccountField, nLength); break; } case OnRtnRepealFromBankToFutureByFuture: { MSG_UNWRAPPER_0(OnRtnRepealFromBankToFutureByFuture, CThostFtdcRspRepealField, nLength); break; } case OnRtnRepealFromFutureToBankByFuture: { MSG_UNWRAPPER_0(OnRtnRepealFromFutureToBankByFuture, CThostFtdcRspRepealField, nLength); break; } case OnRspFromBankToFutureByFuture: { MSG_UNWRAPPER(OnRspFromBankToFutureByFuture, CThostFtdcReqTransferField, nLength); break; } case OnRspFromFutureToBankByFuture: { MSG_UNWRAPPER(OnRspFromFutureToBankByFuture, CThostFtdcReqTransferField, nLength); break; } case OnRspQueryBankAccountMoneyByFuture: { MSG_UNWRAPPER(OnRspQueryBankAccountMoneyByFuture, CThostFtdcReqQueryAccountField, nLength); break; } case OnRtnOpenAccountByBank: { MSG_UNWRAPPER_0(OnRtnOpenAccountByBank, CThostFtdcOpenAccountField, nLength); break; } case OnRtnCancelAccountByBank: { MSG_UNWRAPPER_0(OnRtnCancelAccountByBank, CThostFtdcCancelAccountField, nLength); break; } case OnRtnChangeAccountByBank: { MSG_UNWRAPPER_0(OnRtnChangeAccountByBank, CThostFtdcChangeAccountField, nLength); break; } case OnRspQryProduct: { MSG_UNWRAPPER(OnRspQryProduct, CThostFtdcProductField, nLength); break; } case OnRspQueryCFMMCTradingAccountToken: { MSG_UNWRAPPER(OnRspQueryCFMMCTradingAccountToken, CThostFtdcQueryCFMMCTradingAccountTokenField, nLength); break; } } } private: CThostFtdcTraderSpi* m_pSpi; std::string m_strBuffer; int nMsgSize; char m_szPackMsg[2048]; std::ofstream ofs_order; }; typedef ascs::tcp::single_client_base <my_client_socket> my_single_client;