diff --git a/FakeAPI/FakeAPI.cpp b/FakeAPI/FakeAPI.cpp new file mode 100644 index 0000000..d4ebbe0 --- /dev/null +++ b/FakeAPI/FakeAPI.cpp @@ -0,0 +1,6 @@ +// FakeAPI.cpp : Defines the exported functions for the DLL application. +// + +#include "stdafx.h" + + diff --git a/FakeAPI/FakeAPI.vcxproj b/FakeAPI/FakeAPI.vcxproj new file mode 100644 index 0000000..076d12b --- /dev/null +++ b/FakeAPI/FakeAPI.vcxproj @@ -0,0 +1,107 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {358586C9-A4B8-43E4-8376-59C68F0F6211} + Win32Proj + FakeAPI + + + + DynamicLibrary + true + v120 + Unicode + + + DynamicLibrary + false + v120 + true + Unicode + + + + + + + + + + + + + true + D:\Program Files (x86)\simnow-快期交易新一代 + thosttraderapi + + + false + + + + Use + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;FAKEAPI_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + + + Windows + true + + + + + Level3 + Use + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;FAKEAPI_EXPORTS;%(PreprocessorDefinitions) + true + + + Windows + true + true + true + + + + + + + + + + + + false + + + false + + + + + + + Create + Create + + + + + + + \ No newline at end of file diff --git a/FakeAPI/FakeAPI.vcxproj.filters b/FakeAPI/FakeAPI.vcxproj.filters new file mode 100644 index 0000000..a060f3f --- /dev/null +++ b/FakeAPI/FakeAPI.vcxproj.filters @@ -0,0 +1,45 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/FakeAPI/ReadMe.txt b/FakeAPI/ReadMe.txt new file mode 100644 index 0000000..c9718a7 --- /dev/null +++ b/FakeAPI/ReadMe.txt @@ -0,0 +1,48 @@ +======================================================================== + DYNAMIC LINK LIBRARY : FakeAPI Project Overview +======================================================================== + +AppWizard has created this FakeAPI DLL for you. + +This file contains a summary of what you will find in each of the files that +make up your FakeAPI application. + + +FakeAPI.vcxproj + This is the main project file for VC++ projects generated using an Application Wizard. + It contains information about the version of Visual C++ that generated the file, and + information about the platforms, configurations, and project features selected with the + Application Wizard. + +FakeAPI.vcxproj.filters + This is the filters file for VC++ projects generated using an Application Wizard. + It contains information about the association between the files in your project + and the filters. This association is used in the IDE to show grouping of files with + similar extensions under a specific node (for e.g. ".cpp" files are associated with the + "Source Files" filter). + +FakeAPI.cpp + This is the main DLL source file. + + When created, this DLL does not export any symbols. As a result, it + will not produce a .lib file when it is built. If you wish this project + to be a project dependency of some other project, you will either need to + add code to export some symbols from the DLL so that an export library + will be produced, or you can set the Ignore Input Library property to Yes + on the General propert page of the Linker folder in the project's Property + Pages dialog box. + +///////////////////////////////////////////////////////////////////////////// +Other standard files: + +StdAfx.h, StdAfx.cpp + These files are used to build a precompiled header (PCH) file + named FakeAPI.pch and a precompiled types file named StdAfx.obj. + +///////////////////////////////////////////////////////////////////////////// +Other notes: + +AppWizard uses "TODO:" comments to indicate parts of the source code you +should add to or customize. + +///////////////////////////////////////////////////////////////////////////// diff --git a/FakeAPI/SecurityFtdcTraderApi.cpp b/FakeAPI/SecurityFtdcTraderApi.cpp new file mode 100644 index 0000000..6839b57 --- /dev/null +++ b/FakeAPI/SecurityFtdcTraderApi.cpp @@ -0,0 +1,143 @@ +#include "stdafx.h" + +#define ISLIB +#define LIB_TRADER_API_EXPORT + +#include +#include "../include/LTS_v2/SecurityFtdcTraderApi.h" + + +class MyClassLTS :public CSecurityFtdcTraderApi +{ + +public: + ///TraderApi + ///@param pszFlowPath ϢļĿ¼ĬΪǰĿ¼ + ///@return UserApi + static CSecurityFtdcTraderApi *CreateFtdcTraderApi(const char *pszFlowPath = ""); + + ///ɾӿڶ + ///@remark ʹñӿڶʱ,øúɾӿڶ + virtual void Release(){} + + ///ʼ + ///@remark ʼл,ֻеú,ӿڲſʼ + virtual void Init() + { + m_pSpi->OnFrontConnected(); + } + + ///ȴӿ߳̽ + ///@return ߳˳ + virtual int Join(){ return 0; } + + ///ȡǰ + ///@retrun ȡĽ + ///@remark ֻе¼ɹ,ܵõȷĽ + virtual const char *GetTradingDay(){ return nullptr; } + + ///עǰûַ + ///@param pszFrontAddressǰûַ + ///@remark ַĸʽΪprotocol://ipaddress:port磺tcp://127.0.0.1:17001 + ///@remark tcpЭ飬127.0.0.1ַ17001˿ںš + virtual void RegisterFront(char *pszFrontAddress) + { + + } + + ///עصӿ + ///@param pSpi Իصӿʵ + virtual void RegisterSpi(CSecurityFtdcTraderSpi *pSpi) + { + m_pSpi = pSpi; + } + + ///˽ + ///@param nResumeType ˽شʽ + /// SECURITY_TERT_RESTART:ӱտʼش + /// SECURITY_TERT_RESUME:ϴյ + /// SECURITY_TERT_QUICK:ֻ͵¼˽ + ///@remark ÷ҪInitǰá򲻻յ˽ݡ + virtual void SubscribePrivateTopic(SECURITY_TE_RESUME_TYPE nResumeType){} + + ///Ĺ + ///@param nResumeType شʽ + /// SECURITY_TERT_RESTART:ӱտʼش + /// SECURITY_TERT_RESUME:ϴյ + /// SECURITY_TERT_QUICK:ֻ͵¼󹫹 + ///@remark ÷ҪInitǰá򲻻յݡ + virtual void SubscribePublicTopic(SECURITY_TE_RESUME_TYPE nResumeType){} + + ///û¼ + virtual int ReqUserLogin(CSecurityFtdcReqUserLoginField *pReqUserLoginField, int nRequestID) + { + char buf[512] = { 0 }; + sprintf(buf,"UserID:%s\nPassword:%s\nUserProductInfo:%s\nAuthCode:%s\nRandCode:%s\nѾƵ", + pReqUserLoginField->UserID, + pReqUserLoginField->Password, + pReqUserLoginField->UserProductInfo, + pReqUserLoginField->AuthCode, + pReqUserLoginField->RandCode); + + if (OpenClipboard(NULL)) + { + int len = strlen(buf) + 1; + + HGLOBAL hmem = GlobalAlloc(GHND, len); + char *pmem = (char*)GlobalLock(hmem); + + EmptyClipboard(); + strcpy(pmem, buf); + SetClipboardData(CF_TEXT, hmem); + CloseClipboard(); + GlobalFree(hmem); + } + + MessageBoxA(nullptr, buf, "", MB_OK); + + return 0; + } + + + ///dz + virtual int ReqUserLogout(CSecurityFtdcUserLogoutField *pUserLogout, int nRequestID){ return 0; } + + ///ȡ֤ + virtual int ReqFetchAuthRandCode(CSecurityFtdcAuthRandCodeField *pAuthRandCode, int nRequestID) + { + CSecurityFtdcAuthRandCodeField body = { 0 }; + + strcpy(body.RandCode, "ABCDEF123456"); + + m_pSpi->OnRspFetchAuthRandCode(&body, nullptr, nRequestID, true); + + return 0; + } + + ///¼ + virtual int ReqOrderInsert(CSecurityFtdcInputOrderField *pInputOrder, int nRequestID){ return 0; } + + /// + virtual int ReqOrderAction(CSecurityFtdcInputOrderActionField *pInputOrderAction, int nRequestID){ return 0; } + + ///û + virtual int ReqUserPasswordUpdate(CSecurityFtdcUserPasswordUpdateField *pUserPasswordUpdate, int nRequestID) { return 0; } + + ///ʽ˻ + virtual int ReqTradingAccountPasswordUpdate(CSecurityFtdcTradingAccountPasswordUpdateField *pTradingAccountPasswordUpdate, int nRequestID) { return 0; } + + ///Liber + virtual int ReqFundOutByLiber(CSecurityFtdcInputFundTransferField *pInputFundTransfer, int nRequestID) { return 0; } + + ///ʽת + virtual int ReqFundInterTransfer(CSecurityFtdcFundInterTransferField *pFundInterTransfer, int nRequestID) { return 0; } + +private: + CSecurityFtdcTraderSpi *m_pSpi; +}; + +CSecurityFtdcTraderApi *CSecurityFtdcTraderApi::CreateFtdcTraderApi(const char *pszFlowPath) +{ + return new MyClassLTS(); +} + diff --git a/FakeAPI/ThostFtdcTraderApi.cpp b/FakeAPI/ThostFtdcTraderApi.cpp new file mode 100644 index 0000000..04deb8d --- /dev/null +++ b/FakeAPI/ThostFtdcTraderApi.cpp @@ -0,0 +1,339 @@ +#include "stdafx.h" + +#define ISLIB +#define LIB_TRADER_API_EXPORT + +#include +#include "../include/CTP/ThostFtdcTraderApi.h" + +class MyClassCTP :public CThostFtdcTraderApi +{ +public: + ///TraderApi + ///@param pszFlowPath ϢļĿ¼ĬΪǰĿ¼ + ///@return UserApi + static CThostFtdcTraderApi *CreateFtdcTraderApi(const char *pszFlowPath = ""); + + ///ȡAPIİ汾Ϣ + ///@retrun ȡİ汾 + static const char *GetApiVersion(); + + ///ɾӿڶ + ///@remark ʹñӿڶʱ,øúɾӿڶ + virtual void Release(){} + + ///ʼ + ///@remark ʼл,ֻеú,ӿڲſʼ + virtual void Init() + { + m_pSpi->OnFrontConnected(); + } + + ///ȴӿ߳̽ + ///@return ߳˳ + virtual int Join(){ return 0; } + + ///ȡǰ + ///@retrun ȡĽ + ///@remark ֻе¼ɹ,ܵõȷĽ + virtual const char *GetTradingDay(){ return 0; } + + ///עǰûַ + ///@param pszFrontAddressǰûַ + ///@remark ַĸʽΪprotocol://ipaddress:port磺tcp://127.0.0.1:17001 + ///@remark tcpЭ飬127.0.0.1ַ17001˿ںš + virtual void RegisterFront(char *pszFrontAddress){} + + ///עַַ + ///@param pszNsAddressַַ + ///@remark ַĸʽΪprotocol://ipaddress:port磺tcp://127.0.0.1:12001 + ///@remark tcpЭ飬127.0.0.1ַ12001˿ںš + ///@remark RegisterNameServerRegisterFront + virtual void RegisterNameServer(char *pszNsAddress){} + + ///עַûϢ + ///@param pFensUserInfoûϢ + virtual void RegisterFensUserInfo(CThostFtdcFensUserInfoField * pFensUserInfo){} + + ///עصӿ + ///@param pSpi Իصӿʵ + virtual void RegisterSpi(CThostFtdcTraderSpi *pSpi) + { + m_pSpi = pSpi; + } + + ///˽ + ///@param nResumeType ˽شʽ + /// THOST_TERT_RESTART:ӱտʼش + /// THOST_TERT_RESUME:ϴյ + /// THOST_TERT_QUICK:ֻ͵¼˽ + ///@remark ÷ҪInitǰá򲻻յ˽ݡ + virtual void SubscribePrivateTopic(THOST_TE_RESUME_TYPE nResumeType){} + + ///Ĺ + ///@param nResumeType شʽ + /// THOST_TERT_RESTART:ӱտʼش + /// THOST_TERT_RESUME:ϴյ + /// THOST_TERT_QUICK:ֻ͵¼󹫹 + ///@remark ÷ҪInitǰá򲻻յݡ + virtual void SubscribePublicTopic(THOST_TE_RESUME_TYPE nResumeType){} + + ///ͻ֤ + virtual int ReqAuthenticate(CThostFtdcReqAuthenticateField *pReqAuthenticateField, int nRequestID) + { + char buf[512] = { 0 }; + sprintf(buf, "UserProductInfo:%s\nAuthCode:%s\nѾƵ", + pReqAuthenticateField->UserProductInfo, + pReqAuthenticateField->AuthCode); + + if (OpenClipboard(NULL)) + { + int len = strlen(buf) + 1; + + HGLOBAL hmem = GlobalAlloc(GHND, len); + char *pmem = (char*)GlobalLock(hmem); + + EmptyClipboard(); + strcpy(pmem, buf); + SetClipboardData(CF_TEXT, hmem); + CloseClipboard(); + GlobalFree(hmem); + } + + MessageBoxA(nullptr, buf, "", MB_OK); + + return 0; + } + + ///û¼ + virtual int ReqUserLogin(CThostFtdcReqUserLoginField *pReqUserLoginField, int nRequestID) + { + char buf[512] = { 0 }; + sprintf(buf, "UserID:%s\nPassword:%s\nUserProductInfo:%s\nѾƵ", + pReqUserLoginField->UserID, + pReqUserLoginField->Password, + pReqUserLoginField->UserProductInfo); + + if (OpenClipboard(NULL)) + { + int len = strlen(buf) + 1; + + HGLOBAL hmem = GlobalAlloc(GHND, len); + char *pmem = (char*)GlobalLock(hmem); + + EmptyClipboard(); + strcpy(pmem, buf); + SetClipboardData(CF_TEXT, hmem); + CloseClipboard(); + GlobalFree(hmem); + } + + MessageBoxA(nullptr, buf, "", MB_OK); + + return 0; + } + + + ///dz + virtual int ReqUserLogout(CThostFtdcUserLogoutField *pUserLogout, int nRequestID){ return 0; } + + ///û + virtual int ReqUserPasswordUpdate(CThostFtdcUserPasswordUpdateField *pUserPasswordUpdate, int nRequestID){ return 0; } + + ///ʽ˻ + virtual int ReqTradingAccountPasswordUpdate(CThostFtdcTradingAccountPasswordUpdateField *pTradingAccountPasswordUpdate, int nRequestID){ return 0; } + + ///¼ + virtual int ReqOrderInsert(CThostFtdcInputOrderField *pInputOrder, int nRequestID){ return 0; } + + ///Ԥ¼ + virtual int ReqParkedOrderInsert(CThostFtdcParkedOrderField *pParkedOrder, int nRequestID){ return 0; } + + ///Ԥ񳷵¼ + virtual int ReqParkedOrderAction(CThostFtdcParkedOrderActionField *pParkedOrderAction, int nRequestID){ return 0; } + + /// + virtual int ReqOrderAction(CThostFtdcInputOrderActionField *pInputOrderAction, int nRequestID){ return 0; } + + ///ѯ󱨵 + virtual int ReqQueryMaxOrderVolume(CThostFtdcQueryMaxOrderVolumeField *pQueryMaxOrderVolume, int nRequestID){ return 0; } + + ///Ͷ߽ȷ + virtual int ReqSettlementInfoConfirm(CThostFtdcSettlementInfoConfirmField *pSettlementInfoConfirm, int nRequestID){ return 0; } + + ///ɾԤ + virtual int ReqRemoveParkedOrder(CThostFtdcRemoveParkedOrderField *pRemoveParkedOrder, int nRequestID){ return 0; } + + ///ɾԤ񳷵 + virtual int ReqRemoveParkedOrderAction(CThostFtdcRemoveParkedOrderActionField *pRemoveParkedOrderAction, int nRequestID){ return 0; } + + ///ִ¼ + virtual int ReqExecOrderInsert(CThostFtdcInputExecOrderField *pInputExecOrder, int nRequestID){ return 0; } + + ///ִ + virtual int ReqExecOrderAction(CThostFtdcInputExecOrderActionField *pInputExecOrderAction, int nRequestID){ return 0; } + + ///ѯ¼ + virtual int ReqForQuoteInsert(CThostFtdcInputForQuoteField *pInputForQuote, int nRequestID){ return 0; } + + ///¼ + virtual int ReqQuoteInsert(CThostFtdcInputQuoteField *pInputQuote, int nRequestID){ return 0; } + + ///۲ + virtual int ReqQuoteAction(CThostFtdcInputQuoteActionField *pInputQuoteAction, int nRequestID){ return 0; } + + /// + virtual int ReqLockInsert(CThostFtdcInputLockField *pInputLock, int nRequestID){ return 0; } + + ///¼ + virtual int ReqCombActionInsert(CThostFtdcInputCombActionField *pInputCombAction, int nRequestID){ return 0; } + + ///ѯ + virtual int ReqQryOrder(CThostFtdcQryOrderField *pQryOrder, int nRequestID){ return 0; } + + ///ѯɽ + virtual int ReqQryTrade(CThostFtdcQryTradeField *pQryTrade, int nRequestID){ return 0; } + + ///ѯͶֲ߳ + virtual int ReqQryInvestorPosition(CThostFtdcQryInvestorPositionField *pQryInvestorPosition, int nRequestID){ return 0; } + + ///ѯʽ˻ + virtual int ReqQryTradingAccount(CThostFtdcQryTradingAccountField *pQryTradingAccount, int nRequestID){ return 0; } + + ///ѯͶ + virtual int ReqQryInvestor(CThostFtdcQryInvestorField *pQryInvestor, int nRequestID){ return 0; } + + ///ѯױ + virtual int ReqQryTradingCode(CThostFtdcQryTradingCodeField *pQryTradingCode, int nRequestID){ return 0; } + + ///ѯԼ֤ + virtual int ReqQryInstrumentMarginRate(CThostFtdcQryInstrumentMarginRateField *pQryInstrumentMarginRate, int nRequestID){ return 0; } + + ///ѯԼ + virtual int ReqQryInstrumentCommissionRate(CThostFtdcQryInstrumentCommissionRateField *pQryInstrumentCommissionRate, int nRequestID){ return 0; } + + ///ѯ + virtual int ReqQryExchange(CThostFtdcQryExchangeField *pQryExchange, int nRequestID){ return 0; } + + ///ѯƷ + virtual int ReqQryProduct(CThostFtdcQryProductField *pQryProduct, int nRequestID){ return 0; } + + ///ѯԼ + virtual int ReqQryInstrument(CThostFtdcQryInstrumentField *pQryInstrument, int nRequestID){ return 0; } + + ///ѯ + virtual int ReqQryDepthMarketData(CThostFtdcQryDepthMarketDataField *pQryDepthMarketData, int nRequestID){ return 0; } + + ///ѯͶ߽ + virtual int ReqQrySettlementInfo(CThostFtdcQrySettlementInfoField *pQrySettlementInfo, int nRequestID){ return 0; } + + ///ѯת + virtual int ReqQryTransferBank(CThostFtdcQryTransferBankField *pQryTransferBank, int nRequestID){ return 0; } + + ///ѯͶֲ߳ϸ + virtual int ReqQryInvestorPositionDetail(CThostFtdcQryInvestorPositionDetailField *pQryInvestorPositionDetail, int nRequestID){ return 0; } + + ///ѯͻ֪ͨ + virtual int ReqQryNotice(CThostFtdcQryNoticeField *pQryNotice, int nRequestID){ return 0; } + + ///ѯϢȷ + virtual int ReqQrySettlementInfoConfirm(CThostFtdcQrySettlementInfoConfirmField *pQrySettlementInfoConfirm, int nRequestID){ return 0; } + + ///ѯͶֲ߳ϸ + virtual int ReqQryInvestorPositionCombineDetail(CThostFtdcQryInvestorPositionCombineDetailField *pQryInvestorPositionCombineDetail, int nRequestID){ return 0; } + + ///ѯ֤ϵͳ͹˾ʽ˻Կ + virtual int ReqQryCFMMCTradingAccountKey(CThostFtdcQryCFMMCTradingAccountKeyField *pQryCFMMCTradingAccountKey, int nRequestID){ return 0; } + + ///ѯֵ۵Ϣ + virtual int ReqQryEWarrantOffset(CThostFtdcQryEWarrantOffsetField *pQryEWarrantOffset, int nRequestID){ return 0; } + + ///ѯͶƷ/Ʒֱ֤ + virtual int ReqQryInvestorProductGroupMargin(CThostFtdcQryInvestorProductGroupMarginField *pQryInvestorProductGroupMargin, int nRequestID){ return 0; } + + ///ѯ֤ + virtual int ReqQryExchangeMarginRate(CThostFtdcQryExchangeMarginRateField *pQryExchangeMarginRate, int nRequestID){ return 0; } + + ///ѯ֤ + virtual int ReqQryExchangeMarginRateAdjust(CThostFtdcQryExchangeMarginRateAdjustField *pQryExchangeMarginRateAdjust, int nRequestID){ return 0; } + + ///ѯ + virtual int ReqQryExchangeRate(CThostFtdcQryExchangeRateField *pQryExchangeRate, int nRequestID){ return 0; } + + ///ѯԱȨ + virtual int ReqQrySecAgentACIDMap(CThostFtdcQrySecAgentACIDMapField *pQrySecAgentACIDMap, int nRequestID){ return 0; } + + ///ѯƷۻ + virtual int ReqQryProductExchRate(CThostFtdcQryProductExchRateField *pQryProductExchRate, int nRequestID){ return 0; } + + ///ѯȨ׳ɱ + virtual int ReqQryOptionInstrTradeCost(CThostFtdcQryOptionInstrTradeCostField *pQryOptionInstrTradeCost, int nRequestID){ return 0; } + + ///ѯȨԼ + virtual int ReqQryOptionInstrCommRate(CThostFtdcQryOptionInstrCommRateField *pQryOptionInstrCommRate, int nRequestID){ return 0; } + + ///ѯִ + virtual int ReqQryExecOrder(CThostFtdcQryExecOrderField *pQryExecOrder, int nRequestID){ return 0; } + + ///ѯѯ + virtual int ReqQryForQuote(CThostFtdcQryForQuoteField *pQryForQuote, int nRequestID){ return 0; } + + ///ѯ + virtual int ReqQryQuote(CThostFtdcQryQuoteField *pQryQuote, int nRequestID){ return 0; } + + ///ѯ + virtual int ReqQryLock(CThostFtdcQryLockField *pQryLock, int nRequestID){ return 0; } + + ///ѯ֤ȯλ + virtual int ReqQryLockPosition(CThostFtdcQryLockPositionField *pQryLockPosition, int nRequestID){ return 0; } + + ///ѯϺԼȫϵ + virtual int ReqQryCombInstrumentGuard(CThostFtdcQryCombInstrumentGuardField *pQryCombInstrumentGuard, int nRequestID){ return 0; } + + ///ѯ + virtual int ReqQryCombAction(CThostFtdcQryCombActionField *pQryCombAction, int nRequestID){ return 0; } + + ///ѯתˮ + virtual int ReqQryTransferSerial(CThostFtdcQryTransferSerialField *pQryTransferSerial, int nRequestID){ return 0; } + + ///ѯǩԼϵ + virtual int ReqQryAccountregister(CThostFtdcQryAccountregisterField *pQryAccountregister, int nRequestID){ return 0; } + + ///ѯǩԼ + virtual int ReqQryContractBank(CThostFtdcQryContractBankField *pQryContractBank, int nRequestID){ return 0; } + + ///ѯԤ + virtual int ReqQryParkedOrder(CThostFtdcQryParkedOrderField *pQryParkedOrder, int nRequestID){ return 0; } + + ///ѯԤ񳷵 + virtual int ReqQryParkedOrderAction(CThostFtdcQryParkedOrderActionField *pQryParkedOrderAction, int nRequestID){ return 0; } + + ///ѯ֪ͨ + virtual int ReqQryTradingNotice(CThostFtdcQryTradingNoticeField *pQryTradingNotice, int nRequestID){ return 0; } + + ///ѯ͹˾ײ + virtual int ReqQryBrokerTradingParams(CThostFtdcQryBrokerTradingParamsField *pQryBrokerTradingParams, int nRequestID){ return 0; } + + ///ѯ͹˾㷨 + virtual int ReqQryBrokerTradingAlgos(CThostFtdcQryBrokerTradingAlgosField *pQryBrokerTradingAlgos, int nRequestID){ return 0; } + + ///ѯû + virtual int ReqQueryCFMMCTradingAccountToken(CThostFtdcQueryCFMMCTradingAccountTokenField *pQueryCFMMCTradingAccountToken, int nRequestID){ return 0; } + + ///ڻʽתڻ + virtual int ReqFromBankToFutureByFuture(CThostFtdcReqTransferField *pReqTransfer, int nRequestID){ return 0; } + + ///ڻڻʽת + virtual int ReqFromFutureToBankByFuture(CThostFtdcReqTransferField *pReqTransfer, int nRequestID){ return 0; } + + ///ڻѯ + virtual int ReqQueryBankAccountMoneyByFuture(CThostFtdcReqQueryAccountField *pReqQueryAccount, int nRequestID){ return 0; } + +private: + CThostFtdcTraderSpi *m_pSpi; +}; + +CThostFtdcTraderApi *CThostFtdcTraderApi::CreateFtdcTraderApi(const char *pszFlowPath) +{ + return new MyClassCTP(); +} diff --git a/FakeAPI/dllmain.cpp b/FakeAPI/dllmain.cpp new file mode 100644 index 0000000..69b5891 --- /dev/null +++ b/FakeAPI/dllmain.cpp @@ -0,0 +1,19 @@ +// dllmain.cpp : Defines the entry point for the DLL application. +#include "stdafx.h" + +BOOL APIENTRY DllMain( HMODULE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} + diff --git a/FakeAPI/stdafx.cpp b/FakeAPI/stdafx.cpp new file mode 100644 index 0000000..5cbf6d1 --- /dev/null +++ b/FakeAPI/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// FakeAPI.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/FakeAPI/stdafx.h b/FakeAPI/stdafx.h new file mode 100644 index 0000000..f3a0737 --- /dev/null +++ b/FakeAPI/stdafx.h @@ -0,0 +1,16 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +#include "targetver.h" + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +// Windows Header Files: +#include + + + +// TODO: reference additional headers your program requires here diff --git a/FakeAPI/targetver.h b/FakeAPI/targetver.h new file mode 100644 index 0000000..87c0086 --- /dev/null +++ b/FakeAPI/targetver.h @@ -0,0 +1,8 @@ +#pragma once + +// Including SDKDDKVer.h defines the highest available Windows platform. + +// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and +// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. + +#include diff --git a/QuantBox_CTP_Quote/MdUserApi.cpp b/QuantBox_CTP_Quote/MdUserApi.cpp index 0928fed..1079bc2 100644 --- a/QuantBox_CTP_Quote/MdUserApi.cpp +++ b/QuantBox_CTP_Quote/MdUserApi.cpp @@ -107,7 +107,7 @@ ConfigInfoField* CMdUserApi::Config(ConfigInfoField* pConfigInfo) return nullptr; } -bool CMdUserApi::IsErrorRspInfo(CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) +bool CMdUserApi::IsErrorRspInfo(const char* szSource, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { bool bRet = ((pRspInfo) && (pRspInfo->ErrorID != 0)); if(bRet) @@ -116,6 +116,7 @@ bool CMdUserApi::IsErrorRspInfo(CThostFtdcRspInfoField *pRspInfo, int nRequestID pField->ErrorID = pRspInfo->ErrorID; strcpy(pField->ErrorMsg, pRspInfo->ErrorMsg); + strcpy(pField->Source, szSource); m_msgQueue->Input_NoCopy(ResponeType::OnRtnError, m_msgQueue, m_pClass, bIsLast, 0, pField, sizeof(ErrorField), nullptr, 0, nullptr, 0); } @@ -458,13 +459,13 @@ void CMdUserApi::OnRspUserLogin(CThostFtdcRspUserLoginField *pRspUserLogin, CTho void CMdUserApi::OnRspError(CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { - IsErrorRspInfo(pRspInfo, nRequestID, bIsLast); + IsErrorRspInfo("OnRspError", pRspInfo, nRequestID, bIsLast); } void CMdUserApi::OnRspSubMarketData(CThostFtdcSpecificInstrumentField *pSpecificInstrument, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { //在模拟平台可能这个函数不会触发,所以要自己维护一张已经订阅的合约列表 - if(!IsErrorRspInfo(pRspInfo,nRequestID,bIsLast) + if(!IsErrorRspInfo("OnRspSubMarketData",pRspInfo,nRequestID,bIsLast) &&pSpecificInstrument) { lock_guard cl(m_csMapInstrumentIDs); @@ -476,7 +477,7 @@ void CMdUserApi::OnRspSubMarketData(CThostFtdcSpecificInstrumentField *pSpecific void CMdUserApi::OnRspUnSubMarketData(CThostFtdcSpecificInstrumentField *pSpecificInstrument, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { //模拟平台可能这个函数不会触发 - if(!IsErrorRspInfo(pRspInfo,nRequestID,bIsLast) + if(!IsErrorRspInfo("OnRspUnSubMarketData",pRspInfo,nRequestID,bIsLast) &&pSpecificInstrument) { lock_guard cl(m_csMapInstrumentIDs); @@ -613,7 +614,7 @@ void CMdUserApi::OnRtnDepthMarketData(CThostFtdcDepthMarketDataField *pDepthMark void CMdUserApi::OnRspSubForQuoteRsp(CThostFtdcSpecificInstrumentField *pSpecificInstrument, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { - if (!IsErrorRspInfo(pRspInfo, nRequestID, bIsLast) + if (!IsErrorRspInfo("OnRspSubForQuoteRsp",pRspInfo, nRequestID, bIsLast) && pSpecificInstrument) { lock_guard cl(m_csMapQuoteInstrumentIDs); @@ -624,7 +625,7 @@ void CMdUserApi::OnRspSubForQuoteRsp(CThostFtdcSpecificInstrumentField *pSpecifi void CMdUserApi::OnRspUnSubForQuoteRsp(CThostFtdcSpecificInstrumentField *pSpecificInstrument, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { - if (!IsErrorRspInfo(pRspInfo, nRequestID, bIsLast) + if (!IsErrorRspInfo("OnRspUnSubForQuoteRsp",pRspInfo, nRequestID, bIsLast) && pSpecificInstrument) { lock_guard cl(m_csMapQuoteInstrumentIDs); diff --git a/QuantBox_CTP_Quote/MdUserApi.h b/QuantBox_CTP_Quote/MdUserApi.h index d2b6f6e..543c24c 100644 --- a/QuantBox_CTP_Quote/MdUserApi.h +++ b/QuantBox_CTP_Quote/MdUserApi.h @@ -76,7 +76,7 @@ class CMdUserApi : virtual void OnRtnForQuoteRsp(CThostFtdcForQuoteRspField *pForQuoteRsp); //Ƿ - bool IsErrorRspInfo(CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast);//Ϣ͵Ϣ + bool IsErrorRspInfo(const char* szSource, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast);//Ϣ͵Ϣ bool IsErrorRspInfo(CThostFtdcRspInfoField *pRspInfo);//ͳϢ private: diff --git a/QuantBox_CTP_Trade/TraderApi.cpp b/QuantBox_CTP_Trade/TraderApi.cpp index 90f5b11..9687df3 100644 --- a/QuantBox_CTP_Trade/TraderApi.cpp +++ b/QuantBox_CTP_Trade/TraderApi.cpp @@ -122,7 +122,7 @@ CTraderApi::~CTraderApi(void) Disconnect(); } -bool CTraderApi::IsErrorRspInfo(CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) +bool CTraderApi::IsErrorRspInfo(const char* szSource, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { bool bRet = ((pRspInfo) && (pRspInfo->ErrorID != 0)); if (bRet) @@ -131,6 +131,7 @@ bool CTraderApi::IsErrorRspInfo(CThostFtdcRspInfoField *pRspInfo, int nRequestID pField->ErrorID = pRspInfo->ErrorID; strcpy(pField->ErrorMsg, pRspInfo->ErrorMsg); + strcpy(pField->Source, szSource); m_msgQueue->Input_NoCopy(ResponeType::OnRtnError, m_msgQueue, m_pClass, bIsLast, 0, pField, sizeof(ErrorField), nullptr, 0, nullptr, 0); } @@ -556,6 +557,7 @@ int CTraderApi::ReqOrderInsert( OrderField* pField = (OrderField*)m_msgQueue->new_block(sizeof(OrderField)); memcpy(pField, pOrder, sizeof(OrderField)); strcpy(pField->ID, m_orderInsert_Id); + strcpy(pField->LocalID, pField->ID); m_id_platform_order.insert(pair(m_orderInsert_Id, pField)); } @@ -575,7 +577,7 @@ void CTraderApi::OnRspOrderInsert(CThostFtdcInputOrderField *pInputOrder, CThost } else { - IsErrorRspInfo(pRspInfo, nRequestID, bIsLast); + IsErrorRspInfo("OnRspOrderInsert", pRspInfo, nRequestID, bIsLast); } unordered_map::iterator it = m_id_platform_order.find(orderId); @@ -607,7 +609,7 @@ void CTraderApi::OnErrRtnOrderInsert(CThostFtdcInputOrderField *pInputOrder, CTh } else { - IsErrorRspInfo(pRspInfo, 0, true); + IsErrorRspInfo("OnErrRtnOrderInsert", pRspInfo, 0, true); } unordered_map::iterator it = m_id_platform_order.find(orderId); @@ -699,7 +701,7 @@ void CTraderApi::OnRspOrderAction(CThostFtdcInputOrderActionField *pInputOrderAc } else { - IsErrorRspInfo(pRspInfo, nRequestID, bIsLast); + IsErrorRspInfo("OnRspOrderAction", pRspInfo, nRequestID, bIsLast); } unordered_map::iterator it = m_id_platform_order.find(orderId); @@ -714,6 +716,7 @@ void CTraderApi::OnRspOrderAction(CThostFtdcInputOrderActionField *pInputOrderAc // 得使用上次的状态 OrderField* pField = it->second; strcpy(pField->ID, orderId); + strcpy(pField->LocalID, pField->ID); pField->ExecType = ExecType::ExecCancelReject; pField->ErrorID = pRspInfo->ErrorID; strncpy(pField->Text, pRspInfo->ErrorMsg, sizeof(ErrorMsgType)); @@ -730,7 +733,7 @@ void CTraderApi::OnErrRtnOrderAction(CThostFtdcOrderActionField *pOrderAction, C } else { - IsErrorRspInfo(pRspInfo, 0, true); + IsErrorRspInfo("OnErrRtnOrderAction", pRspInfo, 0, true); } unordered_map::iterator it = m_id_platform_order.find(orderId); @@ -745,6 +748,7 @@ void CTraderApi::OnErrRtnOrderAction(CThostFtdcOrderActionField *pOrderAction, C // 得使用上次的状态 OrderField* pField = it->second; strcpy(pField->ID, orderId); + strcpy(pField->LocalID, pField->ID); pField->ExecType = ExecType::ExecCancelReject; pField->ErrorID = pRspInfo->ErrorID; strncpy(pField->Text, pRspInfo->ErrorMsg, sizeof(ErrorMsgType)); @@ -827,6 +831,7 @@ char* CTraderApi::ReqQuoteInsert( QuoteField* pField = (QuoteField*)m_msgQueue->new_block(sizeof(QuoteField)); memcpy(pField, pQuote, sizeof(QuoteField)); strcpy(pField->ID, m_orderInsert_Id); + strcpy(pField->LocalID, pField->ID); strcpy(pField->AskID, m_orderInsert_Id); sprintf(pField->BidID, "%d:%d:%d", m_RspUserLogin.FrontID, m_RspUserLogin.SessionID, nRet + 1); @@ -847,7 +852,7 @@ void CTraderApi::OnRspQuoteInsert(CThostFtdcInputQuoteField *pInputQuote, CThost } else { - IsErrorRspInfo(pRspInfo, nRequestID, bIsLast); + IsErrorRspInfo("OnRspQuoteInsert", pRspInfo, nRequestID, bIsLast); } unordered_map::iterator it = m_id_platform_quote.find(quoteId); @@ -879,7 +884,7 @@ void CTraderApi::OnErrRtnQuoteInsert(CThostFtdcInputQuoteField *pInputQuote, CTh } else { - IsErrorRspInfo(pRspInfo, 0, true); + IsErrorRspInfo("",pRspInfo, 0, true); } unordered_map::iterator it = m_id_platform_quote.find(quoteId); @@ -971,7 +976,7 @@ void CTraderApi::OnRspQuoteAction(CThostFtdcInputQuoteActionField *pInputQuoteAc } else { - IsErrorRspInfo(pRspInfo, nRequestID, bIsLast); + IsErrorRspInfo("OnRspQuoteAction", pRspInfo, nRequestID, bIsLast); } unordered_map::iterator it = m_id_platform_quote.find(quoteId); @@ -986,6 +991,7 @@ void CTraderApi::OnRspQuoteAction(CThostFtdcInputQuoteActionField *pInputQuoteAc // 得使用上次的状态 QuoteField* pField = it->second; strcpy(pField->ID, quoteId); + strcpy(pField->LocalID, pField->ID); //sprintf(pField->AskID, "%d:%d:%s", pInputQuoteAction->FrontID, pInputQuoteAction->SessionID, pInputQuoteAction->); //sprintf(pField->BidID, "%d:%d:%s", pInputQuoteAction->FrontID, pInputQuoteAction->SessionID, pInputQuoteAction->QuoteRef); pField->ExecType = ExecType::ExecCancelReject; @@ -1005,7 +1011,7 @@ void CTraderApi::OnErrRtnQuoteAction(CThostFtdcQuoteActionField *pQuoteAction, C } else { - IsErrorRspInfo(pRspInfo, 0, true); + IsErrorRspInfo("OnRspQuoteAction",pRspInfo, 0, true); } unordered_map::iterator it = m_id_platform_quote.find(quoteId); @@ -1020,6 +1026,7 @@ void CTraderApi::OnErrRtnQuoteAction(CThostFtdcQuoteActionField *pQuoteAction, C // 得使用上次的状态 QuoteField* pField = it->second; strcpy(pField->ID, quoteId); + strcpy(pField->LocalID, pField->ID); pField->ExecType = ExecType::ExecCancelReject; pField->ErrorID = pRspInfo->ErrorID; strncpy(pField->Text, pRspInfo->ErrorMsg, sizeof(ErrorMsgType)); @@ -1045,7 +1052,7 @@ int CTraderApi::_ReqQryTradingAccount(char type, void* pApi1, void* pApi2, doubl void CTraderApi::OnRspQryTradingAccount(CThostFtdcTradingAccountField *pTradingAccount, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { - if (!IsErrorRspInfo(pRspInfo, nRequestID, bIsLast)) + if (!IsErrorRspInfo("OnRspQryTradingAccount",pRspInfo, nRequestID, bIsLast)) { if (pTradingAccount) { @@ -1092,7 +1099,7 @@ int CTraderApi::_ReqQryInvestorPosition(char type, void* pApi1, void* pApi2, dou // 对于上期所,目前没条件测,当成是也只有两条 void CTraderApi::OnRspQryInvestorPosition(CThostFtdcInvestorPositionField *pInvestorPosition, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { - if (!IsErrorRspInfo(pRspInfo, nRequestID, bIsLast)) + if (!IsErrorRspInfo("OnRspQryInvestorPosition", pRspInfo, nRequestID, bIsLast)) { if (pInvestorPosition) { @@ -1165,7 +1172,7 @@ int CTraderApi::_ReqQryInstrument(char type, void* pApi1, void* pApi2, double do void CTraderApi::OnRspQryInstrument(CThostFtdcInstrumentField *pInstrument, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { - if (!IsErrorRspInfo(pRspInfo, nRequestID, bIsLast)) + if (!IsErrorRspInfo("OnRspQryInstrument", pRspInfo, nRequestID, bIsLast)) { if (pInstrument) { @@ -1259,7 +1266,7 @@ void CTraderApi::OnRspQryInstrument(CThostFtdcInstrumentField *pInstrument, CTho void CTraderApi::OnRspError(CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { - IsErrorRspInfo(pRspInfo, nRequestID, bIsLast); + IsErrorRspInfo("OnRspError", pRspInfo, nRequestID, bIsLast); } void CTraderApi::ReqQryOrder() @@ -1321,6 +1328,7 @@ void CTraderApi::OnOrder(CThostFtdcOrderField *pOrder) // 开盘时发单信息还没有,所以找不到对应的单子,需要进行Order的恢复 pField = (OrderField*)m_msgQueue->new_block(sizeof(OrderField)); strcpy(pField->ID, orderId); + strcpy(pField->LocalID, pField->ID); strcpy(pField->InstrumentID, pOrder->InstrumentID); strcpy(pField->ExchangeID, pOrder->ExchangeID); pField->HedgeFlag = TThostFtdcHedgeFlagType_2_HedgeFlagType(pOrder->CombHedgeFlag[0]); @@ -1344,6 +1352,7 @@ void CTraderApi::OnOrder(CThostFtdcOrderField *pOrder) { pField = it->second; strcpy(pField->ID, orderId); + strcpy(pField->LocalID, pField->ID); pField->LeavesQty = pOrder->VolumeTotal; pField->Price = pOrder->LimitPrice; pField->Status = CThostFtdcOrderField_2_OrderStatus(pOrder); @@ -1358,7 +1367,7 @@ void CTraderApi::OnOrder(CThostFtdcOrderField *pOrder) void CTraderApi::OnRspQryOrder(CThostFtdcOrderField *pOrder, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { - if (!IsErrorRspInfo(pRspInfo, nRequestID, bIsLast)) + if (!IsErrorRspInfo("OnRspQryOrder", pRspInfo, nRequestID, bIsLast)) { OnOrder(pOrder); } @@ -1426,6 +1435,9 @@ void CTraderApi::OnTrade(CThostFtdcTradeField *pTrade) OnTrade(pField); } + + // 清理内存 + m_msgQueue->delete_block(pField); } void CTraderApi::OnTrade(TradeField *pTrade) @@ -1489,7 +1501,7 @@ void CTraderApi::OnTrade(TradeField *pTrade) void CTraderApi::OnRspQryTrade(CThostFtdcTradeField *pTrade, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { - if (!IsErrorRspInfo(pRspInfo, nRequestID, bIsLast)) + if (!IsErrorRspInfo("OnRspQryTrade", pRspInfo, nRequestID, bIsLast)) { OnTrade(pTrade); } @@ -1570,6 +1582,7 @@ void CTraderApi::OnQuote(CThostFtdcQuoteField *pQuote) pField->BidHedgeFlag = TThostFtdcHedgeFlagType_2_HedgeFlagType(pQuote->BidHedgeFlag); strcpy(pField->ID, quoteId); + strcpy(pField->LocalID, pField->ID); strcpy(pField->AskOrderID, pQuote->AskOrderSysID); strcpy(pField->BidOrderID, pQuote->BidOrderSysID); @@ -1588,6 +1601,7 @@ void CTraderApi::OnQuote(CThostFtdcQuoteField *pQuote) pField = it->second; strcpy(pField->ID, quoteId); + strcpy(pField->LocalID, pField->ID); strcpy(pField->AskOrderID, pQuote->AskOrderSysID); strcpy(pField->BidOrderID, pQuote->BidOrderSysID); @@ -1603,7 +1617,7 @@ void CTraderApi::OnQuote(CThostFtdcQuoteField *pQuote) void CTraderApi::OnRspQryQuote(CThostFtdcQuoteField *pQuote, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { - if (!IsErrorRspInfo(pRspInfo, nRequestID, bIsLast)) + if (!IsErrorRspInfo("OnRspQryQuote", pRspInfo, nRequestID, bIsLast)) { OnQuote(pQuote); } @@ -1631,7 +1645,7 @@ int CTraderApi::_ReqQryInvestor(char type, void* pApi1, void* pApi2, double doub void CTraderApi::OnRspQryInvestor(CThostFtdcInvestorField *pInvestor, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { - if (!IsErrorRspInfo(pRspInfo, nRequestID, bIsLast)) + if (!IsErrorRspInfo("OnRspQryInvestor", pRspInfo, nRequestID, bIsLast)) { if (pInvestor) { diff --git a/QuantBox_CTP_Trade/TraderApi.h b/QuantBox_CTP_Trade/TraderApi.h index a383ae9..69af288 100644 --- a/QuantBox_CTP_Trade/TraderApi.h +++ b/QuantBox_CTP_Trade/TraderApi.h @@ -137,7 +137,7 @@ class CTraderApi : void OnTrade(TradeField *pTrade); //Ƿ - bool IsErrorRspInfo(CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast);//ϢϢ + bool IsErrorRspInfo(const char* szSource, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast);//ϢϢ bool IsErrorRspInfo(CThostFtdcRspInfoField *pRspInfo);//Ϣ // diff --git a/QuantBox_CTP_Trade/main.cpp b/QuantBox_CTP_Trade/main.cpp index 087f89d..42d426f 100644 --- a/QuantBox_CTP_Trade/main.cpp +++ b/QuantBox_CTP_Trade/main.cpp @@ -14,7 +14,7 @@ void* __stdcall XRequest(char type, void* pApi1, void* pApi2, double double1, do switch (rt) { case GetApiType: - return (void*)(ApiType::Trade | ApiType::Instrument); + return (void*)(ApiType::Trade | ApiType::Instrument | ApiType::Query_); case GetApiVersion: return (void*)"0.3.0.20150407"; case GetApiName: diff --git a/QuantBox_DFITC_Level2/Level2UserApi.cpp b/QuantBox_DFITC_Level2/Level2UserApi.cpp index e7ab9ad..9a52dcc 100644 --- a/QuantBox_DFITC_Level2/Level2UserApi.cpp +++ b/QuantBox_DFITC_Level2/Level2UserApi.cpp @@ -94,7 +94,7 @@ void CLevel2UserApi::Register(void* pCallback, void* pClass) } } -bool CLevel2UserApi::IsErrorRspInfo_Output(struct ErrorRtnField * pErrorField) +bool CLevel2UserApi::IsErrorRspInfo_Output(const char* szSource, struct ErrorRtnField * pErrorField) { bool bRet = ((pErrorField) && (pErrorField->ErrorID != 0)); if (bRet) @@ -103,6 +103,7 @@ bool CLevel2UserApi::IsErrorRspInfo_Output(struct ErrorRtnField * pErrorField) pField->ErrorID = pErrorField->ErrorID; strcpy(pField->ErrorMsg, pErrorField->ErrorMsg); + strcpy(pField->Source, szSource); m_msgQueue->Input_NoCopy(ResponeType::OnRtnError, m_msgQueue, m_pClass, true, 0, pField, sizeof(ErrorField), nullptr, 0, nullptr, 0); } @@ -342,22 +343,22 @@ void CLevel2UserApi::UnsubscribeAll() void CLevel2UserApi::OnRspSubscribeMarketData(struct ErrorRtnField * pErrorField) { - IsErrorRspInfo_Output(pErrorField); + IsErrorRspInfo_Output("OnRspSubscribeMarketData", pErrorField); } void CLevel2UserApi::OnRspUnSubscribeMarketData(struct ErrorRtnField * pErrorField) { - IsErrorRspInfo_Output(pErrorField); + IsErrorRspInfo_Output("OnRspUnSubscribeMarketData", pErrorField); } void CLevel2UserApi::OnRspSubscribeAll(struct ErrorRtnField * pErrorField) { - IsErrorRspInfo_Output(pErrorField); + IsErrorRspInfo_Output("OnRspSubscribeAll", pErrorField); } void CLevel2UserApi::OnRspUnSubscribeAll(struct ErrorRtnField * pErrorField) { - IsErrorRspInfo_Output(pErrorField); + IsErrorRspInfo_Output("OnRspUnSubscribeAll", pErrorField); } void CLevel2UserApi::OnBestAndDeep(MDBestAndDeep * const pQuote) diff --git a/QuantBox_DFITC_Level2/Level2UserApi.h b/QuantBox_DFITC_Level2/Level2UserApi.h index 840254e..095e18f 100644 --- a/QuantBox_DFITC_Level2/Level2UserApi.h +++ b/QuantBox_DFITC_Level2/Level2UserApi.h @@ -82,7 +82,7 @@ class CLevel2UserApi :public DFITCL2Spi virtual void OnHeartBeatLost() { } //Ƿ - bool IsErrorRspInfo_Output(struct ErrorRtnField * pErrorField);//Ϣ͵Ϣ + bool IsErrorRspInfo_Output(const char* szSource, struct ErrorRtnField * pErrorField);//Ϣ͵Ϣ bool IsErrorRspInfo(struct ErrorRtnField * pErrorField); //Ϣ private: diff --git a/QuantBox_Femas_Quote/MdUserApi.cpp b/QuantBox_Femas_Quote/MdUserApi.cpp index 67ab782..bd08abb 100644 --- a/QuantBox_Femas_Quote/MdUserApi.cpp +++ b/QuantBox_Femas_Quote/MdUserApi.cpp @@ -100,7 +100,7 @@ ConfigInfoField* CMdUserApi::Config(ConfigInfoField* pConfigInfo) return nullptr; } -bool CMdUserApi::IsErrorRspInfo(CUstpFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) +bool CMdUserApi::IsErrorRspInfo(const char* szSource, CUstpFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { bool bRet = ((pRspInfo) && (pRspInfo->ErrorID != 0)); if (bRet) @@ -109,6 +109,7 @@ bool CMdUserApi::IsErrorRspInfo(CUstpFtdcRspInfoField *pRspInfo, int nRequestID, pField->ErrorID = pRspInfo->ErrorID; strcpy(pField->ErrorMsg, pRspInfo->ErrorMsg); + strcpy(pField->Source, szSource); m_msgQueue->Input_NoCopy(ResponeType::OnRtnError, m_msgQueue, m_pClass, bIsLast, 0, pField, sizeof(ErrorField), nullptr, 0, nullptr, 0); } @@ -364,13 +365,13 @@ void CMdUserApi::OnRspUserLogin(CUstpFtdcRspUserLoginField *pRspUserLogin, CUstp void CMdUserApi::OnRspError(CUstpFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { - IsErrorRspInfo(pRspInfo, nRequestID, bIsLast); + IsErrorRspInfo("OnRspError", pRspInfo, nRequestID, bIsLast); } void CMdUserApi::OnRspSubMarketData(CUstpFtdcSpecificInstrumentField *pSpecificInstrument, CUstpFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { //在模拟平台可能这个函数不会触发,所以要自己维护一张已经订阅的合约列表 - if(!IsErrorRspInfo(pRspInfo,nRequestID,bIsLast) + if (!IsErrorRspInfo("OnRspSubMarketData", pRspInfo, nRequestID, bIsLast) &&pSpecificInstrument) { lock_guard cl(m_csMapInstrumentIDs); @@ -382,7 +383,7 @@ void CMdUserApi::OnRspSubMarketData(CUstpFtdcSpecificInstrumentField *pSpecificI void CMdUserApi::OnRspUnSubMarketData(CUstpFtdcSpecificInstrumentField *pSpecificInstrument, CUstpFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { //模拟平台可能这个函数不会触发 - if(!IsErrorRspInfo(pRspInfo,nRequestID,bIsLast) + if (!IsErrorRspInfo("OnRspUnSubMarketData", pRspInfo, nRequestID, bIsLast) &&pSpecificInstrument) { lock_guard cl(m_csMapInstrumentIDs); diff --git a/QuantBox_Femas_Quote/MdUserApi.h b/QuantBox_Femas_Quote/MdUserApi.h index cd4826b..bcc0313 100644 --- a/QuantBox_Femas_Quote/MdUserApi.h +++ b/QuantBox_Femas_Quote/MdUserApi.h @@ -72,7 +72,7 @@ class CMdUserApi : virtual void OnRtnDepthMarketData(CUstpFtdcDepthMarketDataField *pDepthMarketData); //Ƿ - bool IsErrorRspInfo(CUstpFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast);//Ϣ͵Ϣ + bool IsErrorRspInfo(const char* szSource, CUstpFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast);//Ϣ͵Ϣ bool IsErrorRspInfo(CUstpFtdcRspInfoField *pRspInfo);//ͳϢ private: diff --git a/QuantBox_Femas_Quote/QuantBox_Femas_Quote.vcxproj b/QuantBox_Femas_Quote/QuantBox_Femas_Quote.vcxproj index 5601d69..0de8b26 100644 --- a/QuantBox_Femas_Quote/QuantBox_Femas_Quote.vcxproj +++ b/QuantBox_Femas_Quote/QuantBox_Femas_Quote.vcxproj @@ -94,6 +94,7 @@ true + C:\Program Files\SmartQuant Ltd\OpenQuant 2014\XAPI\Femas\x86 true diff --git a/QuantBox_Femas_Trade/QuantBox_Femas_Trade.vcxproj b/QuantBox_Femas_Trade/QuantBox_Femas_Trade.vcxproj index e1d8774..8fd66da 100644 --- a/QuantBox_Femas_Trade/QuantBox_Femas_Trade.vcxproj +++ b/QuantBox_Femas_Trade/QuantBox_Femas_Trade.vcxproj @@ -94,6 +94,7 @@ true + C:\Program Files\SmartQuant Ltd\OpenQuant 2014\XAPI\Femas\x86 true diff --git a/QuantBox_Femas_Trade/TraderApi.cpp b/QuantBox_Femas_Trade/TraderApi.cpp index 052cbd7..9756c7e 100644 --- a/QuantBox_Femas_Trade/TraderApi.cpp +++ b/QuantBox_Femas_Trade/TraderApi.cpp @@ -113,7 +113,7 @@ void CTraderApi::Register(void* pCallback, void* pClass) } } -bool CTraderApi::IsErrorRspInfo(CUstpFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) +bool CTraderApi::IsErrorRspInfo(const char* szSource, CUstpFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { bool bRet = ((pRspInfo) && (pRspInfo->ErrorID != 0)); if (bRet) @@ -122,6 +122,7 @@ bool CTraderApi::IsErrorRspInfo(CUstpFtdcRspInfoField *pRspInfo, int nRequestID, pField->ErrorID = pRspInfo->ErrorID; strcpy(pField->ErrorMsg, pRspInfo->ErrorMsg); + strcpy(pField->Source, szSource); m_msgQueue->Input_NoCopy(ResponeType::OnRtnError, m_msgQueue, m_pClass, bIsLast, 0, pField, sizeof(ErrorField), nullptr, 0, nullptr, 0); } @@ -487,6 +488,7 @@ int CTraderApi::ReqOrderInsert( OrderField* pField = (OrderField*)m_msgQueue->new_block(sizeof(OrderField)); memcpy(pField, pOrder, sizeof(OrderField)); strcpy(pField->ID, m_orderInsert_Id); + strcpy(pField->LocalID, pField->ID); m_id_platform_order.insert(pair(m_orderInsert_Id, pField)); } strncpy((char*)pInOut, m_orderInsert_Id, sizeof(OrderIDType)); @@ -506,7 +508,7 @@ void CTraderApi::OnRspOrderInsert(CUstpFtdcInputOrderField *pInputOrder, CUstpFt } else { - IsErrorRspInfo(pRspInfo, nRequestID, bIsLast); + IsErrorRspInfo("OnRspOrderInsert",pRspInfo, nRequestID, bIsLast); } unordered_map::iterator it = m_id_platform_order.find(orderId); @@ -550,7 +552,7 @@ void CTraderApi::OnErrRtnOrderInsert(CUstpFtdcInputOrderField *pInputOrder, CUst } else { - IsErrorRspInfo(pRspInfo, 0, true); + IsErrorRspInfo("OnErrRtnOrderInsert", pRspInfo, 0, true); } unordered_map::iterator it = m_id_platform_order.find(orderId); @@ -644,7 +646,7 @@ void CTraderApi::OnRspOrderAction(CUstpFtdcOrderActionField *pOrderAction, CUstp } else { - IsErrorRspInfo(pRspInfo, nRequestID, bIsLast); + IsErrorRspInfo("OnRspOrderAction", pRspInfo, nRequestID, bIsLast); } unordered_map::iterator it = m_id_platform_order.find(orderId); @@ -659,6 +661,7 @@ void CTraderApi::OnRspOrderAction(CUstpFtdcOrderActionField *pOrderAction, CUstp { OrderField* pField = it->second; strcpy(pField->ID, orderId); + strcpy(pField->LocalID, pField->ID); pField->ExecType = ExecType::ExecCancelled; pField->Status = OrderStatus::Cancelled; pField->ErrorID = pRspInfo->ErrorID; @@ -672,6 +675,7 @@ void CTraderApi::OnRspOrderAction(CUstpFtdcOrderActionField *pOrderAction, CUstp // ʹϴε״̬ OrderField* pField = it->second; strcpy(pField->ID, orderId); + strcpy(pField->LocalID, pField->ID); pField->ExecType = ExecType::ExecCancelReject; pField->ErrorID = pRspInfo->ErrorID; strncpy(pField->Text, pRspInfo->ErrorMsg, sizeof(ErrorMsgType)); @@ -691,7 +695,7 @@ void CTraderApi::OnErrRtnOrderAction(CUstpFtdcOrderActionField *pOrderAction, CU } else { - IsErrorRspInfo(pRspInfo, 0, true); + IsErrorRspInfo("OnErrRtnOrderAction", pRspInfo, 0, true); } unordered_map::iterator it = m_id_platform_order.find(orderId); @@ -706,6 +710,7 @@ void CTraderApi::OnErrRtnOrderAction(CUstpFtdcOrderActionField *pOrderAction, CU // ʹϴε״̬ OrderField* pField = it->second; strcpy(pField->ID, orderId); + strcpy(pField->LocalID, pField->ID); pField->ExecType = ExecType::ExecCancelReject; pField->ErrorID = pRspInfo->ErrorID; strncpy(pField->Text, pRspInfo->ErrorMsg, sizeof(ErrorMsgType)); @@ -1022,7 +1027,7 @@ int CTraderApi::_ReqQryInvestorAccount(char type, void* pApi1, void* pApi2, doub void CTraderApi::OnRspQryInvestorAccount(CUstpFtdcRspInvestorAccountField *pRspInvestorAccount, CUstpFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { - if (!IsErrorRspInfo(pRspInfo, nRequestID, bIsLast)) + if (!IsErrorRspInfo("OnRspQryInvestorAccount", pRspInfo, nRequestID, bIsLast)) { if (pRspInvestorAccount) { @@ -1067,7 +1072,7 @@ int CTraderApi::_ReqQryInvestorPosition(char type, void* pApi1, void* pApi2, dou void CTraderApi::OnRspQryInvestorPosition(CUstpFtdcRspInvestorPositionField *pRspInvestorPosition, CUstpFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { - if (!IsErrorRspInfo(pRspInfo, nRequestID, bIsLast)) + if (!IsErrorRspInfo("OnRspQryInvestorPosition", pRspInfo, nRequestID, bIsLast)) { if (pRspInvestorPosition) { @@ -1111,7 +1116,7 @@ int CTraderApi::_ReqQryInstrument(char type, void* pApi1, void* pApi2, double do void CTraderApi::OnRspQryInstrument(CUstpFtdcRspInstrumentField *pRspInstrument, CUstpFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { - if (!IsErrorRspInfo(pRspInfo, nRequestID, bIsLast)) + if (!IsErrorRspInfo("OnRspQryInstrument", pRspInfo, nRequestID, bIsLast)) { if (pRspInstrument) { @@ -1186,7 +1191,7 @@ void CTraderApi::OnRspQryInvestorFee(CUstpFtdcInvestorFeeField *pInvestorFee, CU void CTraderApi::OnRspError(CUstpFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { - IsErrorRspInfo(pRspInfo, nRequestID, bIsLast); + IsErrorRspInfo("OnRspError", pRspInfo, nRequestID, bIsLast); } void CTraderApi::ReqQryOrder() @@ -1250,6 +1255,7 @@ void CTraderApi::OnOrder(CUstpFtdcOrderField *pOrder) pField = (OrderField*)m_msgQueue->new_block(sizeof(OrderField)); strcpy(pField->ID, orderId); + strcpy(pField->LocalID, pField->ID); strcpy(pField->InstrumentID, pOrder->InstrumentID); strcpy(pField->ExchangeID, pOrder->ExchangeID); pField->HedgeFlag = TUstpFtdcHedgeFlagType_2_HedgeFlagType(pOrder->HedgeFlag); @@ -1274,6 +1280,7 @@ void CTraderApi::OnOrder(CUstpFtdcOrderField *pOrder) { pField = it->second; strcpy(pField->ID, orderId); + strcpy(pField->LocalID, pField->ID); pField->LeavesQty = pOrder->VolumeRemain; pField->Price = pOrder->LimitPrice; pField->Status = CUstpFtdcOrderField_2_OrderStatus(pOrder); @@ -1288,7 +1295,7 @@ void CTraderApi::OnOrder(CUstpFtdcOrderField *pOrder) void CTraderApi::OnRspQryOrder(CUstpFtdcOrderField *pOrder, CUstpFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { - if (!IsErrorRspInfo(pRspInfo, nRequestID, bIsLast)) + if (!IsErrorRspInfo("OnRspQryOrder", pRspInfo, nRequestID, bIsLast)) { OnOrder(pOrder); } @@ -1363,7 +1370,7 @@ void CTraderApi::OnTrade(CUstpFtdcTradeField *pTrade) void CTraderApi::OnRspQryTrade(CUstpFtdcTradeField *pTrade, CUstpFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { - if (!IsErrorRspInfo(pRspInfo, nRequestID, bIsLast)) + if (!IsErrorRspInfo("OnRspQryTrade", pRspInfo, nRequestID, bIsLast)) { OnTrade(pTrade); } diff --git a/QuantBox_Femas_Trade/TraderApi.h b/QuantBox_Femas_Trade/TraderApi.h index d2c91b7..ec0cccc 100644 --- a/QuantBox_Femas_Trade/TraderApi.h +++ b/QuantBox_Femas_Trade/TraderApi.h @@ -116,7 +116,7 @@ class CTraderApi : //void OnQuote(CUstpFtdcRtnQuoteField *pQuote); //Ƿ - bool IsErrorRspInfo(CUstpFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast);//ϢϢ + bool IsErrorRspInfo(const char* szSource, CUstpFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast);//ϢϢ bool IsErrorRspInfo(CUstpFtdcRspInfoField *pRspInfo);//Ϣ // diff --git a/QuantBox_Femas_Trade/main.cpp b/QuantBox_Femas_Trade/main.cpp index bce63ad..8a37eef 100644 --- a/QuantBox_Femas_Trade/main.cpp +++ b/QuantBox_Femas_Trade/main.cpp @@ -14,7 +14,7 @@ void* __stdcall XRequest(char type, void* pApi1, void* pApi2, double double1, do switch (rt) { case GetApiType: - return (void*)(ApiType::Trade | ApiType::Instrument); + return (void*)(ApiType::Trade | ApiType::Instrument | ApiType::Query_); case GetApiVersion: return (void*)"0.3.0.20150407"; case GetApiName: diff --git a/QuantBox_KingstarGold/QuantBox_KingstarGold.vcxproj b/QuantBox_KingstarGold/QuantBox_KingstarGold.vcxproj index b0ee9df..7800d75 100644 --- a/QuantBox_KingstarGold/QuantBox_KingstarGold.vcxproj +++ b/QuantBox_KingstarGold/QuantBox_KingstarGold.vcxproj @@ -94,6 +94,7 @@ true + C:\Program Files\SmartQuant Ltd\OpenQuant 2014\XAPI\KingstarGold\x86 true diff --git a/QuantBox_KingstarGold/TraderApi.cpp b/QuantBox_KingstarGold/TraderApi.cpp index 8d87913..d7111c7 100644 --- a/QuantBox_KingstarGold/TraderApi.cpp +++ b/QuantBox_KingstarGold/TraderApi.cpp @@ -105,7 +105,7 @@ CTraderApi::~CTraderApi(void) Disconnect(); } -bool CTraderApi::IsErrorRspInfo(CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) +bool CTraderApi::IsErrorRspInfo(const char* szSource, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { bool bRet = ((pRspInfo) && (pRspInfo->ErrorID != 0)); if (bRet) @@ -114,6 +114,7 @@ bool CTraderApi::IsErrorRspInfo(CThostFtdcRspInfoField *pRspInfo, int nRequestID pField->ErrorID = pRspInfo->ErrorID; strcpy(pField->ErrorMsg, pRspInfo->ErrorMsg); + strcpy(pField->Source, szSource); m_msgQueue->Input_NoCopy(ResponeType::OnRtnError, m_msgQueue, m_pClass, bIsLast, 0, pField, sizeof(ErrorField), nullptr, 0, nullptr, 0); } @@ -1049,7 +1050,7 @@ int CTraderApi::_ReqQryInstrument(char type, void* pApi1, void* pApi2, double do void CTraderApi::OnRspQryInstrument(CThostFtdcInstrumentField *pInstrument, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { - if (!IsErrorRspInfo(pRspInfo, nRequestID, bIsLast)) + if (!IsErrorRspInfo("OnRspQryInstrument", pRspInfo, nRequestID, bIsLast)) { if (pInstrument) { @@ -1198,7 +1199,7 @@ void CTraderApi::OnRspQryInstrument(CThostFtdcInstrumentField *pInstrument, CTho void CTraderApi::OnRspError(CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { - IsErrorRspInfo(pRspInfo, nRequestID, bIsLast); + IsErrorRspInfo("OnRspError", pRspInfo, nRequestID, bIsLast); } void CTraderApi::ReqQryOrder() @@ -1299,7 +1300,7 @@ void CTraderApi::OnOrder(CThostFtdcOrderField *pOrder) void CTraderApi::OnRspQryOrder(CThostFtdcOrderField *pOrder, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { - if (!IsErrorRspInfo(pRspInfo, nRequestID, bIsLast)) + if (!IsErrorRspInfo("OnRspQryOrder", pRspInfo, nRequestID, bIsLast)) { OnOrder(pOrder); } @@ -1370,7 +1371,7 @@ void CTraderApi::OnTrade(CThostFtdcTradeField *pTrade) void CTraderApi::OnRspQryTrade(CThostFtdcTradeField *pTrade, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { - if (!IsErrorRspInfo(pRspInfo, nRequestID, bIsLast)) + if (!IsErrorRspInfo("OnRspQryTrade", pRspInfo, nRequestID, bIsLast)) { OnTrade(pTrade); } diff --git a/QuantBox_KingstarGold/TraderApi.h b/QuantBox_KingstarGold/TraderApi.h index 5ce8b5d..633dbd1 100644 --- a/QuantBox_KingstarGold/TraderApi.h +++ b/QuantBox_KingstarGold/TraderApi.h @@ -107,7 +107,7 @@ class CTraderApi : void OnTrade(CThostFtdcTradeField *pTrade); //Ƿ - bool IsErrorRspInfo(CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast);//ϢϢ + bool IsErrorRspInfo(const char* szSource, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast);//ϢϢ bool IsErrorRspInfo(CThostFtdcRspInfoField *pRspInfo);//Ϣ // diff --git a/QuantBox_KingstarGold/main.cpp b/QuantBox_KingstarGold/main.cpp index 56c965d..73ba32c 100644 --- a/QuantBox_KingstarGold/main.cpp +++ b/QuantBox_KingstarGold/main.cpp @@ -14,7 +14,7 @@ void* __stdcall XRequest(char type, void* pApi1, void* pApi2, double double1, do switch (rt) { case GetApiType: - return (void*)(ApiType::Trade | ApiType::MarketData | ApiType::Instrument); + return (void*)(ApiType::Trade | ApiType::MarketData | ApiType::Instrument | ApiType::Query_); case GetApiVersion: return (void*)"0.3.0.20150407"; case GetApiName: diff --git a/QuantBox_KingstarStock_Trade/TraderApi.cpp b/QuantBox_KingstarStock_Trade/TraderApi.cpp index 8e2019d..ba62ed8 100644 --- a/QuantBox_KingstarStock_Trade/TraderApi.cpp +++ b/QuantBox_KingstarStock_Trade/TraderApi.cpp @@ -279,7 +279,7 @@ void CTraderApi::Register(void* pCallback, void* pClass) } } -bool CTraderApi::IsErrorRspInfo(STRspMsg *pRspInfo, int nRequestID, bool bIsLast) +bool CTraderApi::IsErrorRspInfo(const char* szSource, STRspMsg *pRspInfo, int nRequestID, bool bIsLast) { bool bRet = ((pRspInfo) && (pRspInfo->error_no != 0)); if (bRet) @@ -288,6 +288,7 @@ bool CTraderApi::IsErrorRspInfo(STRspMsg *pRspInfo, int nRequestID, bool bIsLast pField->ErrorID = pRspInfo->error_no; strcpy(pField->ErrorMsg, pRspInfo->msg); + strcpy(pField->Source, szSource); m_msgQueue->Input_NoCopy(ResponeType::OnRtnError, m_msgQueue, m_pClass, bIsLast, 0, pField, sizeof(ErrorField), nullptr, 0, nullptr, 0); } diff --git a/QuantBox_KingstarStock_Trade/TraderApi.h b/QuantBox_KingstarStock_Trade/TraderApi.h index 67729fe..28ea42c 100644 --- a/QuantBox_KingstarStock_Trade/TraderApi.h +++ b/QuantBox_KingstarStock_Trade/TraderApi.h @@ -133,7 +133,7 @@ class CTraderApi //Ƿ - bool IsErrorRspInfo(STRspMsg *pRspInfo, int nRequestID, bool bIsLast);//ϢϢ + bool IsErrorRspInfo(const char* szSource, STRspMsg *pRspInfo, int nRequestID, bool bIsLast);//ϢϢ bool IsErrorRspInfo(STRspMsg *pRspInfo);//Ϣ //// diff --git a/QuantBox_KingstarStock_Trade/main.cpp b/QuantBox_KingstarStock_Trade/main.cpp index 4aa7556..aadf923 100644 --- a/QuantBox_KingstarStock_Trade/main.cpp +++ b/QuantBox_KingstarStock_Trade/main.cpp @@ -14,7 +14,7 @@ void* __stdcall XRequest(char type, void* pApi1, void* pApi2, double double1, do switch (rt) { case GetApiType: - return (void*)(ApiType::Trade | ApiType::Instrument); + return (void*)(ApiType::Trade | ApiType::Instrument | ApiType::Query_); case GetApiVersion: return (void*)"0.3.0.20150407"; case GetApiName: diff --git a/QuantBox_Kingstar_Quote/MdUserApi.cpp b/QuantBox_Kingstar_Quote/MdUserApi.cpp index c697115..6cde5a8 100644 --- a/QuantBox_Kingstar_Quote/MdUserApi.cpp +++ b/QuantBox_Kingstar_Quote/MdUserApi.cpp @@ -101,7 +101,7 @@ ConfigInfoField* CMdUserApi::Config(ConfigInfoField* pConfigInfo) return nullptr; } -bool CMdUserApi::IsErrorRspInfo(CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) +bool CMdUserApi::IsErrorRspInfo(const char* szSource, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { bool bRet = ((pRspInfo) && (pRspInfo->ErrorID != 0)); if (bRet) @@ -110,6 +110,7 @@ bool CMdUserApi::IsErrorRspInfo(CThostFtdcRspInfoField *pRspInfo, int nRequestID pField->ErrorID = pRspInfo->ErrorID; strcpy(pField->ErrorMsg, pRspInfo->ErrorMsg); + strcpy(pField->Source, szSource); m_msgQueue->Input_NoCopy(ResponeType::OnRtnError, m_msgQueue, m_pClass, bIsLast, 0, pField, sizeof(ErrorField), nullptr, 0, nullptr, 0); } @@ -433,13 +434,13 @@ void CMdUserApi::OnRspUserLogin(CThostFtdcRspUserLoginField *pRspUserLogin, CTho void CMdUserApi::OnRspError(CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { - IsErrorRspInfo(pRspInfo, nRequestID, bIsLast); + IsErrorRspInfo("OnRspError", pRspInfo, nRequestID, bIsLast); } void CMdUserApi::OnRspSubMarketData(CThostFtdcSpecificInstrumentField *pSpecificInstrument, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { //ģƽ̨ᴥҪԼάһѾĵĺԼб - if (!IsErrorRspInfo(pRspInfo, nRequestID, bIsLast) + if (!IsErrorRspInfo("OnRspSubMarketData", pRspInfo, nRequestID, bIsLast) && pSpecificInstrument) { lock_guard cl(m_csMapInstrumentIDs); @@ -451,7 +452,7 @@ void CMdUserApi::OnRspSubMarketData(CThostFtdcSpecificInstrumentField *pSpecific void CMdUserApi::OnRspUnSubMarketData(CThostFtdcSpecificInstrumentField *pSpecificInstrument, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { //ģƽ̨ᴥ - if (!IsErrorRspInfo(pRspInfo, nRequestID, bIsLast) + if (!IsErrorRspInfo("OnRspUnSubMarketData", pRspInfo, nRequestID, bIsLast) && pSpecificInstrument) { lock_guard cl(m_csMapInstrumentIDs); @@ -579,7 +580,7 @@ void CMdUserApi::OnRtnDepthMarketData(CThostFtdcDepthMarketDataField *pDepthMark void CMdUserApi::OnRspSubForQuoteRsp(CThostFtdcSpecificInstrumentField *pSpecificInstrument, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { - if (!IsErrorRspInfo(pRspInfo, nRequestID, bIsLast) + if (!IsErrorRspInfo("OnRspSubForQuoteRsp", pRspInfo, nRequestID, bIsLast) && pSpecificInstrument) { lock_guard cl(m_csMapQuoteInstrumentIDs); @@ -590,7 +591,7 @@ void CMdUserApi::OnRspSubForQuoteRsp(CThostFtdcSpecificInstrumentField *pSpecifi void CMdUserApi::OnRspUnSubForQuoteRsp(CThostFtdcSpecificInstrumentField *pSpecificInstrument, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { - if (!IsErrorRspInfo(pRspInfo, nRequestID, bIsLast) + if (!IsErrorRspInfo("OnRspUnSubForQuoteRsp", pRspInfo, nRequestID, bIsLast) && pSpecificInstrument) { lock_guard cl(m_csMapQuoteInstrumentIDs); diff --git a/QuantBox_Kingstar_Quote/MdUserApi.h b/QuantBox_Kingstar_Quote/MdUserApi.h index 9c398b1..823a84a 100644 --- a/QuantBox_Kingstar_Quote/MdUserApi.h +++ b/QuantBox_Kingstar_Quote/MdUserApi.h @@ -77,7 +77,7 @@ class CMdUserApi : virtual void OnRtnForQuoteRsp(CThostFtdcForQuoteRspField *pForQuoteRsp); //Ƿ - bool IsErrorRspInfo(CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast);//Ϣ͵Ϣ + bool IsErrorRspInfo(const char* szSource, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast);//Ϣ͵Ϣ bool IsErrorRspInfo(CThostFtdcRspInfoField *pRspInfo);//ͳϢ private: diff --git a/QuantBox_Kingstar_Trade/TraderApi.cpp b/QuantBox_Kingstar_Trade/TraderApi.cpp index a7bd027..d8b7b71 100644 --- a/QuantBox_Kingstar_Trade/TraderApi.cpp +++ b/QuantBox_Kingstar_Trade/TraderApi.cpp @@ -121,7 +121,7 @@ CTraderApi::~CTraderApi(void) Disconnect(); } -bool CTraderApi::IsErrorRspInfo(CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) +bool CTraderApi::IsErrorRspInfo(const char* szSource, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { bool bRet = ((pRspInfo) && (pRspInfo->ErrorID != 0)); if (bRet) @@ -130,6 +130,7 @@ bool CTraderApi::IsErrorRspInfo(CThostFtdcRspInfoField *pRspInfo, int nRequestID pField->ErrorID = pRspInfo->ErrorID; strcpy(pField->ErrorMsg, pRspInfo->ErrorMsg); + strcpy(pField->Source, szSource); m_msgQueue->Input_NoCopy(ResponeType::OnRtnError, m_msgQueue, m_pClass, bIsLast, 0, pField, sizeof(ErrorField), nullptr, 0, nullptr, 0); } @@ -557,6 +558,7 @@ int CTraderApi::ReqOrderInsert( OrderField* pField = (OrderField*)m_msgQueue->new_block(sizeof(OrderField)); memcpy(pField, pOrder, sizeof(OrderField)); strcpy(pField->ID, m_orderInsert_Id); + strcpy(pField->LocalID, pField->ID); m_id_platform_order.insert(pair(m_orderInsert_Id, pField)); } @@ -576,7 +578,7 @@ void CTraderApi::OnRspOrderInsert(CThostFtdcInputOrderField *pInputOrder, CThost } else { - IsErrorRspInfo(pRspInfo, nRequestID, bIsLast); + IsErrorRspInfo("OnRspOrderInsert", pRspInfo, nRequestID, bIsLast); } unordered_map::iterator it = m_id_platform_order.find(orderId); @@ -608,7 +610,7 @@ void CTraderApi::OnErrRtnOrderInsert(CThostFtdcInputOrderField *pInputOrder, CTh } else { - IsErrorRspInfo(pRspInfo, 0, true); + IsErrorRspInfo("OnErrRtnOrderInsert", pRspInfo, 0, true); } unordered_map::iterator it = m_id_platform_order.find(orderId); @@ -700,7 +702,7 @@ void CTraderApi::OnRspOrderAction(CThostFtdcInputOrderActionField *pInputOrderAc } else { - IsErrorRspInfo(pRspInfo, nRequestID, bIsLast); + IsErrorRspInfo("OnRspOrderAction", pRspInfo, nRequestID, bIsLast); } unordered_map::iterator it = m_id_platform_order.find(orderId); @@ -715,6 +717,7 @@ void CTraderApi::OnRspOrderAction(CThostFtdcInputOrderActionField *pInputOrderAc // ʹϴε״̬ OrderField* pField = it->second; strcpy(pField->ID, orderId); + strcpy(pField->LocalID, pField->ID); pField->ExecType = ExecType::ExecCancelReject; pField->ErrorID = pRspInfo->ErrorID; strncpy(pField->Text, pRspInfo->ErrorMsg, sizeof(ErrorMsgType)); @@ -731,7 +734,7 @@ void CTraderApi::OnErrRtnOrderAction(CThostFtdcOrderActionField *pOrderAction, C } else { - IsErrorRspInfo(pRspInfo, 0, true); + IsErrorRspInfo("OnErrRtnOrderAction", pRspInfo, 0, true); } unordered_map::iterator it = m_id_platform_order.find(orderId); @@ -746,6 +749,7 @@ void CTraderApi::OnErrRtnOrderAction(CThostFtdcOrderActionField *pOrderAction, C // ʹϴε״̬ OrderField* pField = it->second; strcpy(pField->ID, orderId); + strcpy(pField->LocalID, pField->ID); pField->ExecType = ExecType::ExecCancelReject; pField->ErrorID = pRspInfo->ErrorID; strncpy(pField->Text, pRspInfo->ErrorMsg, sizeof(ErrorMsgType)); @@ -827,6 +831,7 @@ char* CTraderApi::ReqQuoteInsert( QuoteField* pField = (QuoteField*)m_msgQueue->new_block(sizeof(QuoteField)); memcpy(pField, pQuote, sizeof(QuoteField)); strcpy(pField->ID, m_orderInsert_Id); + strcpy(pField->LocalID, pField->ID); strcpy(pField->AskID, m_orderInsert_Id); sprintf(pField->BidID, "%d:%d:%d", m_RspUserLogin.FrontID, m_RspUserLogin.SessionID, nRet + 1); @@ -847,7 +852,7 @@ void CTraderApi::OnRspQuoteInsert(CThostFtdcInputQuoteField *pInputQuote, CThost } else { - IsErrorRspInfo(pRspInfo, nRequestID, bIsLast); + IsErrorRspInfo("OnRspQuoteInsert", pRspInfo, nRequestID, bIsLast); } unordered_map::iterator it = m_id_platform_quote.find(quoteId); @@ -879,7 +884,7 @@ void CTraderApi::OnErrRtnQuoteInsert(CThostFtdcInputQuoteField *pInputQuote, CTh } else { - IsErrorRspInfo(pRspInfo, 0, true); + IsErrorRspInfo("OnErrRtnQuoteInsert", pRspInfo, 0, true); } unordered_map::iterator it = m_id_platform_quote.find(quoteId); @@ -971,7 +976,7 @@ void CTraderApi::OnRspQuoteAction(CThostFtdcInputQuoteActionField *pInputQuoteAc } else { - IsErrorRspInfo(pRspInfo, nRequestID, bIsLast); + IsErrorRspInfo("OnRspQuoteAction", pRspInfo, nRequestID, bIsLast); } unordered_map::iterator it = m_id_platform_quote.find(quoteId); @@ -986,6 +991,7 @@ void CTraderApi::OnRspQuoteAction(CThostFtdcInputQuoteActionField *pInputQuoteAc // ʹϴε״̬ QuoteField* pField = it->second; strcpy(pField->ID, quoteId); + strcpy(pField->LocalID, pField->ID); //sprintf(pField->AskID, "%d:%d:%s", pInputQuoteAction->FrontID, pInputQuoteAction->SessionID, pInputQuoteAction->); //sprintf(pField->BidID, "%d:%d:%s", pInputQuoteAction->FrontID, pInputQuoteAction->SessionID, pInputQuoteAction->QuoteRef); pField->ExecType = ExecType::ExecCancelReject; @@ -1005,7 +1011,7 @@ void CTraderApi::OnErrRtnQuoteAction(CThostFtdcQuoteActionField *pQuoteAction, C } else { - IsErrorRspInfo(pRspInfo, 0, true); + IsErrorRspInfo("OnErrRtnQuoteAction", pRspInfo, 0, true); } unordered_map::iterator it = m_id_platform_quote.find(quoteId); @@ -1020,6 +1026,7 @@ void CTraderApi::OnErrRtnQuoteAction(CThostFtdcQuoteActionField *pQuoteAction, C // ʹϴε״̬ QuoteField* pField = it->second; strcpy(pField->ID, quoteId); + strcpy(pField->LocalID, pField->ID); pField->ExecType = ExecType::ExecCancelReject; pField->ErrorID = pRspInfo->ErrorID; strncpy(pField->Text, pRspInfo->ErrorMsg, sizeof(ErrorMsgType)); @@ -1045,7 +1052,7 @@ int CTraderApi::_ReqQryTradingAccount(char type, void* pApi1, void* pApi2, doubl void CTraderApi::OnRspQryTradingAccount(CThostFtdcTradingAccountField *pTradingAccount, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { - if (!IsErrorRspInfo(pRspInfo, nRequestID, bIsLast)) + if (!IsErrorRspInfo("OnRspQryTradingAccount", pRspInfo, nRequestID, bIsLast)) { if (pTradingAccount) { @@ -1092,7 +1099,7 @@ int CTraderApi::_ReqQryInvestorPosition(char type, void* pApi1, void* pApi2, dou // Ŀǰû⣬Ҳֻ void CTraderApi::OnRspQryInvestorPosition(CThostFtdcInvestorPositionField *pInvestorPosition, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { - if (!IsErrorRspInfo(pRspInfo, nRequestID, bIsLast)) + if (!IsErrorRspInfo("OnRspQryInvestorPosition", pRspInfo, nRequestID, bIsLast)) { if (pInvestorPosition) { @@ -1161,7 +1168,7 @@ int CTraderApi::_ReqQryInstrument(char type, void* pApi1, void* pApi2, double do void CTraderApi::OnRspQryInstrument(CThostFtdcInstrumentField *pInstrument, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { - if (!IsErrorRspInfo(pRspInfo, nRequestID, bIsLast)) + if (!IsErrorRspInfo("OnRspQryInstrument", pRspInfo, nRequestID, bIsLast)) { if (pInstrument) { @@ -1255,7 +1262,7 @@ void CTraderApi::OnRspQryInstrument(CThostFtdcInstrumentField *pInstrument, CTho void CTraderApi::OnRspError(CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { - IsErrorRspInfo(pRspInfo, nRequestID, bIsLast); + IsErrorRspInfo("OnRspError", pRspInfo, nRequestID, bIsLast); } void CTraderApi::ReqQryOrder() @@ -1317,6 +1324,7 @@ void CTraderApi::OnOrder(CThostFtdcOrderField *pOrder) // ʱϢûУҲӦĵӣҪOrderĻָ pField = (OrderField*)m_msgQueue->new_block(sizeof(OrderField)); strcpy(pField->ID, orderId); + strcpy(pField->LocalID, pField->ID); strcpy(pField->InstrumentID, pOrder->InstrumentID); strcpy(pField->ExchangeID, pOrder->ExchangeID); pField->HedgeFlag = TThostFtdcHedgeFlagType_2_HedgeFlagType(pOrder->CombHedgeFlag[0]); @@ -1340,6 +1348,7 @@ void CTraderApi::OnOrder(CThostFtdcOrderField *pOrder) { pField = it->second; strcpy(pField->ID, orderId); + strcpy(pField->LocalID, pField->ID); pField->LeavesQty = pOrder->VolumeTotal; pField->Price = pOrder->LimitPrice; pField->Status = CThostFtdcOrderField_2_OrderStatus(pOrder); @@ -1354,7 +1363,7 @@ void CTraderApi::OnOrder(CThostFtdcOrderField *pOrder) void CTraderApi::OnRspQryOrder(CThostFtdcOrderField *pOrder, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { - if (!IsErrorRspInfo(pRspInfo, nRequestID, bIsLast)) + if (!IsErrorRspInfo("OnRspQryOrder", pRspInfo, nRequestID, bIsLast)) { OnOrder(pOrder); } @@ -1484,7 +1493,7 @@ void CTraderApi::OnTrade(TradeField *pTrade) void CTraderApi::OnRspQryTrade(CThostFtdcTradeField *pTrade, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { - if (!IsErrorRspInfo(pRspInfo, nRequestID, bIsLast)) + if (!IsErrorRspInfo("OnRspQryTrade", pRspInfo, nRequestID, bIsLast)) { OnTrade(pTrade); } @@ -1565,6 +1574,7 @@ void CTraderApi::OnQuote(CThostFtdcQuoteField *pQuote) pField->BidHedgeFlag = TThostFtdcHedgeFlagType_2_HedgeFlagType(pQuote->BidHedgeFlag); strcpy(pField->ID, quoteId); + strcpy(pField->LocalID, pField->ID); strcpy(pField->AskOrderID, pQuote->AskOrderSysID); strcpy(pField->BidOrderID, pQuote->BidOrderSysID); @@ -1583,6 +1593,7 @@ void CTraderApi::OnQuote(CThostFtdcQuoteField *pQuote) pField = it->second; strcpy(pField->ID, quoteId); + strcpy(pField->LocalID, pField->ID); strcpy(pField->AskOrderID, pQuote->AskOrderSysID); strcpy(pField->BidOrderID, pQuote->BidOrderSysID); @@ -1598,7 +1609,7 @@ void CTraderApi::OnQuote(CThostFtdcQuoteField *pQuote) void CTraderApi::OnRspQryQuote(CThostFtdcQuoteField *pQuote, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { - if (!IsErrorRspInfo(pRspInfo, nRequestID, bIsLast)) + if (!IsErrorRspInfo("OnRspQryQuote", pRspInfo, nRequestID, bIsLast)) { OnQuote(pQuote); } @@ -1626,7 +1637,7 @@ int CTraderApi::_ReqQryInvestor(char type, void* pApi1, void* pApi2, double doub void CTraderApi::OnRspQryInvestor(CThostFtdcInvestorField *pInvestor, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { - if (!IsErrorRspInfo(pRspInfo, nRequestID, bIsLast)) + if (!IsErrorRspInfo("OnRspQryInvestor", pRspInfo, nRequestID, bIsLast)) { if (pInvestor) { diff --git a/QuantBox_Kingstar_Trade/TraderApi.h b/QuantBox_Kingstar_Trade/TraderApi.h index 500ca96..f34211f 100644 --- a/QuantBox_Kingstar_Trade/TraderApi.h +++ b/QuantBox_Kingstar_Trade/TraderApi.h @@ -139,7 +139,7 @@ class CTraderApi : void OnTrade(TradeField *pTrade); //Ƿ - bool IsErrorRspInfo(CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast);//ϢϢ + bool IsErrorRspInfo(const char* szSource, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast);//ϢϢ bool IsErrorRspInfo(CThostFtdcRspInfoField *pRspInfo);//Ϣ // diff --git a/QuantBox_Kingstar_Trade/main.cpp b/QuantBox_Kingstar_Trade/main.cpp index 656a88e..3ae95ab 100644 --- a/QuantBox_Kingstar_Trade/main.cpp +++ b/QuantBox_Kingstar_Trade/main.cpp @@ -14,7 +14,7 @@ void* __stdcall XRequest(char type, void* pApi1, void* pApi2, double double1, do switch (rt) { case GetApiType: - return (void*)(ApiType::Trade | ApiType::Instrument); + return (void*)(ApiType::Trade | ApiType::Instrument | ApiType::Query_); case GetApiVersion: return (void*)"0.3.0.20150815"; case GetApiName: diff --git a/QuantBox_LTS_Level2/Level2UserApi.cpp b/QuantBox_LTS_Level2/Level2UserApi.cpp index f4a073e..ab0413b 100644 --- a/QuantBox_LTS_Level2/Level2UserApi.cpp +++ b/QuantBox_LTS_Level2/Level2UserApi.cpp @@ -27,7 +27,7 @@ ExchangeType TSecurityFtdcExchangeIDType_2_ExchangeType(TSecurityFtdcExchangeIDT case 'S': return ExchangeType::SSE; case 'Z': - return ExchangeType::SZE; + return ExchangeType::SZSE; default: return ExchangeType::Undefined_; } @@ -113,7 +113,7 @@ void CLevel2UserApi::Register(void* pCallback, void* pClass) } } -bool CLevel2UserApi::IsErrorRspInfo(CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) +bool CLevel2UserApi::IsErrorRspInfo(const char* szSource, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { bool bRet = ((pRspInfo) && (pRspInfo->ErrorID != 0)); if (bRet) @@ -122,6 +122,7 @@ bool CLevel2UserApi::IsErrorRspInfo(CSecurityFtdcRspInfoField *pRspInfo, int nRe pField->ErrorID = pRspInfo->ErrorID; strcpy(pField->ErrorMsg, pRspInfo->ErrorMsg); + strcpy(pField->Source, szSource); m_msgQueue->Input_NoCopy(ResponeType::OnRtnError, m_msgQueue, m_pClass, bIsLast, 0, pField, sizeof(ErrorField), nullptr, 0, nullptr, 0); } @@ -323,7 +324,7 @@ void CLevel2UserApi::OnRspUserLogin(CSecurityFtdcUserLoginField *pUserLogin, CSe void CLevel2UserApi::OnRspError(CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { - IsErrorRspInfo(pRspInfo, nRequestID, bIsLast); + IsErrorRspInfo("OnRspError", pRspInfo, nRequestID, bIsLast); } char* GetSetFromString_Index_Stock(const char* szString, const char* seps, @@ -593,7 +594,7 @@ void CLevel2UserApi::Subscribe(const set& instrumentIDs, const string& s void CLevel2UserApi::OnRspSubL2MarketData(CSecurityFtdcSpecificInstrumentField *pSpecificInstrument, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { //ģƽ̨ᴥҪԼάһѾĵĺԼб - if(!IsErrorRspInfo(pRspInfo,nRequestID,bIsLast) + if (!IsErrorRspInfo("OnRspSubL2MarketData", pRspInfo, nRequestID, bIsLast) && pSpecificInstrument) { lock_guard cl(m_csMapIDs); @@ -613,7 +614,7 @@ void CLevel2UserApi::OnRspSubL2MarketData(CSecurityFtdcSpecificInstrumentField * void CLevel2UserApi::OnRspUnSubL2MarketData(CSecurityFtdcSpecificInstrumentField *pSpecificInstrument, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { //ģƽ̨ᴥ - if(!IsErrorRspInfo(pRspInfo,nRequestID,bIsLast) + if (!IsErrorRspInfo("OnRspUnSubL2MarketData", pRspInfo, nRequestID, bIsLast) && pSpecificInstrument) { lock_guard cl(m_csMapIDs); @@ -855,7 +856,7 @@ void CLevel2UserApi::OnRtnL2MarketData(CSecurityFtdcL2MarketDataField *pL2Market void CLevel2UserApi::OnRspSubL2Index(CSecurityFtdcSpecificInstrumentField *pSpecificInstrument, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { //ģƽ̨ᴥҪԼάһѾĵĺԼб - if (!IsErrorRspInfo(pRspInfo, nRequestID, bIsLast) + if (!IsErrorRspInfo("OnRspSubL2Index", pRspInfo, nRequestID, bIsLast) && pSpecificInstrument) { lock_guard cl(m_csMapIDs); @@ -875,7 +876,7 @@ void CLevel2UserApi::OnRspSubL2Index(CSecurityFtdcSpecificInstrumentField *pSpec void CLevel2UserApi::OnRspUnSubL2Index(CSecurityFtdcSpecificInstrumentField *pSpecificInstrument, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { //ģƽ̨ᴥ - if (!IsErrorRspInfo(pRspInfo, nRequestID, bIsLast) + if (!IsErrorRspInfo("OnRspUnSubL2Index", pRspInfo, nRequestID, bIsLast) && pSpecificInstrument) { lock_guard cl(m_csMapIDs); diff --git a/QuantBox_LTS_Level2/Level2UserApi.h b/QuantBox_LTS_Level2/Level2UserApi.h index 26c948f..4461cee 100644 --- a/QuantBox_LTS_Level2/Level2UserApi.h +++ b/QuantBox_LTS_Level2/Level2UserApi.h @@ -79,7 +79,7 @@ class CLevel2UserApi :public CSecurityFtdcL2MDUserSpi private: //Ƿ - bool IsErrorRspInfo(CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast);//Ϣ͵Ϣ + bool IsErrorRspInfo(const char* szSource, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast);//Ϣ͵Ϣ bool IsErrorRspInfo(CSecurityFtdcRspInfoField *pRspInfo);//ͳϢ private: diff --git a/QuantBox_LTS_Query_v2/QuantBox_LTS_Query_v2.vcxproj b/QuantBox_LTS_Query_v2/QuantBox_LTS_Query_v2.vcxproj new file mode 100644 index 0000000..ffef572 --- /dev/null +++ b/QuantBox_LTS_Query_v2/QuantBox_LTS_Query_v2.vcxproj @@ -0,0 +1,116 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {51D11C21-C4A7-4F07-9658-B8BA223684B8} + Win32Proj + QuantBox_LTS_Query_v2 + + + + DynamicLibrary + true + v120 + Unicode + + + DynamicLibrary + false + v120 + true + Unicode + + + + + + + + + + + + + true + C:\Program Files\SmartQuant Ltd\OpenQuant 2014\XAPI\LTS_v2\x86 + + + false + + + + Use + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;QUANTBOX_LTS_QUERY_V2_EXPORTS;BUILDING_DLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + + + Windows + true + ..\include\ApiHeader.def + + + xcopy "$(TargetPath)" "$(SolutionDir)XAPI\LTS_v2\x86\" /Y + + + + + Level3 + Use + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;QUANTBOX_LTS_QUERY_V2_EXPORTS;%(PreprocessorDefinitions) + true + + + Windows + true + true + true + + + + + + + + + + + + + + + + + + + false + + + false + + + + + + + Create + Create + + + + + + \ No newline at end of file diff --git a/QuantBox_LTS_Query_v2/QuantBox_LTS_Query_v2.vcxproj.filters b/QuantBox_LTS_Query_v2/QuantBox_LTS_Query_v2.vcxproj.filters new file mode 100644 index 0000000..a2781ef --- /dev/null +++ b/QuantBox_LTS_Query_v2/QuantBox_LTS_Query_v2.vcxproj.filters @@ -0,0 +1,63 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/QuantBox_LTS_Trade_v2/QueryApi.cpp b/QuantBox_LTS_Query_v2/QueryApi.cpp similarity index 84% rename from QuantBox_LTS_Trade_v2/QueryApi.cpp rename to QuantBox_LTS_Query_v2/QueryApi.cpp index 907b6cd..8aff268 100644 --- a/QuantBox_LTS_Trade_v2/QueryApi.cpp +++ b/QuantBox_LTS_Query_v2/QueryApi.cpp @@ -11,7 +11,8 @@ #include "../QuantBox_Queue/MsgQueue.h" -#include "TypeConvert.h" +// õ뽻ͬһת +#include "../QuantBox_LTS_Trade_v2/TypeConvert.h" #include #include @@ -53,6 +54,9 @@ void CQueryApi::QueryInThread(char type, void* pApi1, void* pApi2, double double case E_QryTradeField: iRet = _ReqQryTrade(type, pApi1, pApi2, double1, double2, ptr1, size1, ptr2, size2, ptr3, size3); break; + case E_AuthRandCodeField: + iRet = _ReqFetchAuthRandCode(type, pApi1, pApi2, double1, double2, ptr1, size1, ptr2, size2, ptr3, size3); + break; default: break; } @@ -256,7 +260,8 @@ void CQueryApi::OnFrontConnected() { m_msgQueue->Input_NoCopy(ResponeType::OnConnectionStatus, m_msgQueue, m_pClass, ConnectionStatus::Connected, 0, nullptr, 0, nullptr, 0, nullptr, 0); - ReqUserLogin(); + //ReqUserLogin(); + ReqFetchAuthRandCode(); } void CQueryApi::OnFrontDisconnected(int nReason) @@ -270,7 +275,43 @@ void CQueryApi::OnFrontDisconnected(int nReason) m_msgQueue->Input_NoCopy(ResponeType::OnConnectionStatus, m_msgQueue, m_pClass, ConnectionStatus::Disconnected, 0, pField, sizeof(RspUserLoginField), nullptr, 0, nullptr, 0); } -void CQueryApi::ReqUserLogin() +void CQueryApi::ReqFetchAuthRandCode() +{ + CSecurityFtdcAuthRandCodeField* pBody = (CSecurityFtdcAuthRandCodeField*)m_msgQueue_Query->new_block(sizeof(CSecurityFtdcAuthRandCodeField)); + + strncpy(pBody->RandCode, "", sizeof(TSecurityFtdcAuthCodeType)); + + m_msgQueue_Query->Input_NoCopy(RequestType::E_AuthRandCodeField, m_msgQueue_Query, this, 0, 0, + pBody, sizeof(CSecurityFtdcAuthRandCodeField), nullptr, 0, nullptr, 0); +} + +int CQueryApi::_ReqFetchAuthRandCode(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3) +{ + m_msgQueue->Input_NoCopy(ResponeType::OnConnectionStatus, m_msgQueue, m_pClass, ConnectionStatus::Authorizing, 0, nullptr, 0, nullptr, 0, nullptr, 0); + return m_pApi->ReqFetchAuthRandCode((CSecurityFtdcAuthRandCodeField*)ptr1, ++m_lRequestID); +} + +void CQueryApi::OnRspFetchAuthRandCode(CSecurityFtdcAuthRandCodeField *pAuthRandCode, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) +{ + RspUserLoginField* pField = (RspUserLoginField*)m_msgQueue->new_block(sizeof(RspUserLoginField)); + + if (!IsErrorRspInfo(pRspInfo) + && pAuthRandCode) + { + m_msgQueue->Input_NoCopy(ResponeType::OnConnectionStatus, m_msgQueue, m_pClass, ConnectionStatus::Authorized, 0, pField, sizeof(RspUserLoginField), nullptr, 0, nullptr, 0); + + ReqUserLogin(pAuthRandCode->RandCode); + } + else + { + pField->ErrorID = pRspInfo->ErrorID; + strncpy(pField->ErrorMsg, pRspInfo->ErrorMsg, sizeof(ErrorMsgType)); + + m_msgQueue->Input_NoCopy(ResponeType::OnConnectionStatus, m_msgQueue, m_pClass, ConnectionStatus::Disconnected, 0, pField, sizeof(RspUserLoginField), nullptr, 0, nullptr, 0); + } +} + +void CQueryApi::ReqUserLogin(TSecurityFtdcAuthCodeType RandCode) { CSecurityFtdcReqUserLoginField* pBody = (CSecurityFtdcReqUserLoginField*)m_msgQueue_Query->new_block(sizeof(CSecurityFtdcReqUserLoginField)); @@ -278,6 +319,8 @@ void CQueryApi::ReqUserLogin() strncpy(pBody->UserID, m_UserInfo.UserID, sizeof(TSecurityFtdcInvestorIDType)); strncpy(pBody->Password, m_UserInfo.Password, sizeof(TSecurityFtdcPasswordType)); strncpy(pBody->UserProductInfo, m_ServerInfo.UserProductInfo, sizeof(TSecurityFtdcProductInfoType)); + strncpy(pBody->AuthCode, m_ServerInfo.AuthCode, sizeof(TSecurityFtdcAuthCodeType)); + strncpy(pBody->RandCode, RandCode, sizeof(TSecurityFtdcAuthCodeType)); m_msgQueue_Query->Input_NoCopy(RequestType::E_ReqUserLoginField, m_msgQueue_Query, this, 0, 0, pBody, sizeof(CSecurityFtdcReqUserLoginField), nullptr, 0, nullptr, 0); @@ -468,75 +511,75 @@ void CQueryApi::OnRspUserLogin(CSecurityFtdcRspUserLoginField *pRspUserLogin, CS // return nRet; //} -void CQueryApi::OnRspOrderInsert(CSecurityFtdcInputOrderField *pInputOrder, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) -{ - OrderIDType orderId = { 0 }; - if (pInputOrder) - { - sprintf(orderId, "%d:%d:%s", m_RspUserLogin.FrontID, m_RspUserLogin.SessionID, pInputOrder->OrderRef); - } - else - { - IsErrorRspInfo(pRspInfo, nRequestID, bIsLast); - } - - unordered_map::iterator it = m_id_platform_order.find(orderId); - if (it == m_id_platform_order.end()) - { - // ûҵӦʾ - //assert(false); - } - else - { - // ҵˣҪ״̬ - // ʹϴε״̬ - OrderField* pField = it->second; - strcpy(pField->ID, orderId); - pField->ExecType = ExecType::ExecRejected; - pField->Status = OrderStatus::Rejected; - pField->ErrorID = pRspInfo->ErrorID; - strncpy(pField->Text, pRspInfo->ErrorMsg, sizeof(ErrorMsgType)); - m_msgQueue->Input_Copy(ResponeType::OnRtnOrder, m_msgQueue, m_pClass, 0, 0, pField, sizeof(OrderField), nullptr, 0, nullptr, 0); - } -} - -void CQueryApi::OnErrRtnOrderInsert(CSecurityFtdcInputOrderField *pInputOrder, CSecurityFtdcRspInfoField *pRspInfo) -{ - OrderIDType orderId = { 0 }; - if (pInputOrder) - { - sprintf(orderId, "%d:%d:%s", m_RspUserLogin.FrontID, m_RspUserLogin.SessionID, pInputOrder->OrderRef); - } - else - { - IsErrorRspInfo(pRspInfo, 0, true); - } - - unordered_map::iterator it = m_id_platform_order.find(orderId); - if (it == m_id_platform_order.end()) - { - // ûҵӦʾ - //assert(false); - // LTSڿʼʱҲյ˻رﰡ - } - else - { - // ҵˣҪ״̬ - // ʹϴε״̬ - OrderField* pField = it->second; - strcpy(pField->ID, orderId); - pField->ExecType = ExecType::ExecRejected; - pField->Status = OrderStatus::Rejected; - pField->ErrorID = pRspInfo->ErrorID; - strncpy(pField->Text, pRspInfo->ErrorMsg, sizeof(ErrorMsgType)); - m_msgQueue->Input_Copy(ResponeType::OnRtnOrder, m_msgQueue, m_pClass, 0, 0, pField, sizeof(OrderField), nullptr, 0, nullptr, 0); - } -} +//void CQueryApi::OnRspOrderInsert(CSecurityFtdcInputOrderField *pInputOrder, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) +//{ +// OrderIDType orderId = { 0 }; +// if (pInputOrder) +// { +// sprintf(orderId, "%d:%d:%s", m_RspUserLogin.FrontID, m_RspUserLogin.SessionID, pInputOrder->OrderRef); +// } +// else +// { +// IsErrorRspInfo(pRspInfo, nRequestID, bIsLast); +// } +// +// unordered_map::iterator it = m_id_platform_order.find(orderId); +// if (it == m_id_platform_order.end()) +// { +// // ûҵӦʾ +// //assert(false); +// } +// else +// { +// // ҵˣҪ״̬ +// // ʹϴε״̬ +// OrderField* pField = it->second; +// strcpy(pField->ID, orderId); +// pField->ExecType = ExecType::ExecRejected; +// pField->Status = OrderStatus::Rejected; +// pField->ErrorID = pRspInfo->ErrorID; +// strncpy(pField->Text, pRspInfo->ErrorMsg, sizeof(ErrorMsgType)); +// m_msgQueue->Input_Copy(ResponeType::OnRtnOrder, m_msgQueue, m_pClass, 0, 0, pField, sizeof(OrderField), nullptr, 0, nullptr, 0); +// } +//} -void CQueryApi::OnRtnTrade(CSecurityFtdcTradeField *pTrade) -{ - OnTrade(pTrade,false); -} +//void CQueryApi::OnErrRtnOrderInsert(CSecurityFtdcInputOrderField *pInputOrder, CSecurityFtdcRspInfoField *pRspInfo) +//{ +// OrderIDType orderId = { 0 }; +// if (pInputOrder) +// { +// sprintf(orderId, "%d:%d:%s", m_RspUserLogin.FrontID, m_RspUserLogin.SessionID, pInputOrder->OrderRef); +// } +// else +// { +// IsErrorRspInfo(pRspInfo, 0, true); +// } +// +// unordered_map::iterator it = m_id_platform_order.find(orderId); +// if (it == m_id_platform_order.end()) +// { +// // ûҵӦʾ +// //assert(false); +// // LTSڿʼʱҲյ˻رﰡ +// } +// else +// { +// // ҵˣҪ״̬ +// // ʹϴε״̬ +// OrderField* pField = it->second; +// strcpy(pField->ID, orderId); +// pField->ExecType = ExecType::ExecRejected; +// pField->Status = OrderStatus::Rejected; +// pField->ErrorID = pRspInfo->ErrorID; +// strncpy(pField->Text, pRspInfo->ErrorMsg, sizeof(ErrorMsgType)); +// m_msgQueue->Input_Copy(ResponeType::OnRtnOrder, m_msgQueue, m_pClass, 0, 0, pField, sizeof(OrderField), nullptr, 0, nullptr, 0); +// } +//} +// +//void CQueryApi::OnRtnTrade(CSecurityFtdcTradeField *pTrade) +//{ +// OnTrade(pTrade,false); +//} //int CQueryApi::ReqOrderAction(OrderIDType* szIds, int count, OrderIDType* pOutput) //{ @@ -593,70 +636,70 @@ void CQueryApi::OnRtnTrade(CSecurityFtdcTradeField *pTrade) // return nRet; //} -void CQueryApi::OnRspOrderAction(CSecurityFtdcInputOrderActionField *pInputOrderAction, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) -{ - OrderIDType orderId = { 0 }; - if (pInputOrderAction) - { - sprintf(orderId, "%d:%d:%s", pInputOrderAction->FrontID, pInputOrderAction->SessionID, pInputOrderAction->OrderRef); - } - else - { - IsErrorRspInfo(pRspInfo, nRequestID, bIsLast); - } - - unordered_map::iterator it = m_id_platform_order.find(orderId); - if (it == m_id_platform_order.end()) - { - // ûҵӦʾ - //assert(false); - } - else - { - // ҵˣҪ״̬ - // ʹϴε״̬ - OrderField* pField = it->second; - pField->ExecType = ExecType::ExecCancelReject; - pField->ErrorID = pRspInfo->ErrorID; - strncpy(pField->Text, pRspInfo->ErrorMsg, sizeof(ErrorMsgType)); - m_msgQueue->Input_Copy(ResponeType::OnRtnOrder, m_msgQueue, m_pClass, 0, 0, pField, sizeof(OrderField), nullptr, 0, nullptr, 0); - } -} - -void CQueryApi::OnErrRtnOrderAction(CSecurityFtdcOrderActionField *pOrderAction, CSecurityFtdcRspInfoField *pRspInfo) -{ - OrderIDType orderId = { 0 }; - if (pOrderAction) - { - sprintf(orderId, "%d:%d:%s", pOrderAction->FrontID, pOrderAction->SessionID, pOrderAction->OrderRef); - } - else - { - IsErrorRspInfo(pRspInfo, 0, true); - } +//void CQueryApi::OnRspOrderAction(CSecurityFtdcInputOrderActionField *pInputOrderAction, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) +//{ +// OrderIDType orderId = { 0 }; +// if (pInputOrderAction) +// { +// sprintf(orderId, "%d:%d:%s", pInputOrderAction->FrontID, pInputOrderAction->SessionID, pInputOrderAction->OrderRef); +// } +// else +// { +// IsErrorRspInfo(pRspInfo, nRequestID, bIsLast); +// } +// +// unordered_map::iterator it = m_id_platform_order.find(orderId); +// if (it == m_id_platform_order.end()) +// { +// // ûҵӦʾ +// //assert(false); +// } +// else +// { +// // ҵˣҪ״̬ +// // ʹϴε״̬ +// OrderField* pField = it->second; +// pField->ExecType = ExecType::ExecCancelReject; +// pField->ErrorID = pRspInfo->ErrorID; +// strncpy(pField->Text, pRspInfo->ErrorMsg, sizeof(ErrorMsgType)); +// m_msgQueue->Input_Copy(ResponeType::OnRtnOrder, m_msgQueue, m_pClass, 0, 0, pField, sizeof(OrderField), nullptr, 0, nullptr, 0); +// } +//} - unordered_map::iterator it = m_id_platform_order.find(orderId); - if (it == m_id_platform_order.end()) - { - // ûҵӦʾ - //assert(false); - } - else - { - // ҵˣҪ״̬ - // ʹϴε״̬ - OrderField* pField = it->second; - pField->ExecType = ExecType::ExecCancelReject; - pField->ErrorID = pRspInfo->ErrorID; - strncpy(pField->Text, pRspInfo->ErrorMsg, sizeof(ErrorMsgType)); - m_msgQueue->Input_Copy(ResponeType::OnRtnOrder, m_msgQueue, m_pClass, 0, 0, pField, sizeof(OrderField), nullptr, 0, nullptr, 0); - } -} +//void CQueryApi::OnErrRtnOrderAction(CSecurityFtdcOrderActionField *pOrderAction, CSecurityFtdcRspInfoField *pRspInfo) +//{ +// OrderIDType orderId = { 0 }; +// if (pOrderAction) +// { +// sprintf(orderId, "%d:%d:%s", pOrderAction->FrontID, pOrderAction->SessionID, pOrderAction->OrderRef); +// } +// else +// { +// IsErrorRspInfo(pRspInfo, 0, true); +// } +// +// unordered_map::iterator it = m_id_platform_order.find(orderId); +// if (it == m_id_platform_order.end()) +// { +// // ûҵӦʾ +// //assert(false); +// } +// else +// { +// // ҵˣҪ״̬ +// // ʹϴε״̬ +// OrderField* pField = it->second; +// pField->ExecType = ExecType::ExecCancelReject; +// pField->ErrorID = pRspInfo->ErrorID; +// strncpy(pField->Text, pRspInfo->ErrorMsg, sizeof(ErrorMsgType)); +// m_msgQueue->Input_Copy(ResponeType::OnRtnOrder, m_msgQueue, m_pClass, 0, 0, pField, sizeof(OrderField), nullptr, 0, nullptr, 0); +// } +//} -void CQueryApi::OnRtnOrder(CSecurityFtdcOrderField *pOrder) -{ - OnOrder(pOrder,false); -} +//void CQueryApi::OnRtnOrder(CSecurityFtdcOrderField *pOrder) +//{ +// OnOrder(pOrder,false); +//} void CQueryApi::ReqQryTradingAccount() { diff --git a/QuantBox_LTS_Trade_v2/QueryApi.h b/QuantBox_LTS_Query_v2/QueryApi.h similarity index 88% rename from QuantBox_LTS_Trade_v2/QueryApi.h rename to QuantBox_LTS_Query_v2/QueryApi.h index 4ad8062..f71aca1 100644 --- a/QuantBox_LTS_Trade_v2/QueryApi.h +++ b/QuantBox_LTS_Query_v2/QueryApi.h @@ -52,6 +52,8 @@ class CQueryApi : E_QrySettlementInfoField, E_QryOrderField, E_QryTradeField, + + E_AuthRandCodeField, }; public: @@ -103,9 +105,12 @@ class CQueryApi : int _Init(); - void ReqUserLogin(); + void ReqUserLogin(TSecurityFtdcAuthCodeType RandCode); int _ReqUserLogin(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3); + void ReqFetchAuthRandCode(); + int _ReqFetchAuthRandCode(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3); + int _ReqQryInstrument(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3); int _ReqQryTradingAccount(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3); int _ReqQryInvestorPosition(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3); @@ -128,26 +133,27 @@ class CQueryApi : virtual void OnFrontDisconnected(int nReason); //֤ + virtual void OnRspFetchAuthRandCode(CSecurityFtdcAuthRandCodeField *pAuthRandCode, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); //virtual void OnRspAuthenticate(CSecurityFtdcRspAuthenticateField *pRspAuthenticateField, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); virtual void OnRspUserLogin(CSecurityFtdcRspUserLoginField *pRspUserLogin, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); //virtual void OnRspSettlementInfoConfirm(CSecurityFtdcSettlementInfoConfirmField *pSettlementInfoConfirm, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); virtual void OnRspQryInvestor(CSecurityFtdcInvestorField *pInvestor, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); - //µ - virtual void OnRspOrderInsert(CSecurityFtdcInputOrderField *pInputOrder, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); - virtual void OnErrRtnOrderInsert(CSecurityFtdcInputOrderField *pInputOrder, CSecurityFtdcRspInfoField *pRspInfo); + ////µ + //virtual void OnRspOrderInsert(CSecurityFtdcInputOrderField *pInputOrder, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); + //virtual void OnErrRtnOrderInsert(CSecurityFtdcInputOrderField *pInputOrder, CSecurityFtdcRspInfoField *pRspInfo); - // - virtual void OnRspOrderAction(CSecurityFtdcInputOrderActionField *pInputOrderAction, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); - virtual void OnErrRtnOrderAction(CSecurityFtdcOrderActionField *pOrderAction, CSecurityFtdcRspInfoField *pRspInfo); + //// + //virtual void OnRspOrderAction(CSecurityFtdcInputOrderActionField *pInputOrderAction, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); + //virtual void OnErrRtnOrderAction(CSecurityFtdcOrderActionField *pOrderAction, CSecurityFtdcRspInfoField *pRspInfo); //ر virtual void OnRspQryOrder(CSecurityFtdcOrderField *pOrder, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); - virtual void OnRtnOrder(CSecurityFtdcOrderField *pOrder); + //virtual void OnRtnOrder(CSecurityFtdcOrderField *pOrder); //ɽر virtual void OnRspQryTrade(CSecurityFtdcTradeField *pTrade, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); - virtual void OnRtnTrade(CSecurityFtdcTradeField *pTrade); + //virtual void OnRtnTrade(CSecurityFtdcTradeField *pTrade); //¼ //virtual void OnRspQuoteInsert(CSecurityFtdcInputQuoteField *pInputQuote, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); diff --git a/QuantBox_LTS_Query_v2/ReadMe.txt b/QuantBox_LTS_Query_v2/ReadMe.txt new file mode 100644 index 0000000..51e2116 --- /dev/null +++ b/QuantBox_LTS_Query_v2/ReadMe.txt @@ -0,0 +1,48 @@ +======================================================================== + DYNAMIC LINK LIBRARY : QuantBox_LTS_Query_v2 Project Overview +======================================================================== + +AppWizard has created this QuantBox_LTS_Query_v2 DLL for you. + +This file contains a summary of what you will find in each of the files that +make up your QuantBox_LTS_Query_v2 application. + + +QuantBox_LTS_Query_v2.vcxproj + This is the main project file for VC++ projects generated using an Application Wizard. + It contains information about the version of Visual C++ that generated the file, and + information about the platforms, configurations, and project features selected with the + Application Wizard. + +QuantBox_LTS_Query_v2.vcxproj.filters + This is the filters file for VC++ projects generated using an Application Wizard. + It contains information about the association between the files in your project + and the filters. This association is used in the IDE to show grouping of files with + similar extensions under a specific node (for e.g. ".cpp" files are associated with the + "Source Files" filter). + +QuantBox_LTS_Query_v2.cpp + This is the main DLL source file. + + When created, this DLL does not export any symbols. As a result, it + will not produce a .lib file when it is built. If you wish this project + to be a project dependency of some other project, you will either need to + add code to export some symbols from the DLL so that an export library + will be produced, or you can set the Ignore Input Library property to Yes + on the General propert page of the Linker folder in the project's Property + Pages dialog box. + +///////////////////////////////////////////////////////////////////////////// +Other standard files: + +StdAfx.h, StdAfx.cpp + These files are used to build a precompiled header (PCH) file + named QuantBox_LTS_Query_v2.pch and a precompiled types file named StdAfx.obj. + +///////////////////////////////////////////////////////////////////////////// +Other notes: + +AppWizard uses "TODO:" comments to indicate parts of the source code you +should add to or customize. + +///////////////////////////////////////////////////////////////////////////// diff --git a/QuantBox_LTS_Query_v2/TraderApi.cpp b/QuantBox_LTS_Query_v2/TraderApi.cpp new file mode 100644 index 0000000..809c7cb --- /dev/null +++ b/QuantBox_LTS_Query_v2/TraderApi.cpp @@ -0,0 +1,899 @@ +#include "stdafx.h" +#include "TraderApi.h" + +#include "../include/QueueEnum.h" +#include "../include/QueueHeader.h" + +#include "../include/ApiHeader.h" +#include "../include/ApiStruct.h" + +#include "../include/toolkit.h" + +#include "../QuantBox_Queue/MsgQueue.h" + +#include "TypeConvert.h" + +#include +#include + +void* __stdcall Query(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3) +{ + // 由内部调用,不用检查是否为空 + CTraderApi* pApi = (CTraderApi*)pApi2; + pApi->QueryInThread(type, pApi1, pApi2, double1, double2, ptr1, size1, ptr2, size2, ptr3, size3); + return nullptr; +} + +void CTraderApi::QueryInThread(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3) +{ + int iRet = 0; + switch (type) + { + case E_Init: + iRet = _Init(); + break; + case E_ReqUserLoginField: + iRet = _ReqUserLogin(type, pApi1, pApi2, double1, double2, ptr1, size1, ptr2, size2, ptr3, size3); + break; + case E_AuthRandCodeField: + iRet = _ReqFetchAuthRandCode(type, pApi1, pApi2, double1, double2, ptr1, size1, ptr2, size2, ptr3, size3); + break; + //case E_QryTradingAccountField: + // iRet = _ReqQryTradingAccount(type, pApi1, pApi2, double1, double2, ptr1, size1, ptr2, size2, ptr3, size3); + // break; + //case E_QryInvestorPositionField: + // iRet = _ReqQryInvestorPosition(type, pApi1, pApi2, double1, double2, ptr1, size1, ptr2, size2, ptr3, size3); + // break; + //case E_QryInstrumentField: + // iRet = _ReqQryInstrument(type, pApi1, pApi2, double1, double2, ptr1, size1, ptr2, size2, ptr3, size3); + // break; + //case E_QryInvestorField: + // iRet = _ReqQryInvestor(type, pApi1, pApi2, double1, double2, ptr1, size1, ptr2, size2, ptr3, size3); + // break; + //case E_QryOrderField: + // iRet = _ReqQryOrder(type, pApi1, pApi2, double1, double2, ptr1, size1, ptr2, size2, ptr3, size3); + // break; + //case E_QryTradeField: + // iRet = _ReqQryTrade(type, pApi1, pApi2, double1, double2, ptr1, size1, ptr2, size2, ptr3, size3); + // break; + default: + break; + } + + if (0 == iRet) + { + //返回成功,填加到已发送池 + m_nSleep = 1; + } + else + { + m_msgQueue_Query->Input_Copy(type, pApi1, pApi2, double1, double2, ptr1, size1, ptr2, size2, ptr3, size3); + //失败,按4的幂进行延时,但不超过1s + m_nSleep *= 4; + m_nSleep %= 1023; + } + this_thread::sleep_for(chrono::milliseconds(m_nSleep)); +} + +void CTraderApi::Register(void* pCallback, void* pClass) +{ + m_pClass = pClass; + if (m_msgQueue == nullptr) + return; + + m_msgQueue_Query->Register((void*)Query, this); + m_msgQueue->Register(pCallback, this); + if (pCallback) + { + m_msgQueue_Query->StartThread(); + m_msgQueue->StartThread(); + } + else + { + m_msgQueue_Query->StopThread(); + m_msgQueue->StopThread(); + } +} + +CTraderApi::CTraderApi(void) +{ + m_pApi = nullptr; + m_lRequestID = 0; + m_nSleep = 1; + + // 自己维护两个消息队列 + m_msgQueue = new CMsgQueue(); + m_msgQueue_Query = new CMsgQueue(); + + m_msgQueue_Query->Register((void*)Query, this); + m_msgQueue_Query->StartThread(); +} + + +CTraderApi::~CTraderApi(void) +{ + Disconnect(); +} + +bool CTraderApi::IsErrorRspInfo(const char* szSource, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) +{ + bool bRet = ((pRspInfo) && (pRspInfo->ErrorID != 0)); + if (bRet) + { + ErrorField* pField = (ErrorField*)m_msgQueue->new_block(sizeof(ErrorField)); + + pField->ErrorID = pRspInfo->ErrorID; + strcpy(pField->ErrorMsg, pRspInfo->ErrorMsg); + strcpy(pField->Source, szSource); + + m_msgQueue->Input_NoCopy(ResponeType::OnRtnError, m_msgQueue, m_pClass, bIsLast, 0, pField, sizeof(ErrorField), nullptr, 0, nullptr, 0); + } + return bRet; +} + +bool CTraderApi::IsErrorRspInfo(CSecurityFtdcRspInfoField *pRspInfo) +{ + bool bRet = ((pRspInfo) && (pRspInfo->ErrorID != 0)); + + return bRet; +} + +void CTraderApi::Connect(const string& szPath, + ServerInfoField* pServerInfo, + UserInfoField* pUserInfo) +{ + m_szPath = szPath; + memcpy(&m_ServerInfo, pServerInfo, sizeof(ServerInfoField)); + memcpy(&m_UserInfo, pUserInfo, sizeof(UserInfoField)); + + m_msgQueue_Query->Input_NoCopy(RequestType::E_Init, m_msgQueue_Query, this, 0, 0, + nullptr, 0, nullptr, 0, nullptr, 0); +} + +int CTraderApi::_Init() +{ + char *pszPath = new char[m_szPath.length() + 1024]; + srand((unsigned int)time(nullptr)); + sprintf(pszPath, "%s/%s/%s/Td/%d/", m_szPath.c_str(), m_ServerInfo.BrokerID, m_UserInfo.UserID, rand()); + makedirs(pszPath); + + m_pApi = CSecurityFtdcTraderApi::CreateFtdcTraderApi(pszPath); + delete[] pszPath; + + m_msgQueue->Input_NoCopy(ResponeType::OnConnectionStatus, m_msgQueue, m_pClass, ConnectionStatus::Initialized, 0, nullptr, 0, nullptr, 0, nullptr, 0); + + if (m_pApi) + { + m_pApi->RegisterSpi(this); + + //添加地址 + size_t len = strlen(m_ServerInfo.Address) + 1; + char* buf = new char[len]; + strncpy(buf, m_ServerInfo.Address, len); + + char* token = strtok(buf, _QUANTBOX_SEPS_); + while (token) + { + if (strlen(token)>0) + { + m_pApi->RegisterFront(token); + } + token = strtok(nullptr, _QUANTBOX_SEPS_); + } + delete[] buf; + + if (m_ServerInfo.PublicTopicResumeTypeSubscribePublicTopic((SECURITY_TE_RESUME_TYPE)m_ServerInfo.PublicTopicResumeType); + if (m_ServerInfo.PrivateTopicResumeTypeSubscribePrivateTopic((SECURITY_TE_RESUME_TYPE)m_ServerInfo.PrivateTopicResumeType); + + m_msgQueue->Input_NoCopy(ResponeType::OnConnectionStatus, m_msgQueue, m_pClass, ConnectionStatus::Connecting, 0, nullptr, 0, nullptr, 0, nullptr, 0); + //初始化连接 + m_pApi->Init(); + } + + return 0; +} + +void CTraderApi::Disconnect() +{ + if (m_msgQueue_Query) + { + m_msgQueue_Query->StopThread(); + m_msgQueue_Query->Register(nullptr, nullptr); + m_msgQueue_Query->Clear(); + delete m_msgQueue_Query; + m_msgQueue_Query = nullptr; + } + + if (m_pApi) + { + m_pApi->RegisterSpi(nullptr); + m_pApi->Release(); + m_pApi = nullptr; + + // 全清理,只留最后一个 + m_msgQueue->Clear(); + m_msgQueue->Input_NoCopy(ResponeType::OnConnectionStatus, m_msgQueue, m_pClass, ConnectionStatus::Disconnected, 0, nullptr, 0, nullptr, 0, nullptr, 0); + // 主动触发 + m_msgQueue->Process(); + } + + if (m_msgQueue) + { + m_msgQueue->StopThread(); + m_msgQueue->Register(nullptr, nullptr); + m_msgQueue->Clear(); + delete m_msgQueue; + m_msgQueue = nullptr; + } + + m_lRequestID = 0;//由于线程已经停止,没有必要用原子操作了 + + Clear(); +} + +void CTraderApi::Clear() +{ + for (unordered_map::iterator it = m_id_platform_order.begin(); it != m_id_platform_order.end(); ++it) + delete it->second; + m_id_platform_order.clear(); + + for (unordered_map::iterator it = m_id_api_order.begin(); it != m_id_api_order.end(); ++it) + delete it->second; + m_id_api_order.clear(); + + //for (unordered_map::iterator it = m_id_platform_quote.begin(); it != m_id_platform_quote.end(); ++it) + // delete it->second; + //m_id_platform_quote.clear(); + + //for (unordered_map::iterator it = m_id_api_quote.begin(); it != m_id_api_quote.end(); ++it) + // delete it->second; + //m_id_api_quote.clear(); + + for (unordered_map::iterator it = m_id_platform_position.begin(); it != m_id_platform_position.end(); ++it) + delete it->second; + m_id_platform_position.clear(); +} + +void CTraderApi::OnFrontConnected() +{ + m_msgQueue->Input_NoCopy(ResponeType::OnConnectionStatus, m_msgQueue, m_pClass, ConnectionStatus::Connected, 0, nullptr, 0, nullptr, 0, nullptr, 0); + + //ReqUserLogin(); + ReqFetchAuthRandCode(); +} + +void CTraderApi::OnFrontDisconnected(int nReason) +{ + RspUserLoginField* pField = (RspUserLoginField*)m_msgQueue->new_block(sizeof(RspUserLoginField)); + + //连接失败返回的信息是拼接而成,主要是为了统一输出 + pField->ErrorID = nReason; + GetOnFrontDisconnectedMsg(nReason, pField->ErrorMsg); + + m_msgQueue->Input_NoCopy(ResponeType::OnConnectionStatus, m_msgQueue, m_pClass, ConnectionStatus::Disconnected, 0, pField, sizeof(RspUserLoginField), nullptr, 0, nullptr, 0); +} + +void CTraderApi::ReqFetchAuthRandCode() +{ + CSecurityFtdcAuthRandCodeField* pBody = (CSecurityFtdcAuthRandCodeField*)m_msgQueue_Query->new_block(sizeof(CSecurityFtdcAuthRandCodeField)); + + strncpy(pBody->RandCode, "", sizeof(TSecurityFtdcAuthCodeType)); + + m_msgQueue_Query->Input_NoCopy(RequestType::E_AuthRandCodeField, m_msgQueue_Query, this, 0, 0, + pBody, sizeof(CSecurityFtdcAuthRandCodeField), nullptr, 0, nullptr, 0); +} + +int CTraderApi::_ReqFetchAuthRandCode(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3) +{ + m_msgQueue->Input_NoCopy(ResponeType::OnConnectionStatus, m_msgQueue, m_pClass, ConnectionStatus::Authorizing, 0, nullptr, 0, nullptr, 0, nullptr, 0); + return m_pApi->ReqFetchAuthRandCode((CSecurityFtdcAuthRandCodeField*)ptr1, ++m_lRequestID); +} + +void CTraderApi::OnRspFetchAuthRandCode(CSecurityFtdcAuthRandCodeField *pAuthRandCode, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) +{ + RspUserLoginField* pField = (RspUserLoginField*)m_msgQueue->new_block(sizeof(RspUserLoginField)); + + if (!IsErrorRspInfo(pRspInfo) + && pAuthRandCode) + { + m_msgQueue->Input_NoCopy(ResponeType::OnConnectionStatus, m_msgQueue, m_pClass, ConnectionStatus::Authorized, 0, pField, sizeof(RspUserLoginField), nullptr, 0, nullptr, 0); + + ReqUserLogin(pAuthRandCode->RandCode); + } + else + { + pField->ErrorID = pRspInfo->ErrorID; + strncpy(pField->ErrorMsg, pRspInfo->ErrorMsg, sizeof(ErrorMsgType)); + + m_msgQueue->Input_NoCopy(ResponeType::OnConnectionStatus, m_msgQueue, m_pClass, ConnectionStatus::Disconnected, 0, pField, sizeof(RspUserLoginField), nullptr, 0, nullptr, 0); + } +} + +void CTraderApi::ReqUserLogin(TSecurityFtdcAuthCodeType RandCode) +{ + CSecurityFtdcReqUserLoginField* pBody = (CSecurityFtdcReqUserLoginField*)m_msgQueue_Query->new_block(sizeof(CSecurityFtdcReqUserLoginField)); + + strncpy(pBody->BrokerID, m_ServerInfo.BrokerID, sizeof(TSecurityFtdcBrokerIDType)); + strncpy(pBody->UserID, m_UserInfo.UserID, sizeof(TSecurityFtdcInvestorIDType)); + strncpy(pBody->Password, m_UserInfo.Password, sizeof(TSecurityFtdcPasswordType)); + strncpy(pBody->UserProductInfo, m_ServerInfo.UserProductInfo, sizeof(TSecurityFtdcProductInfoType)); + strncpy(pBody->AuthCode, m_ServerInfo.AuthCode, sizeof(TSecurityFtdcAuthCodeType)); + strncpy(pBody->RandCode, RandCode, sizeof(TSecurityFtdcAuthCodeType)); + + m_msgQueue_Query->Input_NoCopy(RequestType::E_ReqUserLoginField, m_msgQueue_Query, this, 0, 0, + pBody, sizeof(CSecurityFtdcReqUserLoginField), nullptr, 0, nullptr, 0); +} + +int CTraderApi::_ReqUserLogin(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3) +{ + m_msgQueue->Input_NoCopy(ResponeType::OnConnectionStatus, m_msgQueue, m_pClass, ConnectionStatus::Logining, 0, nullptr, 0, nullptr, 0, nullptr, 0); + return m_pApi->ReqUserLogin((CSecurityFtdcReqUserLoginField*)ptr1, ++m_lRequestID); +} + +void CTraderApi::OnRspUserLogin(CSecurityFtdcRspUserLoginField *pRspUserLogin, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) +{ + RspUserLoginField* pField = (RspUserLoginField*)m_msgQueue->new_block(sizeof(RspUserLoginField)); + + if (!IsErrorRspInfo(pRspInfo) + &&pRspUserLogin) + { + pField->TradingDay = GetDate(pRspUserLogin->TradingDay); + pField->LoginTime = GetTime(pRspUserLogin->LoginTime); + + sprintf(pField->SessionID, "%d:%d", pRspUserLogin->FrontID, pRspUserLogin->SessionID); + + m_msgQueue->Input_NoCopy(ResponeType::OnConnectionStatus, m_msgQueue, m_pClass, ConnectionStatus::Logined, 0, pField, sizeof(RspUserLoginField), nullptr, 0, nullptr, 0); + + // 记下登录信息,可能会用到 + memcpy(&m_RspUserLogin,pRspUserLogin,sizeof(CSecurityFtdcRspUserLoginField)); + m_nMaxOrderRef = atol(pRspUserLogin->MaxOrderRef); + // 自己发单时ID从1开始,不能从0开始 + m_nMaxOrderRef = m_nMaxOrderRef>1 ? m_nMaxOrderRef : 1; + //ReqSettlementInfoConfirm(); + //ReqQryInvestor(); + + m_msgQueue->Input_NoCopy(ResponeType::OnConnectionStatus, m_msgQueue, m_pClass, ConnectionStatus::Done, 0, nullptr, 0, nullptr, 0, nullptr, 0); + + if (m_ServerInfo.PrivateTopicResumeType > ResumeType::Restart + && (m_ServerInfo.PrivateTopicResumeTypeErrorID = pRspInfo->ErrorID; + strncpy(pField->ErrorMsg, pRspInfo->ErrorMsg, sizeof(ErrorMsgType)); + + m_msgQueue->Input_NoCopy(ResponeType::OnConnectionStatus, m_msgQueue, m_pClass, ConnectionStatus::Disconnected, 0, pField, sizeof(RspUserLoginField), nullptr, 0, nullptr, 0); + } +} + +int CTraderApi::ReqOrderInsert( + OrderField* pOrder, + int count, + OrderIDType* pInOut) +{ + int OrderRef = -1; + if (nullptr == m_pApi) + return -1; + + CSecurityFtdcInputOrderField body = {0}; + + strncpy(body.BrokerID, m_RspUserLogin.BrokerID, sizeof(TSecurityFtdcBrokerIDType)); + strncpy(body.InvestorID, m_RspUserLogin.UserID, sizeof(TSecurityFtdcInvestorIDType)); + + body.MinVolume = 1; + body.ForceCloseReason = SECURITY_FTDC_FCC_NotForceClose; + body.IsAutoSuspend = 0; + body.UserForceClose = 0; + //body.IsSwapOrder = 0; + + //合约 + strncpy(body.InstrumentID, pOrder->InstrumentID, sizeof(TSecurityFtdcInstrumentIDType)); + strncpy(body.ExchangeID, pOrder->ExchangeID, sizeof(TSecurityFtdcExchangeIDType)); + //买卖 + body.Direction = OrderSide_2_TSecurityFtdcDirectionType(pOrder->Side); + //开平 + body.CombOffsetFlag[0] = OpenCloseType_2_TSecurityFtdcOffsetFlagType(pOrder->OpenClose); + //投保 + body.CombHedgeFlag[0] = HedgeFlagType_2_TSecurityFtdcHedgeFlagType(pOrder->HedgeFlag); + //数量 + body.VolumeTotalOriginal = (int)pOrder->Qty; + + // 对于套利单,是用第一个参数的价格,还是用两个参数的价格差呢? + //body.LimitPrice = pOrder1->Price; + sprintf(body.LimitPrice, "%f", pOrder->Price); + body.StopPrice = pOrder->StopPx; + + // 针对第二个进行处理,如果有第二个参数,认为是交易所套利单 + if (count>1) + { + body.CombOffsetFlag[1] = OpenCloseType_2_TSecurityFtdcOffsetFlagType(pOrder[1].OpenClose); + body.CombHedgeFlag[1] = HedgeFlagType_2_TSecurityFtdcHedgeFlagType(pOrder[1].HedgeFlag); + // 交易所的移仓换月功能,没有实测过 + //body.IsSwapOrder = (body.CombOffsetFlag[0] != body.CombOffsetFlag[1]); + } + + //价格 + //body.OrderPriceType = OrderType_2_TSecurityFtdcOrderPriceTypeType(pOrder1->Type); + + // 市价与限价 + switch (pOrder->Type) + { + case Market: + case Stop: + case MarketOnClose: + case TrailingStop: + body.OrderPriceType = SECURITY_FTDC_OPT_BestPrice; + body.TimeCondition = SECURITY_FTDC_TC_IOC; + break; + case Limit: + case StopLimit: + case TrailingStopLimit: + default: + body.OrderPriceType = SECURITY_FTDC_OPT_LimitPrice; + body.TimeCondition = SECURITY_FTDC_TC_GFD; + break; + } + + // IOC与FOK + switch (pOrder->TimeInForce) + { + case IOC: + body.TimeCondition = SECURITY_FTDC_TC_IOC; + body.VolumeCondition = SECURITY_FTDC_VC_AV; + break; + case FOK: + body.TimeCondition = SECURITY_FTDC_TC_IOC; + body.VolumeCondition = SECURITY_FTDC_VC_CV; + //body.MinVolume = body.VolumeTotalOriginal; // 这个地方必须加吗? + break; + default: + body.VolumeCondition = SECURITY_FTDC_VC_AV; + break; + } + + // 条件单 + switch (pOrder->Type) + { + case Stop: + case TrailingStop: + case StopLimit: + case TrailingStopLimit: + // 条件单没有测试,先留空 + body.ContingentCondition = SECURITY_FTDC_CC_Immediately; + break; + default: + body.ContingentCondition = SECURITY_FTDC_CC_Immediately; + break; + } + + int nRet = 0; + { + //可能报单太快,m_nMaxOrderRef还没有改变就提交了 + lock_guard cl(m_csOrderRef); + + if (OrderRef < 0) + { + nRet = m_nMaxOrderRef; + ++m_nMaxOrderRef; + } + else + { + nRet = OrderRef; + } + sprintf(body.OrderRef, "%d", nRet); + + //不保存到队列,而是直接发送 + int n = m_pApi->ReqOrderInsert(&body, ++m_lRequestID); + if (n < 0) + { + nRet = n; + sprintf(m_orderInsert_Id, "%d", nRet); + } + else + { + sprintf(m_orderInsert_Id, "%d:%d:%d", m_RspUserLogin.FrontID, m_RspUserLogin.SessionID, nRet); + + OrderField* pField = (OrderField*)m_msgQueue->new_block(sizeof(OrderField)); + memcpy(pField, pOrder, sizeof(OrderField)); + strcpy(pField->ID, m_orderInsert_Id); + strcpy(pField->LocalID, pField->ID); + m_id_platform_order.insert(pair(m_orderInsert_Id, pField)); + } + strncpy((char*)pInOut, m_orderInsert_Id, sizeof(OrderIDType)); + } + + return nRet; +} + +void CTraderApi::OnRspOrderInsert(CSecurityFtdcInputOrderField *pInputOrder, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) +{ + OrderIDType orderId = { 0 }; + if (pInputOrder) + { + sprintf(orderId, "%d:%d:%s", m_RspUserLogin.FrontID, m_RspUserLogin.SessionID, pInputOrder->OrderRef); + } + else + { + IsErrorRspInfo("OnRspOrderInsert", pRspInfo, nRequestID, bIsLast); + } + + unordered_map::iterator it = m_id_platform_order.find(orderId); + if (it == m_id_platform_order.end()) + { + // 没找到?不应当,这表示出错了 + //assert(false); + } + else + { + // 找到了,要更新状态 + // 得使用上次的状态 + OrderField* pField = it->second; + strcpy(pField->ID, orderId); + strcpy(pField->LocalID, pField->ID); + pField->ExecType = ExecType::ExecRejected; + pField->Status = OrderStatus::Rejected; + pField->ErrorID = pRspInfo->ErrorID; + strncpy(pField->Text, pRspInfo->ErrorMsg, sizeof(ErrorMsgType)); + m_msgQueue->Input_Copy(ResponeType::OnRtnOrder, m_msgQueue, m_pClass, 0, 0, pField, sizeof(OrderField), nullptr, 0, nullptr, 0); + } +} + +void CTraderApi::OnErrRtnOrderInsert(CSecurityFtdcInputOrderField *pInputOrder, CSecurityFtdcRspInfoField *pRspInfo) +{ + OrderIDType orderId = { 0 }; + if (pInputOrder) + { + sprintf(orderId, "%d:%d:%s", m_RspUserLogin.FrontID, m_RspUserLogin.SessionID, pInputOrder->OrderRef); + } + else + { + IsErrorRspInfo("OnErrRtnOrderInsert", pRspInfo, 0, true); + } + + unordered_map::iterator it = m_id_platform_order.find(orderId); + if (it == m_id_platform_order.end()) + { + // 没找到?不应当,这表示出错了 + //assert(false); + // LTS在开始连接时也会收到此回报,无语啊 + } + else + { + // 找到了,要更新状态 + // 得使用上次的状态 + OrderField* pField = it->second; + strcpy(pField->ID, orderId); + strcpy(pField->LocalID, pField->ID); + pField->ExecType = ExecType::ExecRejected; + pField->Status = OrderStatus::Rejected; + pField->ErrorID = pRspInfo->ErrorID; + strncpy(pField->Text, pRspInfo->ErrorMsg, sizeof(ErrorMsgType)); + m_msgQueue->Input_Copy(ResponeType::OnRtnOrder, m_msgQueue, m_pClass, 0, 0, pField, sizeof(OrderField), nullptr, 0, nullptr, 0); + } +} + +void CTraderApi::OnRtnTrade(CSecurityFtdcTradeField *pTrade) +{ + OnTrade(pTrade,false); +} + +int CTraderApi::ReqOrderAction(OrderIDType* szIds, int count, OrderIDType* pOutput) +{ + unordered_map::iterator it = m_id_api_order.find(szIds[0]); + if (it == m_id_api_order.end()) + { + sprintf((char*)pOutput, "%d", -100); + return -100; + } + else + { + // 找到了订单 + return ReqOrderAction(it->second, count, pOutput); + } +} + +int CTraderApi::ReqOrderAction(CSecurityFtdcOrderField *pOrder, int count, OrderIDType* pOutput) +{ + if (nullptr == m_pApi) + return 0; + + CSecurityFtdcInputOrderActionField body = {0}; + + ///经纪公司代码 + strncpy(body.BrokerID, pOrder->BrokerID,sizeof(TSecurityFtdcBrokerIDType)); + ///投资者代码 + strncpy(body.InvestorID, pOrder->InvestorID,sizeof(TSecurityFtdcInvestorIDType)); + ///报单引用 + strncpy(body.OrderRef, pOrder->OrderRef,sizeof(TSecurityFtdcOrderRefType)); + ///前置编号 + body.FrontID = pOrder->FrontID; + ///会话编号 + body.SessionID = pOrder->SessionID; + ///交易所代码 + strncpy(body.ExchangeID,pOrder->ExchangeID,sizeof(TSecurityFtdcExchangeIDType)); + ///报单编号 + //strncpy(body.OrderSysID,pOrder->OrderSysID,sizeof(TSecurityFtdcOrderSysIDType)); + ///操作标志 + body.ActionFlag = SECURITY_FTDC_AF_Delete; + ///合约代码 + strncpy(body.InstrumentID, pOrder->InstrumentID,sizeof(TSecurityFtdcInstrumentIDType)); + + int nRet = m_pApi->ReqOrderAction(&body, ++m_lRequestID); + if (nRet < 0) + { + sprintf(m_orderAction_Id, "%d", nRet); + } + else + { + memset(m_orderAction_Id, 0, sizeof(OrderIDType)); + } + strncpy((char*)pOutput, m_orderAction_Id, sizeof(OrderIDType)); + + return nRet; +} + +void CTraderApi::OnRspOrderAction(CSecurityFtdcInputOrderActionField *pInputOrderAction, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) +{ + OrderIDType orderId = { 0 }; + if (pInputOrderAction) + { + sprintf(orderId, "%d:%d:%s", pInputOrderAction->FrontID, pInputOrderAction->SessionID, pInputOrderAction->OrderRef); + } + else + { + IsErrorRspInfo("OnRspOrderAction", pRspInfo, nRequestID, bIsLast); + } + + unordered_map::iterator it = m_id_platform_order.find(orderId); + if (it == m_id_platform_order.end()) + { + // 没找到?不应当,这表示出错了 + //assert(false); + } + else + { + // 找到了,要更新状态 + // 得使用上次的状态 + OrderField* pField = it->second; + pField->ExecType = ExecType::ExecCancelReject; + pField->ErrorID = pRspInfo->ErrorID; + strncpy(pField->Text, pRspInfo->ErrorMsg, sizeof(ErrorMsgType)); + m_msgQueue->Input_Copy(ResponeType::OnRtnOrder, m_msgQueue, m_pClass, 0, 0, pField, sizeof(OrderField), nullptr, 0, nullptr, 0); + } +} + +void CTraderApi::OnErrRtnOrderAction(CSecurityFtdcOrderActionField *pOrderAction, CSecurityFtdcRspInfoField *pRspInfo) +{ + OrderIDType orderId = { 0 }; + if (pOrderAction) + { + sprintf(orderId, "%d:%d:%s", pOrderAction->FrontID, pOrderAction->SessionID, pOrderAction->OrderRef); + } + else + { + IsErrorRspInfo("OnErrRtnOrderAction", pRspInfo, 0, true); + } + + unordered_map::iterator it = m_id_platform_order.find(orderId); + if (it == m_id_platform_order.end()) + { + // 没找到?不应当,这表示出错了 + //assert(false); + } + else + { + // 找到了,要更新状态 + // 得使用上次的状态 + OrderField* pField = it->second; + pField->ExecType = ExecType::ExecCancelReject; + pField->ErrorID = pRspInfo->ErrorID; + strncpy(pField->Text, pRspInfo->ErrorMsg, sizeof(ErrorMsgType)); + m_msgQueue->Input_Copy(ResponeType::OnRtnOrder, m_msgQueue, m_pClass, 0, 0, pField, sizeof(OrderField), nullptr, 0, nullptr, 0); + } +} + +void CTraderApi::OnRtnOrder(CSecurityFtdcOrderField *pOrder) +{ + OnOrder(pOrder,false); +} + +void CTraderApi::OnRspError(CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) +{ + IsErrorRspInfo("OnRspError", pRspInfo, nRequestID, bIsLast); +} + +void CTraderApi::OnOrder(CSecurityFtdcOrderField *pOrder, bool bFromQry) +{ + if (nullptr == pOrder) + return; + + OrderIDType orderId = { 0 }; + sprintf(orderId, "%d:%d:%s", pOrder->FrontID, pOrder->SessionID, pOrder->OrderRef); + OrderIDType orderSydId = { 0 }; + + { + // 保存原始订单信息,用于撤单 + + unordered_map::iterator it = m_id_api_order.find(orderId); + if (it == m_id_api_order.end()) + { + // 找不到此订单,表示是新单 + CSecurityFtdcOrderField* pField = new CSecurityFtdcOrderField(); + memcpy(pField, pOrder, sizeof(CSecurityFtdcOrderField)); + m_id_api_order.insert(pair(orderId, pField)); + } + else + { + // 找到了订单 + // 需要再复制保存最后一次的状态,还是只要第一次的用于撤单即可?记下,这样最后好比较 + CSecurityFtdcOrderField* pField = it->second; + memcpy(pField, pOrder, sizeof(CSecurityFtdcOrderField)); + } + + // 保存SysID用于定义成交回报与订单 + sprintf(orderSydId, "%s:%s", pOrder->ExchangeID, pOrder->OrderSysID); + m_sysId_orderId.insert(pair(orderSydId, orderId)); + } + + { + // 从API的订单转换成自己的结构体 + + OrderField* pField = nullptr; + unordered_map::iterator it = m_id_platform_order.find(orderId); + if (it == m_id_platform_order.end()) + { + // 开盘时发单信息还没有,所以找不到对应的单子,需要进行Order的恢复 + pField = (OrderField*)m_msgQueue->new_block(sizeof(OrderField)); + + strcpy(pField->ID, orderId); + strcpy(pField->LocalID, pField->ID); + strcpy(pField->InstrumentID, pOrder->InstrumentID); + strcpy(pField->ExchangeID, pOrder->ExchangeID); + pField->HedgeFlag = TSecurityFtdcHedgeFlagType_2_HedgeFlagType(pOrder->CombHedgeFlag[0]); + pField->Side = TSecurityFtdcDirectionType_2_OrderSide(pOrder->Direction); + pField->Price = atof(pOrder->LimitPrice); + pField->StopPx = pOrder->StopPrice; + strncpy(pField->Text, pOrder->StatusMsg, sizeof(ErrorMsgType)); + pField->OpenClose = TSecurityFtdcOffsetFlagType_2_OpenCloseType(pOrder->CombOffsetFlag[0]); + pField->Status = CSecurityFtdcOrderField_2_OrderStatus(pOrder); + pField->Qty = pOrder->VolumeTotalOriginal; + pField->Type = CSecurityFtdcOrderField_2_OrderType(pOrder); + pField->TimeInForce = CSecurityFtdcOrderField_2_TimeInForce(pOrder); + pField->ExecType = ExecType::ExecNew; + strcpy(pField->OrderID, pOrder->OrderSysID); + + + // 添加到map中,用于其它工具的读取,撤单失败时的再通知等 + m_id_platform_order.insert(pair(orderId, pField)); + } + else + { + pField = it->second; + strcpy(pField->ID, orderId); + strcpy(pField->LocalID, pField->ID); + pField->LeavesQty = pOrder->VolumeTotal; + pField->Price = atof(pOrder->LimitPrice); + pField->Status = CSecurityFtdcOrderField_2_OrderStatus(pOrder); + pField->ExecType = CSecurityFtdcOrderField_2_ExecType(pOrder); + strcpy(pField->OrderID, pOrder->OrderSysID); + strncpy(pField->Text, pOrder->StatusMsg, sizeof(ErrorMsgType)); + } + + m_msgQueue->Input_Copy(ResponeType::OnRtnOrder, m_msgQueue, m_pClass, 0, 0, pField, sizeof(OrderField), nullptr, 0, nullptr, 0); + } +} + +void CTraderApi::OnTrade(CSecurityFtdcTradeField *pTrade, bool bFromQry) +{ + if (nullptr == pTrade) + return; + + TradeField* pField = (TradeField*)m_msgQueue->new_block(sizeof(TradeField)); + + strcpy(pField->InstrumentID, pTrade->InstrumentID); + strcpy(pField->ExchangeID, pTrade->ExchangeID); + pField->Side = TSecurityFtdcDirectionType_2_OrderSide(pTrade->Direction); + pField->Qty = pTrade->Volume; + pField->Price = atof(pTrade->Price); + pField->OpenClose = TSecurityFtdcOffsetFlagType_2_OpenCloseType(pTrade->OffsetFlag); + pField->HedgeFlag = TSecurityFtdcHedgeFlagType_2_HedgeFlagType(pTrade->HedgeFlag); + pField->Commission = 0;//TODO收续费以后要计算出来 + pField->Time = GetTime(pTrade->TradeTime); + strcpy(pField->TradeID, pTrade->TradeID); + + OrderIDType orderSysId = { 0 }; + sprintf(orderSysId, "%s:%s", pTrade->ExchangeID, pTrade->OrderSysID); + unordered_map::iterator it = m_sysId_orderId.find(orderSysId); + if (it == m_sysId_orderId.end()) + { + // 此成交找不到对应的报单 + //assert(false); + } + else + { + // 找到对应的报单 + strcpy(pField->ID, it->second.c_str()); + + m_msgQueue->Input_Copy(ResponeType::OnRtnTrade, m_msgQueue, m_pClass, 0, 0, pField, sizeof(TradeField), nullptr, 0, nullptr, 0); + + unordered_map::iterator it2 = m_id_platform_order.find(it->second); + if (it2 == m_id_platform_order.end()) + { + // 此成交找不到对应的报单 + //assert(false); + } + else + { + // 更新订单的状态 + // 是否要通知接口 + } + + OnTrade(pField, bFromQry); + } +} + +void CTraderApi::OnTrade(TradeField *pTrade, bool bFromQry) +{ + PositionIDType positionId = { 0 }; + sprintf(positionId, "%s:%s:%d:%d", + pTrade->InstrumentID, pTrade->ExchangeID, TradeField_2_PositionSide(pTrade), pTrade->HedgeFlag); + + PositionField* pField = nullptr; + unordered_map::iterator it = m_id_platform_position.find(positionId); + if (it == m_id_platform_position.end()) + { + pField = (PositionField*)m_msgQueue->new_block(sizeof(PositionField)); + + sprintf(pField->Symbol, "%s.%s", pTrade->InstrumentID, pTrade->ExchangeID); + strcpy(pField->InstrumentID, pTrade->InstrumentID); + strcpy(pField->ExchangeID, pTrade->ExchangeID); + pField->Side = TradeField_2_PositionSide(pTrade); + pField->HedgeFlag = TSecurityFtdcHedgeFlagType_2_HedgeFlagType(pTrade->HedgeFlag); + + m_id_platform_position.insert(pair(positionId, pField)); + } + else + { + pField = it->second; + } + + if (pTrade->Side == OrderSide::Buy) + { + pField->Position += pTrade->Qty; + pField->TdPosition += pTrade->Qty; + } + else + { + pField->Position -= pTrade->Qty; + if (pTrade->OpenClose == OpenCloseType::CloseToday) + { + pField->TdPosition -= pTrade->Qty; + } + else + { + pField->YdPosition -= pTrade->Qty; + // 如果昨天的被减成负数,从今天开始继续减 + if (pField->YdPosition<0) + { + pField->TdPosition += pField->YdPosition; + pField->YdPosition = 0; + } + } + + // 计算错误,直接重新查询 + //if (pField->Position < 0 || pField->TdPosition < 0 || pField->YdPosition < 0) + //{ + // ReqQryInvestorPosition("", ""); + // return; + //} + } + + m_msgQueue->Input_Copy(ResponeType::OnRspQryInvestorPosition, m_msgQueue, m_pClass, false, 0, pField, sizeof(PositionField), nullptr, 0, nullptr, 0); +} \ No newline at end of file diff --git a/QuantBox_LTS_Query_v2/TraderApi.h b/QuantBox_LTS_Query_v2/TraderApi.h new file mode 100644 index 0000000..1b64f01 --- /dev/null +++ b/QuantBox_LTS_Query_v2/TraderApi.h @@ -0,0 +1,218 @@ +#pragma once + +#include "../include/LTS_v2/SecurityFtdcTraderApi.h" +#include "../include/ApiStruct.h" + +#ifdef _WIN64 +#pragma comment(lib, "../include/LTS_v2/win64/securitytraderapi.lib") +#pragma comment(lib, "../lib/QuantBox_Queue_x64.lib") +#else +#pragma comment(lib, "../include/LTS_v2/win32/securitytraderapi.lib") +#pragma comment(lib, "../lib/QuantBox_Queue_x86.lib") +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +class CMsgQueue; + +class CTraderApi : + public CSecurityFtdcTraderSpi +{ + //请求数据包类型 + enum RequestType + { + E_Init, + + E_ReqAuthenticateField, + E_ReqUserLoginField, + E_SettlementInfoConfirmField, + + E_QryInvestorField, + + E_QryInstrumentField, + E_InputOrderField, + E_InputOrderActionField, + E_InputQuoteField, + E_InputQuoteActionField, + E_QryTradingAccountField, + E_QryInvestorPositionField, + E_QryInvestorPositionDetailField, + E_QryInstrumentCommissionRateField, + E_QryInstrumentMarginRateField, + E_QryDepthMarketDataField, + E_QrySettlementInfoField, + E_QryOrderField, + E_QryTradeField, + + E_AuthRandCodeField, + }; + +public: + CTraderApi(void); + virtual ~CTraderApi(void); + + void Register(void* pCallback, void* pClass); + + void Connect(const string& szPath, + ServerInfoField* pServerInfo, + UserInfoField* pUserInfo); + void Disconnect(); + + int ReqOrderInsert( + OrderField* pOrder, + int count, + OrderIDType* pInOut); + + int ReqOrderAction(OrderIDType* szIds, int count, OrderIDType* pOutput); + int ReqOrderAction(CSecurityFtdcOrderField *pOrder, int count, OrderIDType* pOutput); + + int ReqQuoteInsert( + int QuoteRef, + OrderField* pOrderAsk, + OrderField* pOrderBid); + + //int ReqQuoteAction(CSecurityFtdcQuoteField *pQuote); + //int ReqQuoteAction(const string& szId); + + //void ReqQryTradingAccount(); + //void ReqQryInvestorPosition(const string& szInstrumentId, const string& szExchange); + //void ReqQryInvestorPositionDetail(const string& szInstrumentId); + //void ReqQryInstrument(const string& szInstrumentId, const string& szExchange); + //void ReqQryInstrumentCommissionRate(const string& szInstrumentId); + //void ReqQryInstrumentMarginRate(const string& szInstrumentId, TSecurityFtdcHedgeFlagType HedgeFlag = SECURITY_FTDC_HF_Speculation); + //void ReqQryDepthMarketData(const string& szInstrumentId); + //void ReqQrySettlementInfo(const string& szTradingDay); + + //void ReqQryOrder(); + //void ReqQryTrade(); + + //void ReqQryInvestor(); + +private: + friend void* __stdcall Query(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3); + void QueryInThread(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3); + + void Clear(); + + int _Init(); + + void ReqUserLogin(TSecurityFtdcAuthCodeType RandCode); + int _ReqUserLogin(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3); + + void ReqFetchAuthRandCode(); + int _ReqFetchAuthRandCode(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3); + + //int _ReqQryInstrument(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3); + //int _ReqQryTradingAccount(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3); + //int _ReqQryInvestorPosition(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3); + //int _ReqQryInvestor(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3); + + //int _ReqQryOrder(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3); + //int _ReqQryTrade(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3); + //int _ReqQryQuote(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3); + + void OnOrder(CSecurityFtdcOrderField *pOrder, bool bFromQry); + void OnTrade(CSecurityFtdcTradeField *pTrade, bool bFromQry); + void OnTrade(TradeField *pTrade, bool bFromQry); + + //检查是否出错 + bool IsErrorRspInfo(const char* szSource, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast);//向消息队列输出信息 + bool IsErrorRspInfo(CSecurityFtdcRspInfoField *pRspInfo);//不输出信息 + + //连接 + virtual void OnFrontConnected(); + virtual void OnFrontDisconnected(int nReason); + + //认证 + virtual void OnRspFetchAuthRandCode(CSecurityFtdcAuthRandCodeField *pAuthRandCode, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); + virtual void OnRspUserLogin(CSecurityFtdcRspUserLoginField *pRspUserLogin, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); + //virtual void OnRspSettlementInfoConfirm(CSecurityFtdcSettlementInfoConfirmField *pSettlementInfoConfirm, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); + //virtual void OnRspQryInvestor(CSecurityFtdcInvestorField *pInvestor, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); + + //下单 + virtual void OnRspOrderInsert(CSecurityFtdcInputOrderField *pInputOrder, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); + virtual void OnErrRtnOrderInsert(CSecurityFtdcInputOrderField *pInputOrder, CSecurityFtdcRspInfoField *pRspInfo); + + //撤单 + virtual void OnRspOrderAction(CSecurityFtdcInputOrderActionField *pInputOrderAction, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); + virtual void OnErrRtnOrderAction(CSecurityFtdcOrderActionField *pOrderAction, CSecurityFtdcRspInfoField *pRspInfo); + + //报单回报 + //virtual void OnRspQryOrder(CSecurityFtdcOrderField *pOrder, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); + virtual void OnRtnOrder(CSecurityFtdcOrderField *pOrder); + + //成交回报 + //virtual void OnRspQryTrade(CSecurityFtdcTradeField *pTrade, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); + virtual void OnRtnTrade(CSecurityFtdcTradeField *pTrade); + + //报价录入 + //virtual void OnRspQuoteInsert(CSecurityFtdcInputQuoteField *pInputQuote, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); + //virtual void OnErrRtnQuoteInsert(CSecurityFtdcInputQuoteField *pInputQuote, CSecurityFtdcRspInfoField *pRspInfo); + //virtual void OnRtnQuote(CSecurityFtdcQuoteField *pQuote); + + //报价撤单 + //virtual void OnRspQuoteAction(CSecurityFtdcInputQuoteActionField *pInputQuoteAction, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); + //virtual void OnErrRtnQuoteAction(CSecurityFtdcQuoteActionField *pQuoteAction, CSecurityFtdcRspInfoField *pRspInfo); + + //仓位 + //virtual void OnRspQryInvestorPosition(CSecurityFtdcInvestorPositionField *pInvestorPosition, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); + //virtual void OnRspQryInvestorPositionDetail(CSecurityFtdcInvestorPositionDetailField *pInvestorPositionDetail, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); + //virtual void OnRspQryInvestorPositionCombineDetail(CSecurityFtdcInvestorPositionCombineDetailField *pInvestorPositionCombineDetail, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; + + //资金 + //virtual void OnRspQryTradingAccount(CSecurityFtdcTradingAccountField *pTradingAccount, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); + + //合约、手续费 + //virtual void OnRspQryInstrument(CSecurityFtdcInstrumentField *pInstrument, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); + //virtual void OnRspQryInstrumentMarginRate(CSecurityFtdcInstrumentMarginRateField *pInstrumentMarginRate, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); + //virtual void OnRspQryInstrumentCommissionRate(CSecurityFtdcInstrumentCommissionRateField *pInstrumentCommissionRate, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); + + //查询行情响应 + //virtual void OnRspQryDepthMarketData(CSecurityFtdcDepthMarketDataField *pDepthMarketData, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); + + //请求查询投资者结算结果响应 + //virtual void OnRspQrySettlementInfo(CSecurityFtdcSettlementInfoField *pSettlementInfo, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); + + //其它 + virtual void OnRspError(CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); + //virtual void OnRtnInstrumentStatus(CSecurityFtdcInstrumentStatusField *pInstrumentStatus); + +private: + atomic m_lRequestID; //请求ID,得保持自增 + + CSecurityFtdcRspUserLoginField m_RspUserLogin; //返回的登录成功响应,目前利用此内成员进行报单所属区分 + CSecurityFtdcInvestorField m_Investor; + + OrderIDType m_orderInsert_Id; + OrderIDType m_orderAction_Id; + + mutex m_csOrderRef; + int m_nMaxOrderRef; //报单引用,用于区分报单,保持自增 + + CSecurityFtdcTraderApi* m_pApi; //交易API + + string m_szPath; //生成配置文件的路径 + ServerInfoField m_ServerInfo; + UserInfoField m_UserInfo; + int m_nSleep; + + unordered_map m_id_platform_order; + unordered_map m_id_api_order; + unordered_map m_sysId_orderId; + + unordered_map m_id_platform_position; + + CMsgQueue* m_msgQueue; //消息队列指针 + CMsgQueue* m_msgQueue_Query; + void* m_pClass; +}; + diff --git a/QuantBox_LTS_Query_v2/dllmain.cpp b/QuantBox_LTS_Query_v2/dllmain.cpp new file mode 100644 index 0000000..69b5891 --- /dev/null +++ b/QuantBox_LTS_Query_v2/dllmain.cpp @@ -0,0 +1,19 @@ +// dllmain.cpp : Defines the entry point for the DLL application. +#include "stdafx.h" + +BOOL APIENTRY DllMain( HMODULE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} + diff --git a/QuantBox_LTS_Query_v2/main.cpp b/QuantBox_LTS_Query_v2/main.cpp new file mode 100644 index 0000000..cd9ff37 --- /dev/null +++ b/QuantBox_LTS_Query_v2/main.cpp @@ -0,0 +1,73 @@ +#include "stdafx.h" +#include "../include/ApiHeader.h" +#include "../include/QueueEnum.h" +#include "QueryApi.h" + +inline CQueryApi* GetApi(void* pApi) +{ + return static_cast(pApi); +} + +void* __stdcall XRequest(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3) +{ + RequestType rt = (RequestType)type; + switch (rt) + { + case GetApiType: + return (void*)(ApiType::Query_ | ApiType::Instrument); + case GetApiVersion: + return (void*)"0.1.0.20151116"; + case GetApiName: + return (void*)"LTS2"; + case Create: + return new CQueryApi(); + default: + break; + } + + if (pApi1 == nullptr) + { + return nullptr; + } + + CQueryApi* pApi = GetApi(pApi1); + + switch (rt) + { + case Release: + delete pApi; + return nullptr; + case Register: + pApi->Register(ptr1, ptr2); + break; + case Connect: + pApi->Connect((const char*)ptr3, (ServerInfoField*)ptr1, (UserInfoField*)ptr2); + break; + case Disconnect: + pApi->Disconnect(); + break; + case ReqQryInstrument: + pApi->ReqQryInstrument((const char*)ptr1, (const char*)ptr2); + break; + case ReqQryTradingAccount: + pApi->ReqQryTradingAccount(); + break; + case ReqQryInvestorPosition: + pApi->ReqQryInvestorPosition((const char*)ptr1, (const char*)ptr2); + break; + //case ReqQrySettlementInfo: + // pApi->ReqQrySettlementInfo((const char*)ptr1); + // break; + //case ReqOrderInsert: + // return (void*)pApi->ReqOrderInsert((OrderField*)ptr1, size1, (OrderIDType*)ptr2); + // //case ReqQuoteInsert: + // // return (void*)pApi->ReqQuoteInsert((int)double1, (OrderField*)ptr1, (OrderField*)ptr2); + //case ReqOrderAction: + // return (void*)pApi->ReqOrderAction((OrderIDType*)ptr1, size1, (OrderIDType*)ptr2); + // break; + default: + break; + } + + return pApi1; +} diff --git a/QuantBox_LTS_Query_v2/stdafx.cpp b/QuantBox_LTS_Query_v2/stdafx.cpp new file mode 100644 index 0000000..74a1def --- /dev/null +++ b/QuantBox_LTS_Query_v2/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// QuantBox_LTS_Query_v2.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/QuantBox_LTS_Query_v2/stdafx.h b/QuantBox_LTS_Query_v2/stdafx.h new file mode 100644 index 0000000..f3a0737 --- /dev/null +++ b/QuantBox_LTS_Query_v2/stdafx.h @@ -0,0 +1,16 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +#include "targetver.h" + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +// Windows Header Files: +#include + + + +// TODO: reference additional headers your program requires here diff --git a/QuantBox_LTS_Query_v2/targetver.h b/QuantBox_LTS_Query_v2/targetver.h new file mode 100644 index 0000000..87c0086 --- /dev/null +++ b/QuantBox_LTS_Query_v2/targetver.h @@ -0,0 +1,8 @@ +#pragma once + +// Including SDKDDKVer.h defines the highest available Windows platform. + +// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and +// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. + +#include diff --git a/QuantBox_LTS_Quote/MdUserApi.cpp b/QuantBox_LTS_Quote/MdUserApi.cpp index b3d6b42..cbe9ad1 100644 --- a/QuantBox_LTS_Quote/MdUserApi.cpp +++ b/QuantBox_LTS_Quote/MdUserApi.cpp @@ -27,7 +27,7 @@ ExchangeType TSecurityFtdcExchangeIDType_2_ExchangeType(TSecurityFtdcExchangeIDT case 'S': return ExchangeType::SSE; case 'Z': - return ExchangeType::SZE; + return ExchangeType::SZSE; default: return ExchangeType::Undefined_; } @@ -112,7 +112,7 @@ void CMdUserApi::Register(void* pCallback, void* pClass) } } -bool CMdUserApi::IsErrorRspInfo(CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) +bool CMdUserApi::IsErrorRspInfo(const char* szSource, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { bool bRet = ((pRspInfo) && (pRspInfo->ErrorID != 0)); if (bRet) @@ -121,6 +121,7 @@ bool CMdUserApi::IsErrorRspInfo(CSecurityFtdcRspInfoField *pRspInfo, int nReques pField->ErrorID = pRspInfo->ErrorID; strcpy(pField->ErrorMsg, pRspInfo->ErrorMsg); + strcpy(pField->Source, szSource); m_msgQueue->Input_NoCopy(ResponeType::OnRtnError, m_msgQueue, m_pClass, bIsLast, 0, pField, sizeof(ErrorField), nullptr, 0, nullptr, 0); } @@ -413,13 +414,13 @@ void CMdUserApi::OnRspUserLogin(CSecurityFtdcRspUserLoginField *pRspUserLogin, C void CMdUserApi::OnRspError(CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { - IsErrorRspInfo(pRspInfo, nRequestID, bIsLast); + IsErrorRspInfo("OnRspError", pRspInfo, nRequestID, bIsLast); } void CMdUserApi::OnRspSubMarketData(CSecurityFtdcSpecificInstrumentField *pSpecificInstrument, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { //ģƽ̨ᴥҪԼάһѾĵĺԼб - if(!IsErrorRspInfo(pRspInfo,nRequestID,bIsLast) + if(!IsErrorRspInfo("OnRspSubMarketData", pRspInfo,nRequestID,bIsLast) &&pSpecificInstrument) { lock_guard cl(m_csMapInstrumentIDs); @@ -439,7 +440,7 @@ void CMdUserApi::OnRspSubMarketData(CSecurityFtdcSpecificInstrumentField *pSpeci void CMdUserApi::OnRspUnSubMarketData(CSecurityFtdcSpecificInstrumentField *pSpecificInstrument, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { //ģƽ̨ᴥ - if(!IsErrorRspInfo(pRspInfo,nRequestID,bIsLast) + if(!IsErrorRspInfo("OnRspUnSubMarketData", pRspInfo,nRequestID,bIsLast) &&pSpecificInstrument) { lock_guard cl(m_csMapInstrumentIDs); diff --git a/QuantBox_LTS_Quote/MdUserApi.h b/QuantBox_LTS_Quote/MdUserApi.h index fbfabfc..0c3db39 100644 --- a/QuantBox_LTS_Quote/MdUserApi.h +++ b/QuantBox_LTS_Quote/MdUserApi.h @@ -73,7 +73,7 @@ class CMdUserApi : //virtual void OnRtnForQuoteRsp(CSecurityFtdcForQuoteRspField *pForQuoteRsp); //Ƿ - bool IsErrorRspInfo(CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast);//Ϣ͵Ϣ + bool IsErrorRspInfo(const char* szSource, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast);//Ϣ͵Ϣ bool IsErrorRspInfo(CSecurityFtdcRspInfoField *pRspInfo);//ͳϢ private: diff --git a/QuantBox_LTS_Quote_v2/MdUserApi.cpp b/QuantBox_LTS_Quote_v2/MdUserApi.cpp index 280f4a2..853ec75 100644 --- a/QuantBox_LTS_Quote_v2/MdUserApi.cpp +++ b/QuantBox_LTS_Quote_v2/MdUserApi.cpp @@ -27,7 +27,7 @@ ExchangeType TSecurityFtdcExchangeIDType_2_ExchangeType(TSecurityFtdcExchangeIDT case 'S': return ExchangeType::SSE; case 'Z': - return ExchangeType::SZE; + return ExchangeType::SZSE; default: return ExchangeType::Undefined_; } @@ -112,7 +112,7 @@ void CMdUserApi::Register(void* pCallback, void* pClass) } } -bool CMdUserApi::IsErrorRspInfo(CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) +bool CMdUserApi::IsErrorRspInfo(const char* szSource, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { bool bRet = ((pRspInfo) && (pRspInfo->ErrorID != 0)); if (bRet) @@ -121,6 +121,7 @@ bool CMdUserApi::IsErrorRspInfo(CSecurityFtdcRspInfoField *pRspInfo, int nReques pField->ErrorID = pRspInfo->ErrorID; strcpy(pField->ErrorMsg, pRspInfo->ErrorMsg); + strcpy(pField->Source, szSource); m_msgQueue->Input_NoCopy(ResponeType::OnRtnError, m_msgQueue, m_pClass, bIsLast, 0, pField, sizeof(ErrorField), nullptr, 0, nullptr, 0); } @@ -413,13 +414,13 @@ void CMdUserApi::OnRspUserLogin(CSecurityFtdcRspUserLoginField *pRspUserLogin, C void CMdUserApi::OnRspError(CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { - IsErrorRspInfo(pRspInfo, nRequestID, bIsLast); + IsErrorRspInfo("OnRspError", pRspInfo, nRequestID, bIsLast); } void CMdUserApi::OnRspSubMarketData(CSecurityFtdcSpecificInstrumentField *pSpecificInstrument, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { //ģƽ̨ᴥҪԼάһѾĵĺԼб - if(!IsErrorRspInfo(pRspInfo,nRequestID,bIsLast) + if (!IsErrorRspInfo("OnRspSubMarketData", pRspInfo, nRequestID, bIsLast) &&pSpecificInstrument) { lock_guard cl(m_csMapInstrumentIDs); @@ -439,7 +440,7 @@ void CMdUserApi::OnRspSubMarketData(CSecurityFtdcSpecificInstrumentField *pSpeci void CMdUserApi::OnRspUnSubMarketData(CSecurityFtdcSpecificInstrumentField *pSpecificInstrument, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { //ģƽ̨ᴥ - if(!IsErrorRspInfo(pRspInfo,nRequestID,bIsLast) + if (!IsErrorRspInfo("OnRspUnSubMarketData", pRspInfo, nRequestID, bIsLast) &&pSpecificInstrument) { lock_guard cl(m_csMapInstrumentIDs); diff --git a/QuantBox_LTS_Quote_v2/MdUserApi.h b/QuantBox_LTS_Quote_v2/MdUserApi.h index 1c2ca8d..6452742 100644 --- a/QuantBox_LTS_Quote_v2/MdUserApi.h +++ b/QuantBox_LTS_Quote_v2/MdUserApi.h @@ -73,7 +73,7 @@ class CMdUserApi : //virtual void OnRtnForQuoteRsp(CSecurityFtdcForQuoteRspField *pForQuoteRsp); //Ƿ - bool IsErrorRspInfo(CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast);//Ϣ͵Ϣ + bool IsErrorRspInfo(const char* szSource, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast);//Ϣ͵Ϣ bool IsErrorRspInfo(CSecurityFtdcRspInfoField *pRspInfo);//ͳϢ private: diff --git a/QuantBox_LTS_Quote_v2/QuantBox_LTS_Quote_v2.vcxproj b/QuantBox_LTS_Quote_v2/QuantBox_LTS_Quote_v2.vcxproj index 36adeb8..ba3fb43 100644 --- a/QuantBox_LTS_Quote_v2/QuantBox_LTS_Quote_v2.vcxproj +++ b/QuantBox_LTS_Quote_v2/QuantBox_LTS_Quote_v2.vcxproj @@ -94,7 +94,7 @@ true - d:\wukan\Documents\GitHub\QuantBox.DataReceiver\bin\Debug\XAPI\LTS_v2\x86 + C:\Program Files\SmartQuant Ltd\OpenQuant 2014\XAPI\LTS_v2\x86 true diff --git a/QuantBox_LTS_Quote_v2/main.cpp b/QuantBox_LTS_Quote_v2/main.cpp index 951d217..524f5d1 100644 --- a/QuantBox_LTS_Quote_v2/main.cpp +++ b/QuantBox_LTS_Quote_v2/main.cpp @@ -17,9 +17,9 @@ void* __stdcall XRequest(char type, void* pApi1, void* pApi2, double double1, do case GetApiType: return (void*)(ApiType::MarketData); case GetApiVersion: - return (void*)"0.3.0.20150407"; + return (void*)"0.1.0.20151112"; case GetApiName: - return (void*)"LTS"; + return (void*)"LTS2"; case Create: return new CMdUserApi(); default: diff --git a/QuantBox_LTS_Trade/TraderApi.cpp b/QuantBox_LTS_Trade/TraderApi.cpp index ad60499..cdbb340 100644 --- a/QuantBox_LTS_Trade/TraderApi.cpp +++ b/QuantBox_LTS_Trade/TraderApi.cpp @@ -112,7 +112,7 @@ CTraderApi::~CTraderApi(void) Disconnect(); } -bool CTraderApi::IsErrorRspInfo(CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) +bool CTraderApi::IsErrorRspInfo(const char* szSource, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { bool bRet = ((pRspInfo) && (pRspInfo->ErrorID != 0)); if (bRet) @@ -121,6 +121,7 @@ bool CTraderApi::IsErrorRspInfo(CSecurityFtdcRspInfoField *pRspInfo, int nReques pField->ErrorID = pRspInfo->ErrorID; strcpy(pField->ErrorMsg, pRspInfo->ErrorMsg); + strcpy(pField->Source, szSource); m_msgQueue->Input_NoCopy(ResponeType::OnRtnError, m_msgQueue, m_pClass, bIsLast, 0, pField, sizeof(ErrorField), nullptr, 0, nullptr, 0); } @@ -460,6 +461,7 @@ int CTraderApi::ReqOrderInsert( OrderField* pField = (OrderField*)m_msgQueue->new_block(sizeof(OrderField)); memcpy(pField, pOrder, sizeof(OrderField)); strcpy(pField->ID, m_orderInsert_Id); + strcpy(pField->LocalID, pField->ID); m_id_platform_order.insert(pair(m_orderInsert_Id, pField)); } strncpy((char*)pInOut, m_orderInsert_Id, sizeof(OrderIDType)); @@ -477,7 +479,7 @@ void CTraderApi::OnRspOrderInsert(CSecurityFtdcInputOrderField *pInputOrder, CSe } else { - IsErrorRspInfo(pRspInfo, nRequestID, bIsLast); + IsErrorRspInfo("OnRspOrderInsert", pRspInfo, nRequestID, bIsLast); } unordered_map::iterator it = m_id_platform_order.find(orderId); @@ -492,6 +494,7 @@ void CTraderApi::OnRspOrderInsert(CSecurityFtdcInputOrderField *pInputOrder, CSe // ʹϴε״̬ OrderField* pField = it->second; strcpy(pField->ID, orderId); + strcpy(pField->LocalID, pField->ID); pField->ExecType = ExecType::ExecRejected; pField->Status = OrderStatus::Rejected; pField->ErrorID = pRspInfo->ErrorID; @@ -509,7 +512,7 @@ void CTraderApi::OnErrRtnOrderInsert(CSecurityFtdcInputOrderField *pInputOrder, } else { - IsErrorRspInfo(pRspInfo, 0, true); + IsErrorRspInfo("OnErrRtnOrderInsert", pRspInfo, 0, true); } unordered_map::iterator it = m_id_platform_order.find(orderId); @@ -525,6 +528,7 @@ void CTraderApi::OnErrRtnOrderInsert(CSecurityFtdcInputOrderField *pInputOrder, // ʹϴε״̬ OrderField* pField = it->second; strcpy(pField->ID, orderId); + strcpy(pField->LocalID, pField->ID); pField->ExecType = ExecType::ExecRejected; pField->Status = OrderStatus::Rejected; pField->ErrorID = pRspInfo->ErrorID; @@ -602,7 +606,7 @@ void CTraderApi::OnRspOrderAction(CSecurityFtdcInputOrderActionField *pInputOrde } else { - IsErrorRspInfo(pRspInfo, nRequestID, bIsLast); + IsErrorRspInfo("OnRspOrderAction",pRspInfo, nRequestID, bIsLast); } unordered_map::iterator it = m_id_platform_order.find(orderId); @@ -632,7 +636,7 @@ void CTraderApi::OnErrRtnOrderAction(CSecurityFtdcOrderActionField *pOrderAction } else { - IsErrorRspInfo(pRspInfo, 0, true); + IsErrorRspInfo("OnErrRtnOrderAction", pRspInfo, 0, true); } unordered_map::iterator it = m_id_platform_order.find(orderId); @@ -676,7 +680,7 @@ int CTraderApi::_ReqQryTradingAccount(char type, void* pApi1, void* pApi2, doubl void CTraderApi::OnRspQryTradingAccount(CSecurityFtdcTradingAccountField *pTradingAccount, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { - if (!IsErrorRspInfo(pRspInfo, nRequestID, bIsLast)) + if (!IsErrorRspInfo("OnRspQryTradingAccount", pRspInfo, nRequestID, bIsLast)) { if (pTradingAccount) { @@ -730,7 +734,7 @@ int CTraderApi::_ReqQryInvestorPosition(char type, void* pApi1, void* pApi2, dou // пƽͶͶǿ void CTraderApi::OnRspQryInvestorPosition(CSecurityFtdcInvestorPositionField *pInvestorPosition, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { - if (!IsErrorRspInfo(pRspInfo, nRequestID, bIsLast)) + if (!IsErrorRspInfo("OnRspQryInvestorPosition", pRspInfo, nRequestID, bIsLast)) { if (pInvestorPosition) { @@ -795,7 +799,7 @@ int CTraderApi::_ReqQryInstrument(char type, void* pApi1, void* pApi2, double do void CTraderApi::OnRspQryInstrument(CSecurityFtdcInstrumentField *pInstrument, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { - if (!IsErrorRspInfo(pRspInfo, nRequestID, bIsLast)) + if (!IsErrorRspInfo("OnRspQryInstrument", pRspInfo, nRequestID, bIsLast)) { if (pInstrument) { @@ -863,7 +867,7 @@ void CTraderApi::OnRspQryInstrument(CSecurityFtdcInstrumentField *pInstrument, C void CTraderApi::OnRspError(CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { - IsErrorRspInfo(pRspInfo, nRequestID, bIsLast); + IsErrorRspInfo("OnRspError", pRspInfo, nRequestID, bIsLast); } void CTraderApi::ReqQryOrder() @@ -926,6 +930,7 @@ void CTraderApi::OnOrder(CSecurityFtdcOrderField *pOrder, bool bFromQry) pField = (OrderField*)m_msgQueue->new_block(sizeof(OrderField)); strcpy(pField->ID, orderId); + strcpy(pField->LocalID, pField->ID); strcpy(pField->InstrumentID, pOrder->InstrumentID); strcpy(pField->ExchangeID, pOrder->ExchangeID); pField->HedgeFlag = TSecurityFtdcHedgeFlagType_2_HedgeFlagType(pOrder->CombHedgeFlag[0]); @@ -949,6 +954,7 @@ void CTraderApi::OnOrder(CSecurityFtdcOrderField *pOrder, bool bFromQry) { pField = it->second; strcpy(pField->ID, orderId); + strcpy(pField->LocalID, pField->ID); pField->LeavesQty = pOrder->VolumeTotal; pField->Price = atof(pOrder->LimitPrice); pField->Status = CSecurityFtdcOrderField_2_OrderStatus(pOrder); @@ -963,7 +969,7 @@ void CTraderApi::OnOrder(CSecurityFtdcOrderField *pOrder, bool bFromQry) void CTraderApi::OnRspQryOrder(CSecurityFtdcOrderField *pOrder, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { - if (!IsErrorRspInfo(pRspInfo, nRequestID, bIsLast)) + if (!IsErrorRspInfo("OnRspQryOrder", pRspInfo, nRequestID, bIsLast)) { OnOrder(pOrder, true); } @@ -1095,7 +1101,7 @@ void CTraderApi::OnTrade(TradeField *pTrade, bool bFromQry) void CTraderApi::OnRspQryTrade(CSecurityFtdcTradeField *pTrade, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { - if (!IsErrorRspInfo(pRspInfo, nRequestID, bIsLast)) + if (!IsErrorRspInfo("OnRspQryTrade", pRspInfo, nRequestID, bIsLast)) { OnTrade(pTrade,true); } @@ -1119,7 +1125,7 @@ int CTraderApi::_ReqQryInvestor(char type, void* pApi1, void* pApi2, double doub void CTraderApi::OnRspQryInvestor(CSecurityFtdcInvestorField *pInvestor, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { - if (!IsErrorRspInfo(pRspInfo, nRequestID, bIsLast)) + if (!IsErrorRspInfo("OnRspQryInvestor", pRspInfo, nRequestID, bIsLast)) { if (pInvestor) { diff --git a/QuantBox_LTS_Trade/TraderApi.h b/QuantBox_LTS_Trade/TraderApi.h index eae1858..bd64513 100644 --- a/QuantBox_LTS_Trade/TraderApi.h +++ b/QuantBox_LTS_Trade/TraderApi.h @@ -120,7 +120,7 @@ class CTraderApi : void OnTrade(TradeField *pTrade, bool bFromQry); //Ƿ - bool IsErrorRspInfo(CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast);//ϢϢ + bool IsErrorRspInfo(const char* szSource, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast);//ϢϢ bool IsErrorRspInfo(CSecurityFtdcRspInfoField *pRspInfo);//Ϣ // diff --git a/QuantBox_LTS_Trade/TypeConvert.cpp b/QuantBox_LTS_Trade/TypeConvert.cpp index baf6754..b7e36ef 100644 --- a/QuantBox_LTS_Trade/TypeConvert.cpp +++ b/QuantBox_LTS_Trade/TypeConvert.cpp @@ -314,7 +314,7 @@ ExchangeType TSecurityFtdcExchangeIDType_2_ExchangeType(TSecurityFtdcExchangeIDT case 'S': return ExchangeType::SSE; case 'Z': - return ExchangeType::SZE; + return ExchangeType::SZSE; default: return ExchangeType::Undefined_; } diff --git a/QuantBox_LTS_Trade/main.cpp b/QuantBox_LTS_Trade/main.cpp index d886eed..4a0f357 100644 --- a/QuantBox_LTS_Trade/main.cpp +++ b/QuantBox_LTS_Trade/main.cpp @@ -14,7 +14,7 @@ void* __stdcall XRequest(char type, void* pApi1, void* pApi2, double double1, do switch (rt) { case GetApiType: - return (void*)(ApiType::Trade | ApiType::Instrument); + return (void*)(ApiType::Trade | ApiType::Instrument | ApiType::Query_); case GetApiVersion: return (void*)"0.3.0.20150407"; case GetApiName: diff --git a/QuantBox_LTS_Trade_v2/QuantBox_LTS_Trade_v2.vcxproj b/QuantBox_LTS_Trade_v2/QuantBox_LTS_Trade_v2.vcxproj index 128b0e4..d474d26 100644 --- a/QuantBox_LTS_Trade_v2/QuantBox_LTS_Trade_v2.vcxproj +++ b/QuantBox_LTS_Trade_v2/QuantBox_LTS_Trade_v2.vcxproj @@ -140,7 +140,6 @@ xcopy "$(SolutionDir)include\LTS_v2\win32\*.dll" "$(SolutionDir)XAPI\LTS_v2\x86 - @@ -161,7 +160,6 @@ xcopy "$(SolutionDir)include\LTS_v2\win32\*.dll" "$(SolutionDir)XAPI\LTS_v2\x86 - Create Create diff --git a/QuantBox_LTS_Trade_v2/QuantBox_LTS_Trade_v2.vcxproj.filters b/QuantBox_LTS_Trade_v2/QuantBox_LTS_Trade_v2.vcxproj.filters index 2704208..65997a2 100644 --- a/QuantBox_LTS_Trade_v2/QuantBox_LTS_Trade_v2.vcxproj.filters +++ b/QuantBox_LTS_Trade_v2/QuantBox_LTS_Trade_v2.vcxproj.filters @@ -36,9 +36,6 @@ Header Files - - Header Files - @@ -62,8 +59,5 @@ Source Files - - Source Files - \ No newline at end of file diff --git a/QuantBox_LTS_Trade_v2/TraderApi.cpp b/QuantBox_LTS_Trade_v2/TraderApi.cpp index b4c3715..588f5da 100644 --- a/QuantBox_LTS_Trade_v2/TraderApi.cpp +++ b/QuantBox_LTS_Trade_v2/TraderApi.cpp @@ -1,4 +1,4 @@ -#include "stdafx.h" +#include "stdafx.h" #include "TraderApi.h" #include "../include/QueueEnum.h" @@ -18,7 +18,7 @@ void* __stdcall Query(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3) { - // ڲãüǷΪ + // 由内部调用,不用检查是否为空 CTraderApi* pApi = (CTraderApi*)pApi2; pApi->QueryInThread(type, pApi1, pApi2, double1, double2, ptr1, size1, ptr2, size2, ptr3, size3); return nullptr; @@ -35,6 +35,9 @@ void CTraderApi::QueryInThread(char type, void* pApi1, void* pApi2, double doubl case E_ReqUserLoginField: iRet = _ReqUserLogin(type, pApi1, pApi2, double1, double2, ptr1, size1, ptr2, size2, ptr3, size3); break; + case E_AuthRandCodeField: + iRet = _ReqFetchAuthRandCode(type, pApi1, pApi2, double1, double2, ptr1, size1, ptr2, size2, ptr3, size3); + break; //case E_QryTradingAccountField: // iRet = _ReqQryTradingAccount(type, pApi1, pApi2, double1, double2, ptr1, size1, ptr2, size2, ptr3, size3); // break; @@ -59,13 +62,13 @@ void CTraderApi::QueryInThread(char type, void* pApi1, void* pApi2, double doubl if (0 == iRet) { - //سɹӵѷͳ + //返回成功,填加到已发送池 m_nSleep = 1; } else { m_msgQueue_Query->Input_Copy(type, pApi1, pApi2, double1, double2, ptr1, size1, ptr2, size2, ptr3, size3); - //ʧܣ4ݽʱ1s + //失败,按4的幂进行延时,但不超过1s m_nSleep *= 4; m_nSleep %= 1023; } @@ -98,7 +101,7 @@ CTraderApi::CTraderApi(void) m_lRequestID = 0; m_nSleep = 1; - // ԼάϢ + // 自己维护两个消息队列 m_msgQueue = new CMsgQueue(); m_msgQueue_Query = new CMsgQueue(); @@ -112,7 +115,7 @@ CTraderApi::~CTraderApi(void) Disconnect(); } -bool CTraderApi::IsErrorRspInfo(CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) +bool CTraderApi::IsErrorRspInfo(const char* szSource, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { bool bRet = ((pRspInfo) && (pRspInfo->ErrorID != 0)); if (bRet) @@ -121,6 +124,7 @@ bool CTraderApi::IsErrorRspInfo(CSecurityFtdcRspInfoField *pRspInfo, int nReques pField->ErrorID = pRspInfo->ErrorID; strcpy(pField->ErrorMsg, pRspInfo->ErrorMsg); + strcpy(pField->Source, szSource); m_msgQueue->Input_NoCopy(ResponeType::OnRtnError, m_msgQueue, m_pClass, bIsLast, 0, pField, sizeof(ErrorField), nullptr, 0, nullptr, 0); } @@ -162,7 +166,7 @@ int CTraderApi::_Init() { m_pApi->RegisterSpi(this); - //ӵַ + //添加地址 size_t len = strlen(m_ServerInfo.Address) + 1; char* buf = new char[len]; strncpy(buf, m_ServerInfo.Address, len); @@ -184,7 +188,7 @@ int CTraderApi::_Init() m_pApi->SubscribePrivateTopic((SECURITY_TE_RESUME_TYPE)m_ServerInfo.PrivateTopicResumeType); m_msgQueue->Input_NoCopy(ResponeType::OnConnectionStatus, m_msgQueue, m_pClass, ConnectionStatus::Connecting, 0, nullptr, 0, nullptr, 0, nullptr, 0); - //ʼ + //初始化连接 m_pApi->Init(); } @@ -208,10 +212,10 @@ void CTraderApi::Disconnect() m_pApi->Release(); m_pApi = nullptr; - // ȫֻһ + // 全清理,只留最后一个 m_msgQueue->Clear(); m_msgQueue->Input_NoCopy(ResponeType::OnConnectionStatus, m_msgQueue, m_pClass, ConnectionStatus::Disconnected, 0, nullptr, 0, nullptr, 0, nullptr, 0); - // + // 主动触发 m_msgQueue->Process(); } @@ -224,7 +228,7 @@ void CTraderApi::Disconnect() m_msgQueue = nullptr; } - m_lRequestID = 0;//߳ѾֹͣûбҪԭӲ + m_lRequestID = 0;//由于线程已经停止,没有必要用原子操作了 Clear(); } @@ -256,21 +260,58 @@ void CTraderApi::OnFrontConnected() { m_msgQueue->Input_NoCopy(ResponeType::OnConnectionStatus, m_msgQueue, m_pClass, ConnectionStatus::Connected, 0, nullptr, 0, nullptr, 0, nullptr, 0); - ReqUserLogin(); + //ReqUserLogin(); + ReqFetchAuthRandCode(); } void CTraderApi::OnFrontDisconnected(int nReason) { RspUserLoginField* pField = (RspUserLoginField*)m_msgQueue->new_block(sizeof(RspUserLoginField)); - //ʧܷصϢƴӶɣҪΪͳһ + //连接失败返回的信息是拼接而成,主要是为了统一输出 pField->ErrorID = nReason; GetOnFrontDisconnectedMsg(nReason, pField->ErrorMsg); m_msgQueue->Input_NoCopy(ResponeType::OnConnectionStatus, m_msgQueue, m_pClass, ConnectionStatus::Disconnected, 0, pField, sizeof(RspUserLoginField), nullptr, 0, nullptr, 0); } -void CTraderApi::ReqUserLogin() +void CTraderApi::ReqFetchAuthRandCode() +{ + CSecurityFtdcAuthRandCodeField* pBody = (CSecurityFtdcAuthRandCodeField*)m_msgQueue_Query->new_block(sizeof(CSecurityFtdcAuthRandCodeField)); + + strncpy(pBody->RandCode, "", sizeof(TSecurityFtdcAuthCodeType)); + + m_msgQueue_Query->Input_NoCopy(RequestType::E_AuthRandCodeField, m_msgQueue_Query, this, 0, 0, + pBody, sizeof(CSecurityFtdcAuthRandCodeField), nullptr, 0, nullptr, 0); +} + +int CTraderApi::_ReqFetchAuthRandCode(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3) +{ + m_msgQueue->Input_NoCopy(ResponeType::OnConnectionStatus, m_msgQueue, m_pClass, ConnectionStatus::Authorizing, 0, nullptr, 0, nullptr, 0, nullptr, 0); + return m_pApi->ReqFetchAuthRandCode((CSecurityFtdcAuthRandCodeField*)ptr1, ++m_lRequestID); +} + +void CTraderApi::OnRspFetchAuthRandCode(CSecurityFtdcAuthRandCodeField *pAuthRandCode, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) +{ + RspUserLoginField* pField = (RspUserLoginField*)m_msgQueue->new_block(sizeof(RspUserLoginField)); + + if (!IsErrorRspInfo(pRspInfo) + && pAuthRandCode) + { + m_msgQueue->Input_NoCopy(ResponeType::OnConnectionStatus, m_msgQueue, m_pClass, ConnectionStatus::Authorized, 0, pField, sizeof(RspUserLoginField), nullptr, 0, nullptr, 0); + + ReqUserLogin(pAuthRandCode->RandCode); + } + else + { + pField->ErrorID = pRspInfo->ErrorID; + strncpy(pField->ErrorMsg, pRspInfo->ErrorMsg, sizeof(ErrorMsgType)); + + m_msgQueue->Input_NoCopy(ResponeType::OnConnectionStatus, m_msgQueue, m_pClass, ConnectionStatus::Disconnected, 0, pField, sizeof(RspUserLoginField), nullptr, 0, nullptr, 0); + } +} + +void CTraderApi::ReqUserLogin(TSecurityFtdcAuthCodeType RandCode) { CSecurityFtdcReqUserLoginField* pBody = (CSecurityFtdcReqUserLoginField*)m_msgQueue_Query->new_block(sizeof(CSecurityFtdcReqUserLoginField)); @@ -278,6 +319,8 @@ void CTraderApi::ReqUserLogin() strncpy(pBody->UserID, m_UserInfo.UserID, sizeof(TSecurityFtdcInvestorIDType)); strncpy(pBody->Password, m_UserInfo.Password, sizeof(TSecurityFtdcPasswordType)); strncpy(pBody->UserProductInfo, m_ServerInfo.UserProductInfo, sizeof(TSecurityFtdcProductInfoType)); + strncpy(pBody->AuthCode, m_ServerInfo.AuthCode, sizeof(TSecurityFtdcAuthCodeType)); + strncpy(pBody->RandCode, RandCode, sizeof(TSecurityFtdcAuthCodeType)); m_msgQueue_Query->Input_NoCopy(RequestType::E_ReqUserLoginField, m_msgQueue_Query, this, 0, 0, pBody, sizeof(CSecurityFtdcReqUserLoginField), nullptr, 0, nullptr, 0); @@ -303,10 +346,10 @@ void CTraderApi::OnRspUserLogin(CSecurityFtdcRspUserLoginField *pRspUserLogin, C m_msgQueue->Input_NoCopy(ResponeType::OnConnectionStatus, m_msgQueue, m_pClass, ConnectionStatus::Logined, 0, pField, sizeof(RspUserLoginField), nullptr, 0, nullptr, 0); - // µ¼Ϣܻõ + // 记下登录信息,可能会用到 memcpy(&m_RspUserLogin,pRspUserLogin,sizeof(CSecurityFtdcRspUserLoginField)); m_nMaxOrderRef = atol(pRspUserLogin->MaxOrderRef); - // ԼʱID1ʼܴ0ʼ + // 自己发单时ID从1开始,不能从0开始 m_nMaxOrderRef = m_nMaxOrderRef>1 ? m_nMaxOrderRef : 1; //ReqSettlementInfoConfirm(); //ReqQryInvestor(); @@ -350,36 +393,36 @@ int CTraderApi::ReqOrderInsert( body.UserForceClose = 0; //body.IsSwapOrder = 0; - //Լ + //合约 strncpy(body.InstrumentID, pOrder->InstrumentID, sizeof(TSecurityFtdcInstrumentIDType)); strncpy(body.ExchangeID, pOrder->ExchangeID, sizeof(TSecurityFtdcExchangeIDType)); - // + //买卖 body.Direction = OrderSide_2_TSecurityFtdcDirectionType(pOrder->Side); - //ƽ + //开平 body.CombOffsetFlag[0] = OpenCloseType_2_TSecurityFtdcOffsetFlagType(pOrder->OpenClose); - //Ͷ + //投保 body.CombHedgeFlag[0] = HedgeFlagType_2_TSecurityFtdcHedgeFlagType(pOrder->HedgeFlag); - // + //数量 body.VolumeTotalOriginal = (int)pOrder->Qty; - // õһļ۸񣬻ļ۸أ + // 对于套利单,是用第一个参数的价格,还是用两个参数的价格差呢? //body.LimitPrice = pOrder1->Price; sprintf(body.LimitPrice, "%f", pOrder->Price); body.StopPrice = pOrder->StopPx; - // ԵڶдеڶΪǽ + // 针对第二个进行处理,如果有第二个参数,认为是交易所套利单 if (count>1) { body.CombOffsetFlag[1] = OpenCloseType_2_TSecurityFtdcOffsetFlagType(pOrder[1].OpenClose); body.CombHedgeFlag[1] = HedgeFlagType_2_TSecurityFtdcHedgeFlagType(pOrder[1].HedgeFlag); - // Ʋֻ¹ܣûʵ + // 交易所的移仓换月功能,没有实测过 //body.IsSwapOrder = (body.CombOffsetFlag[0] != body.CombOffsetFlag[1]); } - //۸ + //价格 //body.OrderPriceType = OrderType_2_TSecurityFtdcOrderPriceTypeType(pOrder1->Type); - // м޼ + // 市价与限价 switch (pOrder->Type) { case Market: @@ -398,7 +441,7 @@ int CTraderApi::ReqOrderInsert( break; } - // IOCFOK + // IOC与FOK switch (pOrder->TimeInForce) { case IOC: @@ -408,21 +451,21 @@ int CTraderApi::ReqOrderInsert( case FOK: body.TimeCondition = SECURITY_FTDC_TC_IOC; body.VolumeCondition = SECURITY_FTDC_VC_CV; - //body.MinVolume = body.VolumeTotalOriginal; // ط + //body.MinVolume = body.VolumeTotalOriginal; // 这个地方必须加吗? break; default: body.VolumeCondition = SECURITY_FTDC_VC_AV; break; } - // + // 条件单 switch (pOrder->Type) { case Stop: case TrailingStop: case StopLimit: case TrailingStopLimit: - // ûвԣ + // 条件单没有测试,先留空 body.ContingentCondition = SECURITY_FTDC_CC_Immediately; break; default: @@ -432,7 +475,7 @@ int CTraderApi::ReqOrderInsert( int nRet = 0; { - //ܱ̫죬m_nMaxOrderRefûиıύ + //可能报单太快,m_nMaxOrderRef还没有改变就提交了 lock_guard cl(m_csOrderRef); if (OrderRef < 0) @@ -446,7 +489,7 @@ int CTraderApi::ReqOrderInsert( } sprintf(body.OrderRef, "%d", nRet); - //浽Уֱӷ + //不保存到队列,而是直接发送 int n = m_pApi->ReqOrderInsert(&body, ++m_lRequestID); if (n < 0) { @@ -460,6 +503,7 @@ int CTraderApi::ReqOrderInsert( OrderField* pField = (OrderField*)m_msgQueue->new_block(sizeof(OrderField)); memcpy(pField, pOrder, sizeof(OrderField)); strcpy(pField->ID, m_orderInsert_Id); + strcpy(pField->LocalID, pField->ID); m_id_platform_order.insert(pair(m_orderInsert_Id, pField)); } strncpy((char*)pInOut, m_orderInsert_Id, sizeof(OrderIDType)); @@ -477,21 +521,22 @@ void CTraderApi::OnRspOrderInsert(CSecurityFtdcInputOrderField *pInputOrder, CSe } else { - IsErrorRspInfo(pRspInfo, nRequestID, bIsLast); + IsErrorRspInfo("OnRspOrderInsert", pRspInfo, nRequestID, bIsLast); } unordered_map::iterator it = m_id_platform_order.find(orderId); if (it == m_id_platform_order.end()) { - // ûҵӦʾ + // 没找到?不应当,这表示出错了 //assert(false); } else { - // ҵˣҪ״̬ - // ʹϴε״̬ + // 找到了,要更新状态 + // 得使用上次的状态 OrderField* pField = it->second; strcpy(pField->ID, orderId); + strcpy(pField->LocalID, pField->ID); pField->ExecType = ExecType::ExecRejected; pField->Status = OrderStatus::Rejected; pField->ErrorID = pRspInfo->ErrorID; @@ -509,22 +554,23 @@ void CTraderApi::OnErrRtnOrderInsert(CSecurityFtdcInputOrderField *pInputOrder, } else { - IsErrorRspInfo(pRspInfo, 0, true); + IsErrorRspInfo("OnErrRtnOrderInsert", pRspInfo, 0, true); } unordered_map::iterator it = m_id_platform_order.find(orderId); if (it == m_id_platform_order.end()) { - // ûҵӦʾ + // 没找到?不应当,这表示出错了 //assert(false); - // LTSڿʼʱҲյ˻رﰡ + // LTS在开始连接时也会收到此回报,无语啊 } else { - // ҵˣҪ״̬ - // ʹϴε״̬ + // 找到了,要更新状态 + // 得使用上次的状态 OrderField* pField = it->second; strcpy(pField->ID, orderId); + strcpy(pField->LocalID, pField->ID); pField->ExecType = ExecType::ExecRejected; pField->Status = OrderStatus::Rejected; pField->ErrorID = pRspInfo->ErrorID; @@ -548,7 +594,7 @@ int CTraderApi::ReqOrderAction(OrderIDType* szIds, int count, OrderIDType* pOutp } else { - // ҵ˶ + // 找到了订单 return ReqOrderAction(it->second, count, pOutput); } } @@ -560,23 +606,23 @@ int CTraderApi::ReqOrderAction(CSecurityFtdcOrderField *pOrder, int count, Order CSecurityFtdcInputOrderActionField body = {0}; - ///͹˾ + ///经纪公司代码 strncpy(body.BrokerID, pOrder->BrokerID,sizeof(TSecurityFtdcBrokerIDType)); - ///Ͷߴ + ///投资者代码 strncpy(body.InvestorID, pOrder->InvestorID,sizeof(TSecurityFtdcInvestorIDType)); - /// + ///报单引用 strncpy(body.OrderRef, pOrder->OrderRef,sizeof(TSecurityFtdcOrderRefType)); - ///ǰñ + ///前置编号 body.FrontID = pOrder->FrontID; - ///Ự + ///会话编号 body.SessionID = pOrder->SessionID; - /// + ///交易所代码 strncpy(body.ExchangeID,pOrder->ExchangeID,sizeof(TSecurityFtdcExchangeIDType)); - /// + ///报单编号 //strncpy(body.OrderSysID,pOrder->OrderSysID,sizeof(TSecurityFtdcOrderSysIDType)); - ///־ + ///操作标志 body.ActionFlag = SECURITY_FTDC_AF_Delete; - ///Լ + ///合约代码 strncpy(body.InstrumentID, pOrder->InstrumentID,sizeof(TSecurityFtdcInstrumentIDType)); int nRet = m_pApi->ReqOrderAction(&body, ++m_lRequestID); @@ -602,19 +648,19 @@ void CTraderApi::OnRspOrderAction(CSecurityFtdcInputOrderActionField *pInputOrde } else { - IsErrorRspInfo(pRspInfo, nRequestID, bIsLast); + IsErrorRspInfo("OnRspOrderAction", pRspInfo, nRequestID, bIsLast); } unordered_map::iterator it = m_id_platform_order.find(orderId); if (it == m_id_platform_order.end()) { - // ûҵӦʾ + // 没找到?不应当,这表示出错了 //assert(false); } else { - // ҵˣҪ״̬ - // ʹϴε״̬ + // 找到了,要更新状态 + // 得使用上次的状态 OrderField* pField = it->second; pField->ExecType = ExecType::ExecCancelReject; pField->ErrorID = pRspInfo->ErrorID; @@ -632,19 +678,19 @@ void CTraderApi::OnErrRtnOrderAction(CSecurityFtdcOrderActionField *pOrderAction } else { - IsErrorRspInfo(pRspInfo, 0, true); + IsErrorRspInfo("OnErrRtnOrderAction", pRspInfo, 0, true); } unordered_map::iterator it = m_id_platform_order.find(orderId); if (it == m_id_platform_order.end()) { - // ûҵӦʾ + // 没找到?不应当,这表示出错了 //assert(false); } else { - // ҵˣҪ״̬ - // ʹϴε״̬ + // 找到了,要更新状态 + // 得使用上次的状态 OrderField* pField = it->second; pField->ExecType = ExecType::ExecCancelReject; pField->ErrorID = pRspInfo->ErrorID; @@ -658,230 +704,11 @@ void CTraderApi::OnRtnOrder(CSecurityFtdcOrderField *pOrder) OnOrder(pOrder,false); } -//void CTraderApi::ReqQryTradingAccount() -//{ -// CSecurityFtdcQryTradingAccountField* pBody = (CSecurityFtdcQryTradingAccountField*)m_msgQueue_Query->new_block(sizeof(CSecurityFtdcQryTradingAccountField)); -// -// strcpy(pBody->BrokerID, m_RspUserLogin.BrokerID); -// strcpy(pBody->InvestorID, m_RspUserLogin.UserID); -// -// m_msgQueue_Query->Input_NoCopy(RequestType::E_QryTradingAccountField, m_msgQueue_Query, this, 0, 0, -// pBody, sizeof(CSecurityFtdcQryTradingAccountField), nullptr, 0, nullptr, 0); -//} -// -//int CTraderApi::_ReqQryTradingAccount(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3) -//{ -// return m_pApi->ReqQryTradingAccount((CSecurityFtdcQryTradingAccountField*)ptr1, ++m_lRequestID); -//} -// -//void CTraderApi::OnRspQryTradingAccount(CSecurityFtdcTradingAccountField *pTradingAccount, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) -//{ -// if (!IsErrorRspInfo(pRspInfo, nRequestID, bIsLast)) -// { -// if (pTradingAccount) -// { -// AccountField* pField = (AccountField*)m_msgQueue->new_block(sizeof(AccountField)); -// -// strcpy(pField->Account, pTradingAccount->AccountID); -// pField->PreBalance = pTradingAccount->PreBalance; -// pField->CurrMargin = pTradingAccount->CurrMargin; -// //pField->CloseProfit = pTradingAccount->CloseProfit; -// //pField->PositionProfit = pTradingAccount->PositionProfit; -// pField->Balance = pTradingAccount->Balance; -// pField->Available = pTradingAccount->Available; -// pField->Deposit = pTradingAccount->Deposit; -// pField->Withdraw = pTradingAccount->Withdraw; -// pField->FrozenTransferFee = pTradingAccount->FrozenTransferFee; -// pField->FrozenStampTax = pTradingAccount->FrozenStampTax; -// pField->FrozenCommission = pTradingAccount->FrozenCommission; -// pField->FrozenCash = pTradingAccount->FrozenCash; -// pField->TransferFee = pTradingAccount->TransferFee; -// pField->StampTax = pTradingAccount->StampTax; -// pField->Commission = pTradingAccount->Commission; -// pField->CashIn = pTradingAccount->CashIn; -// -// m_msgQueue->Input_NoCopy(ResponeType::OnRspQryTradingAccount, m_msgQueue, m_pClass, bIsLast, 0, pField, sizeof(AccountField), nullptr, 0, nullptr, 0); -// } -// else -// { -// m_msgQueue->Input_NoCopy(ResponeType::OnRspQryTradingAccount, m_msgQueue, m_pClass, bIsLast, 0, nullptr, 0, nullptr, 0, nullptr, 0); -// } -// } -//} - -//void CTraderApi::ReqQryInvestorPosition(const string& szInstrumentId, const string& szExchange) -//{ -// CSecurityFtdcQryInvestorPositionField* pBody = (CSecurityFtdcQryInvestorPositionField*)m_msgQueue_Query->new_block(sizeof(CSecurityFtdcQryInvestorPositionField)); -// -// strcpy(pBody->BrokerID, m_RspUserLogin.BrokerID); -// strcpy(pBody->InvestorID, m_RspUserLogin.UserID); -// strncpy(pBody->InstrumentID, szInstrumentId.c_str(), sizeof(TSecurityFtdcInstrumentIDType)); -// -// m_msgQueue_Query->Input_NoCopy(RequestType::E_QryInvestorPositionField, m_msgQueue_Query, this, 0, 0, -// pBody, sizeof(CSecurityFtdcQryInvestorPositionField), nullptr, 0, nullptr, 0); -//} -// -//int CTraderApi::_ReqQryInvestorPosition(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3) -//{ -// return m_pApi->ReqQryInvestorPosition((CSecurityFtdcQryInvestorPositionField*)ptr1, ++m_lRequestID); -//} -// -//// ծعֲNetҹൽLongУֱӴӳɽзֹ鵽Net -//// пƽͶͶǿ -//void CTraderApi::OnRspQryInvestorPosition(CSecurityFtdcInvestorPositionField *pInvestorPosition, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) -//{ -// if (!IsErrorRspInfo(pRspInfo, nRequestID, bIsLast)) -// { -// if (pInvestorPosition) -// { -// PositionIDType positionId = { 0 }; -// sprintf(positionId, "%s:%s:%d:%d", -// pInvestorPosition->InstrumentID, pInvestorPosition->ExchangeID, -// TSecurityFtdcPosiDirectionType_2_PositionSide(pInvestorPosition->PosiDirection), TSecurityFtdcHedgeFlagType_2_HedgeFlagType(pInvestorPosition->HedgeFlag)); -// -// PositionField* pField = nullptr; -// unordered_map::iterator it = m_id_platform_position.find(positionId); -// if (it == m_id_platform_position.end()) -// { -// pField = (PositionField*)m_msgQueue->new_block(sizeof(PositionField)); -// -// sprintf(pField->Symbol, "%s.%s", pInvestorPosition->InstrumentID, pInvestorPosition->ExchangeID); -// strcpy(pField->InstrumentID, pInvestorPosition->InstrumentID); -// strcpy(pField->ExchangeID, pInvestorPosition->ExchangeID); -// pField->Side = TSecurityFtdcPosiDirectionType_2_PositionSide(pInvestorPosition->PosiDirection); -// pField->HedgeFlag = TSecurityFtdcHedgeFlagType_2_HedgeFlagType(pInvestorPosition->HedgeFlag); -// -// m_id_platform_position.insert(pair(positionId, pField)); -// } -// else -// { -// pField = it->second; -// } -// -// pField->Position = pInvestorPosition->Position; -// pField->TdPosition = pInvestorPosition->TodayPosition; -// pField->YdPosition = pInvestorPosition->YdPosition; -// -// // ռȫٱ֪ͨһ -// if (bIsLast) -// { -// int cnt = 0; -// int count = m_id_platform_position.size(); -// for (unordered_map::iterator iter = m_id_platform_position.begin(); iter != m_id_platform_position.end(); iter++) -// { -// ++cnt; -// m_msgQueue->Input_Copy(ResponeType::OnRspQryInvestorPosition, m_msgQueue, m_pClass, cnt == count, 0, iter->second, sizeof(PositionField), nullptr, 0, nullptr, 0); -// } -// } -// } -// } -//} - -//void CTraderApi::ReqQryInstrument(const string& szInstrumentId, const string& szExchange) -//{ -// CSecurityFtdcQryInstrumentField* pBody = (CSecurityFtdcQryInstrumentField*)m_msgQueue_Query->new_block(sizeof(CSecurityFtdcQryInstrumentField)); -// -// strncpy(pBody->InstrumentID, szInstrumentId.c_str(), sizeof(TSecurityFtdcInstrumentIDType)); -// strncpy(pBody->ExchangeID, szExchange.c_str(), sizeof(TSecurityFtdcExchangeIDType)); -// -// m_msgQueue_Query->Input_NoCopy(RequestType::E_QryInstrumentField, m_msgQueue_Query, this, 0, 0, -// pBody, sizeof(CSecurityFtdcQryInstrumentField), nullptr, 0, nullptr, 0); -//} -// -//int CTraderApi::_ReqQryInstrument(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3) -//{ -// return m_pApi->ReqQryInstrument((CSecurityFtdcQryInstrumentField*)ptr1, ++m_lRequestID); -//} -// -//void CTraderApi::OnRspQryInstrument(CSecurityFtdcInstrumentField *pInstrument, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) -//{ -// if (!IsErrorRspInfo(pRspInfo, nRequestID, bIsLast)) -// { -// if (pInstrument) -// { -// InstrumentField* pField = (InstrumentField*)m_msgQueue->new_block(sizeof(InstrumentField)); -// -// strncpy(pField->InstrumentID, pInstrument->InstrumentID, sizeof(InstrumentIDType)); -// strncpy(pField->ExchangeID, pInstrument->ExchangeID, sizeof(ExchangeIDType)); -// -// sprintf(pField->Symbol,"%s.%s",pInstrument->InstrumentID,pInstrument->ExchangeID); -// sprintf(pField->InstrumentName, "%s(%s)", pInstrument->ExchangeInstID, pInstrument->InstrumentName); -// strncpy(pField->ProductID, pInstrument->ProductID, sizeof(InstrumentIDType)); -// -// //strncpy(pField->InstrumentName, pInstrument->InstrumentName, sizeof(InstrumentNameType)); -// pField->Type = CSecurityFtdcInstrumentField_2_InstrumentType(pInstrument); -// pField->VolumeMultiple = pInstrument->VolumeMultiple; -// pField->PriceTick = CSecurityFtdcInstrumentField_2_PriceTick(pInstrument); -// pField->ExpireDate = GetDate(pInstrument->ExpireDate); -// pField->OptionsType = CSecurityFtdcInstrumentField_2_PutCall(pInstrument); -// pField->StrikePrice = pInstrument->ExecPrice; -// -// -// // Ȩı -// if (strlen(pInstrument->InstrumentID) == 8) -// { -// strncpy(pField->UnderlyingInstrID, pInstrument->ExchangeInstID, 6); -// sprintf(&pField->UnderlyingInstrID[6], ".%s", pInstrument->ExchangeID); -// } -// -// -// m_msgQueue->Input_NoCopy(ResponeType::OnRspQryInstrument, m_msgQueue, m_pClass, bIsLast, 0, pField, sizeof(InstrumentField), nullptr, 0, nullptr, 0); -// } -// else -// { -// m_msgQueue->Input_NoCopy(ResponeType::OnRspQryInstrument, m_msgQueue, m_pClass, bIsLast, 0, nullptr, 0, nullptr, 0, nullptr, 0); -// } -// } -//} -// -//void CTraderApi::ReqQryInstrumentCommissionRate(const string& szInstrumentId) -//{ -// if (nullptr == m_pApi) -// return; -// -// SRequest* pRequest = MakeRequestBuf(E_QryInstrumentCommissionRateField); -// if (nullptr == pRequest) -// return; -// -// CSecurityFtdcQryInstrumentCommissionRateField& body = pRequest->QryInstrumentCommissionRateField; -// -// strncpy(body.BrokerID, m_RspUserLogin.BrokerID,sizeof(TSecurityFtdcBrokerIDType)); -// strncpy(body.InvestorID, m_RspUserLogin.UserID,sizeof(TSecurityFtdcInvestorIDType)); -// strncpy(body.InstrumentID,szInstrumentId.c_str(),sizeof(TSecurityFtdcInstrumentIDType)); -// -// AddToSendQueue(pRequest); -//} -// -//void CTraderApi::OnRspQryInstrumentCommissionRate(CSecurityFtdcInstrumentCommissionRateField *pInstrumentCommissionRate, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) -//{ -// //if(m_msgQueue) -// // m_msgQueue->Input_OnRspQryInstrumentCommissionRate(this,pInstrumentCommissionRate,pRspInfo,nRequestID,bIsLast); -// -// if (bIsLast) -// ReleaseRequestMapBuf(nRequestID); -//} - void CTraderApi::OnRspError(CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) { - IsErrorRspInfo(pRspInfo, nRequestID, bIsLast); + IsErrorRspInfo("OnRspError", pRspInfo, nRequestID, bIsLast); } -//void CTraderApi::ReqQryOrder() -//{ -// CSecurityFtdcQryOrderField* pBody = (CSecurityFtdcQryOrderField*)m_msgQueue_Query->new_block(sizeof(CSecurityFtdcQryOrderField)); -// -// strncpy(pBody->BrokerID, m_RspUserLogin.BrokerID, sizeof(TSecurityFtdcBrokerIDType)); -// strncpy(pBody->InvestorID, m_RspUserLogin.UserID, sizeof(TSecurityFtdcInvestorIDType)); -// -// m_msgQueue_Query->Input_NoCopy(RequestType::E_QryOrderField, m_msgQueue_Query, this, 0, 0, -// pBody, sizeof(CSecurityFtdcQryOrderField), nullptr, 0, nullptr, 0); -//} -// -//int CTraderApi::_ReqQryOrder(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3) -//{ -// return m_pApi->ReqQryOrder((CSecurityFtdcQryOrderField*)ptr1, ++m_lRequestID); -//} - void CTraderApi::OnOrder(CSecurityFtdcOrderField *pOrder, bool bFromQry) { if (nullptr == pOrder) @@ -892,40 +719,41 @@ void CTraderApi::OnOrder(CSecurityFtdcOrderField *pOrder, bool bFromQry) OrderIDType orderSydId = { 0 }; { - // ԭʼϢڳ + // 保存原始订单信息,用于撤单 unordered_map::iterator it = m_id_api_order.find(orderId); if (it == m_id_api_order.end()) { - // Ҳ˶ʾµ + // 找不到此订单,表示是新单 CSecurityFtdcOrderField* pField = new CSecurityFtdcOrderField(); memcpy(pField, pOrder, sizeof(CSecurityFtdcOrderField)); m_id_api_order.insert(pair(orderId, pField)); } else { - // ҵ˶ - // ҪٸƱһε״ֻ̬Ҫһεڳɣ£ñȽ + // 找到了订单 + // 需要再复制保存最后一次的状态,还是只要第一次的用于撤单即可?记下,这样最后好比较 CSecurityFtdcOrderField* pField = it->second; memcpy(pField, pOrder, sizeof(CSecurityFtdcOrderField)); } - // SysIDڶɽر붩 + // 保存SysID用于定义成交回报与订单 sprintf(orderSydId, "%s:%s", pOrder->ExchangeID, pOrder->OrderSysID); m_sysId_orderId.insert(pair(orderSydId, orderId)); } { - // APIĶתԼĽṹ + // 从API的订单转换成自己的结构体 OrderField* pField = nullptr; unordered_map::iterator it = m_id_platform_order.find(orderId); if (it == m_id_platform_order.end()) { - // ʱϢûУҲӦĵӣҪOrderĻָ + // 开盘时发单信息还没有,所以找不到对应的单子,需要进行Order的恢复 pField = (OrderField*)m_msgQueue->new_block(sizeof(OrderField)); strcpy(pField->ID, orderId); + strcpy(pField->LocalID, pField->ID); strcpy(pField->InstrumentID, pOrder->InstrumentID); strcpy(pField->ExchangeID, pOrder->ExchangeID); pField->HedgeFlag = TSecurityFtdcHedgeFlagType_2_HedgeFlagType(pOrder->CombHedgeFlag[0]); @@ -942,13 +770,14 @@ void CTraderApi::OnOrder(CSecurityFtdcOrderField *pOrder, bool bFromQry) strcpy(pField->OrderID, pOrder->OrderSysID); - // ӵmapУߵĶȡʧʱ֪ͨ + // 添加到map中,用于其它工具的读取,撤单失败时的再通知等 m_id_platform_order.insert(pair(orderId, pField)); } else { pField = it->second; strcpy(pField->ID, orderId); + strcpy(pField->LocalID, pField->ID); pField->LeavesQty = pOrder->VolumeTotal; pField->Price = atof(pOrder->LimitPrice); pField->Status = CSecurityFtdcOrderField_2_OrderStatus(pOrder); @@ -961,30 +790,6 @@ void CTraderApi::OnOrder(CSecurityFtdcOrderField *pOrder, bool bFromQry) } } -//void CTraderApi::OnRspQryOrder(CSecurityFtdcOrderField *pOrder, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) -//{ -// if (!IsErrorRspInfo(pRspInfo, nRequestID, bIsLast)) -// { -// OnOrder(pOrder, true); -// } -//} - -//void CTraderApi::ReqQryTrade() -//{ -// CSecurityFtdcQryTradeField* pBody = (CSecurityFtdcQryTradeField*)m_msgQueue_Query->new_block(sizeof(CSecurityFtdcQryTradeField)); -// -// strcpy(pBody->BrokerID, m_RspUserLogin.BrokerID); -// strcpy(pBody->InvestorID, m_RspUserLogin.UserID); -// -// m_msgQueue_Query->Input_NoCopy(RequestType::E_QryTradeField, m_msgQueue_Query, this, 0, 0, -// pBody, sizeof(CSecurityFtdcQryTradeField), nullptr, 0, nullptr, 0); -//} -// -//int CTraderApi::_ReqQryTrade(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3) -//{ -// return m_pApi->ReqQryTrade((CSecurityFtdcQryTradeField*)ptr1, ++m_lRequestID); -//} - void CTraderApi::OnTrade(CSecurityFtdcTradeField *pTrade, bool bFromQry) { if (nullptr == pTrade) @@ -999,7 +804,7 @@ void CTraderApi::OnTrade(CSecurityFtdcTradeField *pTrade, bool bFromQry) pField->Price = atof(pTrade->Price); pField->OpenClose = TSecurityFtdcOffsetFlagType_2_OpenCloseType(pTrade->OffsetFlag); pField->HedgeFlag = TSecurityFtdcHedgeFlagType_2_HedgeFlagType(pTrade->HedgeFlag); - pField->Commission = 0;//TODOԺҪ + pField->Commission = 0;//TODO收续费以后要计算出来 pField->Time = GetTime(pTrade->TradeTime); strcpy(pField->TradeID, pTrade->TradeID); @@ -1008,12 +813,12 @@ void CTraderApi::OnTrade(CSecurityFtdcTradeField *pTrade, bool bFromQry) unordered_map::iterator it = m_sysId_orderId.find(orderSysId); if (it == m_sysId_orderId.end()) { - // ˳ɽҲӦı + // 此成交找不到对应的报单 //assert(false); } else { - // ҵӦı + // 找到对应的报单 strcpy(pField->ID, it->second.c_str()); m_msgQueue->Input_Copy(ResponeType::OnRtnTrade, m_msgQueue, m_pClass, 0, 0, pField, sizeof(TradeField), nullptr, 0, nullptr, 0); @@ -1021,16 +826,17 @@ void CTraderApi::OnTrade(CSecurityFtdcTradeField *pTrade, bool bFromQry) unordered_map::iterator it2 = m_id_platform_order.find(it->second); if (it2 == m_id_platform_order.end()) { - // ˳ɽҲӦı + // 此成交找不到对应的报单 //assert(false); } else { - // ¶״̬ - // ǷҪ֪ͨӿ + // 更新订单的状态 + // 是否要通知接口 } - OnTrade(pField, bFromQry); + // 查询与交易分离,所以本地计算更新持仓的功能失效 + //OnTrade(pField, bFromQry); } } @@ -1074,7 +880,7 @@ void CTraderApi::OnTrade(TradeField *pTrade, bool bFromQry) else { pField->YdPosition -= pTrade->Qty; - // ıɸӽ쿪ʼ + // 如果昨天的被减成负数,从今天开始继续减 if (pField->YdPosition<0) { pField->TdPosition += pField->YdPosition; @@ -1082,7 +888,7 @@ void CTraderApi::OnTrade(TradeField *pTrade, bool bFromQry) } } - // ֱ²ѯ + // 计算错误,直接重新查询 //if (pField->Position < 0 || pField->TdPosition < 0 || pField->YdPosition < 0) //{ // ReqQryInvestorPosition("", ""); @@ -1091,53 +897,4 @@ void CTraderApi::OnTrade(TradeField *pTrade, bool bFromQry) } m_msgQueue->Input_Copy(ResponeType::OnRspQryInvestorPosition, m_msgQueue, m_pClass, false, 0, pField, sizeof(PositionField), nullptr, 0, nullptr, 0); -} - -//void CTraderApi::OnRspQryTrade(CSecurityFtdcTradeField *pTrade, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) -//{ -// if (!IsErrorRspInfo(pRspInfo, nRequestID, bIsLast)) -// { -// OnTrade(pTrade,true); -// } -//} - -//void CTraderApi::ReqQryInvestor() -//{ -// CSecurityFtdcQryInvestorField* pBody = (CSecurityFtdcQryInvestorField*)m_msgQueue_Query->new_block(sizeof(CSecurityFtdcQryInvestorField)); -// -// strncpy(pBody->BrokerID, m_RspUserLogin.BrokerID, sizeof(TSecurityFtdcBrokerIDType)); -// strncpy(pBody->InvestorID, m_RspUserLogin.UserID, sizeof(TSecurityFtdcInvestorIDType)); -// -// m_msgQueue_Query->Input_NoCopy(RequestType::E_QryInvestorField, m_msgQueue_Query, this, 0, 0, -// pBody, sizeof(CSecurityFtdcQryInvestorField), nullptr, 0, nullptr, 0); -//} -// -//int CTraderApi::_ReqQryInvestor(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3) -//{ -// return m_pApi->ReqQryInvestor((CSecurityFtdcQryInvestorField*)ptr1, ++m_lRequestID); -//} -// -//void CTraderApi::OnRspQryInvestor(CSecurityFtdcInvestorField *pInvestor, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) -//{ -// if (!IsErrorRspInfo(pRspInfo, nRequestID, bIsLast)) -// { -// if (pInvestor) -// { -// memcpy(&m_Investor, pInvestor, sizeof(CSecurityFtdcInvestorField)); -// -// InvestorField* pField = (InvestorField*)m_msgQueue->new_block(sizeof(InvestorField)); -// -// strcpy(pField->BrokerID, pInvestor->BrokerID); -// strcpy(pField->InvestorID, pInvestor->InvestorID); -// strcpy(pField->InvestorName, pInvestor->InvestorName); -// strcpy(pField->IdentifiedCardNo, pInvestor->IdentifiedCardNo); -// pField->IdentifiedCardType = TSecurityFtdcIdCardTypeType_2_IdCardType(pInvestor->IdentifiedCardType); -// -// m_msgQueue->Input_NoCopy(ResponeType::OnRspQryInvestor, m_msgQueue, m_pClass, bIsLast, 0, pField, sizeof(InvestorField), nullptr, 0, nullptr, 0); -// } -// else -// { -// m_msgQueue->Input_NoCopy(ResponeType::OnRspQryInvestor, m_msgQueue, m_pClass, bIsLast, 0, nullptr, 0, nullptr, 0, nullptr, 0); -// } -// } -//} +} \ No newline at end of file diff --git a/QuantBox_LTS_Trade_v2/TraderApi.h b/QuantBox_LTS_Trade_v2/TraderApi.h index 4a5f77e..1b64f01 100644 --- a/QuantBox_LTS_Trade_v2/TraderApi.h +++ b/QuantBox_LTS_Trade_v2/TraderApi.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once #include "../include/LTS_v2/SecurityFtdcTraderApi.h" #include "../include/ApiStruct.h" @@ -27,7 +27,7 @@ class CMsgQueue; class CTraderApi : public CSecurityFtdcTraderSpi { - //ݰ + //请求数据包类型 enum RequestType { E_Init, @@ -52,6 +52,8 @@ class CTraderApi : E_QrySettlementInfoField, E_QryOrderField, E_QryTradeField, + + E_AuthRandCodeField, }; public: @@ -85,15 +87,15 @@ class CTraderApi : //void ReqQryInvestorPosition(const string& szInstrumentId, const string& szExchange); //void ReqQryInvestorPositionDetail(const string& szInstrumentId); //void ReqQryInstrument(const string& szInstrumentId, const string& szExchange); - void ReqQryInstrumentCommissionRate(const string& szInstrumentId); - void ReqQryInstrumentMarginRate(const string& szInstrumentId, TSecurityFtdcHedgeFlagType HedgeFlag = SECURITY_FTDC_HF_Speculation); - void ReqQryDepthMarketData(const string& szInstrumentId); - void ReqQrySettlementInfo(const string& szTradingDay); + //void ReqQryInstrumentCommissionRate(const string& szInstrumentId); + //void ReqQryInstrumentMarginRate(const string& szInstrumentId, TSecurityFtdcHedgeFlagType HedgeFlag = SECURITY_FTDC_HF_Speculation); + //void ReqQryDepthMarketData(const string& szInstrumentId); + //void ReqQrySettlementInfo(const string& szTradingDay); //void ReqQryOrder(); //void ReqQryTrade(); - void ReqQryInvestor(); + //void ReqQryInvestor(); private: friend void* __stdcall Query(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3); @@ -103,9 +105,12 @@ class CTraderApi : int _Init(); - void ReqUserLogin(); + void ReqUserLogin(TSecurityFtdcAuthCodeType RandCode); int _ReqUserLogin(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3); + void ReqFetchAuthRandCode(); + int _ReqFetchAuthRandCode(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3); + //int _ReqQryInstrument(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3); //int _ReqQryTradingAccount(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3); //int _ReqQryInvestorPosition(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3); @@ -119,83 +124,83 @@ class CTraderApi : void OnTrade(CSecurityFtdcTradeField *pTrade, bool bFromQry); void OnTrade(TradeField *pTrade, bool bFromQry); - //Ƿ - bool IsErrorRspInfo(CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast);//ϢϢ - bool IsErrorRspInfo(CSecurityFtdcRspInfoField *pRspInfo);//Ϣ + //检查是否出错 + bool IsErrorRspInfo(const char* szSource, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast);//向消息队列输出信息 + bool IsErrorRspInfo(CSecurityFtdcRspInfoField *pRspInfo);//不输出信息 - // + //连接 virtual void OnFrontConnected(); virtual void OnFrontDisconnected(int nReason); - //֤ - //virtual void OnRspAuthenticate(CSecurityFtdcRspAuthenticateField *pRspAuthenticateField, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); + //认证 + virtual void OnRspFetchAuthRandCode(CSecurityFtdcAuthRandCodeField *pAuthRandCode, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); virtual void OnRspUserLogin(CSecurityFtdcRspUserLoginField *pRspUserLogin, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); //virtual void OnRspSettlementInfoConfirm(CSecurityFtdcSettlementInfoConfirmField *pSettlementInfoConfirm, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); //virtual void OnRspQryInvestor(CSecurityFtdcInvestorField *pInvestor, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); - //µ + //下单 virtual void OnRspOrderInsert(CSecurityFtdcInputOrderField *pInputOrder, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); virtual void OnErrRtnOrderInsert(CSecurityFtdcInputOrderField *pInputOrder, CSecurityFtdcRspInfoField *pRspInfo); - // + //撤单 virtual void OnRspOrderAction(CSecurityFtdcInputOrderActionField *pInputOrderAction, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); virtual void OnErrRtnOrderAction(CSecurityFtdcOrderActionField *pOrderAction, CSecurityFtdcRspInfoField *pRspInfo); - //ر + //报单回报 //virtual void OnRspQryOrder(CSecurityFtdcOrderField *pOrder, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); virtual void OnRtnOrder(CSecurityFtdcOrderField *pOrder); - //ɽر + //成交回报 //virtual void OnRspQryTrade(CSecurityFtdcTradeField *pTrade, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); virtual void OnRtnTrade(CSecurityFtdcTradeField *pTrade); - //¼ + //报价录入 //virtual void OnRspQuoteInsert(CSecurityFtdcInputQuoteField *pInputQuote, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); //virtual void OnErrRtnQuoteInsert(CSecurityFtdcInputQuoteField *pInputQuote, CSecurityFtdcRspInfoField *pRspInfo); //virtual void OnRtnQuote(CSecurityFtdcQuoteField *pQuote); - //۳ + //报价撤单 //virtual void OnRspQuoteAction(CSecurityFtdcInputQuoteActionField *pInputQuoteAction, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); //virtual void OnErrRtnQuoteAction(CSecurityFtdcQuoteActionField *pQuoteAction, CSecurityFtdcRspInfoField *pRspInfo); - //λ + //仓位 //virtual void OnRspQryInvestorPosition(CSecurityFtdcInvestorPositionField *pInvestorPosition, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); //virtual void OnRspQryInvestorPositionDetail(CSecurityFtdcInvestorPositionDetailField *pInvestorPositionDetail, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); //virtual void OnRspQryInvestorPositionCombineDetail(CSecurityFtdcInvestorPositionCombineDetailField *pInvestorPositionCombineDetail, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; - //ʽ + //资金 //virtual void OnRspQryTradingAccount(CSecurityFtdcTradingAccountField *pTradingAccount, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); - //Լ + //合约、手续费 //virtual void OnRspQryInstrument(CSecurityFtdcInstrumentField *pInstrument, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); //virtual void OnRspQryInstrumentMarginRate(CSecurityFtdcInstrumentMarginRateField *pInstrumentMarginRate, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); //virtual void OnRspQryInstrumentCommissionRate(CSecurityFtdcInstrumentCommissionRateField *pInstrumentCommissionRate, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); - //ѯӦ + //查询行情响应 //virtual void OnRspQryDepthMarketData(CSecurityFtdcDepthMarketDataField *pDepthMarketData, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); - //ѯͶ߽Ӧ + //请求查询投资者结算结果响应 //virtual void OnRspQrySettlementInfo(CSecurityFtdcSettlementInfoField *pSettlementInfo, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); - // + //其它 virtual void OnRspError(CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); //virtual void OnRtnInstrumentStatus(CSecurityFtdcInstrumentStatusField *pInstrumentStatus); private: - atomic m_lRequestID; //ID,ñ + atomic m_lRequestID; //请求ID,得保持自增 - CSecurityFtdcRspUserLoginField m_RspUserLogin; //صĵ¼ɹӦĿǰôڳԱб + CSecurityFtdcRspUserLoginField m_RspUserLogin; //返回的登录成功响应,目前利用此内成员进行报单所属区分 CSecurityFtdcInvestorField m_Investor; OrderIDType m_orderInsert_Id; OrderIDType m_orderAction_Id; mutex m_csOrderRef; - int m_nMaxOrderRef; //ãֱ + int m_nMaxOrderRef; //报单引用,用于区分报单,保持自增 - CSecurityFtdcTraderApi* m_pApi; //API + CSecurityFtdcTraderApi* m_pApi; //交易API - string m_szPath; //ļ· + string m_szPath; //生成配置文件的路径 ServerInfoField m_ServerInfo; UserInfoField m_UserInfo; int m_nSleep; @@ -206,7 +211,7 @@ class CTraderApi : unordered_map m_id_platform_position; - CMsgQueue* m_msgQueue; //Ϣָ + CMsgQueue* m_msgQueue; //消息队列指针 CMsgQueue* m_msgQueue_Query; void* m_pClass; }; diff --git a/QuantBox_LTS_Trade_v2/TypeConvert.cpp b/QuantBox_LTS_Trade_v2/TypeConvert.cpp index baf6754..a8eb917 100644 --- a/QuantBox_LTS_Trade_v2/TypeConvert.cpp +++ b/QuantBox_LTS_Trade_v2/TypeConvert.cpp @@ -147,7 +147,7 @@ OrderStatus CSecurityFtdcOrderField_2_OrderStatus(CSecurityFtdcOrderField* pIn) if (pIn->OrderSubmitStatus == SECURITY_FTDC_OSS_InsertSubmitted) return OrderStatus::New; default: - if (pIn->VolumeTotal == 0) + if (0 == pIn->VolumeTotal) return OrderStatus::Filled; else if (pIn->VolumeTotal == pIn->VolumeTotalOriginal) return OrderStatus::New; @@ -314,7 +314,7 @@ ExchangeType TSecurityFtdcExchangeIDType_2_ExchangeType(TSecurityFtdcExchangeIDT case 'S': return ExchangeType::SSE; case 'Z': - return ExchangeType::SZE; + return ExchangeType::SZSE; default: return ExchangeType::Undefined_; } diff --git a/QuantBox_LTS_Trade_v2/TypeConvert.h b/QuantBox_LTS_Trade_v2/TypeConvert.h index c491293..107efaa 100644 --- a/QuantBox_LTS_Trade_v2/TypeConvert.h +++ b/QuantBox_LTS_Trade_v2/TypeConvert.h @@ -1,7 +1,7 @@ #pragma once -#include "../include/LTS/SecurityFtdcUserApiDataType.h" -#include "../include/LTS/SecurityFtdcUserApiStruct.h" +#include "../include/LTS_v2/SecurityFtdcUserApiDataType.h" +#include "../include/LTS_v2/SecurityFtdcUserApiStruct.h" #include "../include/ApiStruct.h" diff --git a/QuantBox_LTS_Trade_v2/main.cpp b/QuantBox_LTS_Trade_v2/main.cpp index 004dac6..3771e44 100644 --- a/QuantBox_LTS_Trade_v2/main.cpp +++ b/QuantBox_LTS_Trade_v2/main.cpp @@ -14,11 +14,11 @@ void* __stdcall XRequest(char type, void* pApi1, void* pApi2, double double1, do switch (rt) { case GetApiType: - return (void*)(ApiType::Trade | ApiType::Instrument); + return (void*)(ApiType::Trade); case GetApiVersion: - return (void*)"0.3.0.20150407"; + return (void*)"0.2.0.20151116"; case GetApiName: - return (void*)"LTS"; + return (void*)"LTS2"; case Create: return new CTraderApi(); default: diff --git a/QuantBox_Queue/QuantBox_Queue.vcxproj b/QuantBox_Queue/QuantBox_Queue.vcxproj index b497faf..438eca1 100644 --- a/QuantBox_Queue/QuantBox_Queue.vcxproj +++ b/QuantBox_Queue/QuantBox_Queue.vcxproj @@ -95,7 +95,7 @@ true QuantBox_Queue_x86 - C:\Program Files\SmartQuant Ltd\OpenQuant 2014\XAPI\LTS\x86 + C:\Program Files\SmartQuant Ltd\OpenQuant 2014\XAPI\Tdx\x86 true diff --git a/QuantBox_Tdx_Trade/QuantBox_Tdx_Trade.vcxproj b/QuantBox_Tdx_Trade/QuantBox_Tdx_Trade.vcxproj new file mode 100644 index 0000000..0ce01f5 --- /dev/null +++ b/QuantBox_Tdx_Trade/QuantBox_Tdx_Trade.vcxproj @@ -0,0 +1,120 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {01D3F1DE-99B3-4D41-97C3-F4680CDB980B} + Win32Proj + QuantBox_Tdx_Trade + + + + DynamicLibrary + true + v120 + Unicode + + + DynamicLibrary + false + v120 + true + Unicode + + + + + + + + + + + + + true + C:\Program Files\SmartQuant Ltd\OpenQuant 2014\XAPI\Tdx\x86 + + + false + + + + Use + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;QUANTBOX_TDX_TRADE_EXPORTS;BUILDING_DLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + + + Windows + true + ..\include\ApiHeader.def + + + xcopy "$(TargetPath)" "$(SolutionDir)XAPI\Tdx\x86\" /Y +xcopy "$(SolutionDir)include\Tdx\win32\*.dll" "$(SolutionDir)XAPI\Tdx\x86\" /Y + + + + + Level3 + Use + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;QUANTBOX_TDX_TRADE_EXPORTS;%(PreprocessorDefinitions) + true + + + Windows + true + true + true + + + + + + + + + + + + + + + + + + + + + false + + + false + + + + + + Create + Create + + + + + + + + \ No newline at end of file diff --git a/QuantBox_Tdx_Trade/QuantBox_Tdx_Trade.vcxproj.filters b/QuantBox_Tdx_Trade/QuantBox_Tdx_Trade.vcxproj.filters new file mode 100644 index 0000000..c094e00 --- /dev/null +++ b/QuantBox_Tdx_Trade/QuantBox_Tdx_Trade.vcxproj.filters @@ -0,0 +1,72 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/QuantBox_Tdx_Trade/ReadMe.txt b/QuantBox_Tdx_Trade/ReadMe.txt new file mode 100644 index 0000000..f89d1b6 --- /dev/null +++ b/QuantBox_Tdx_Trade/ReadMe.txt @@ -0,0 +1,48 @@ +======================================================================== + DYNAMIC LINK LIBRARY : QuantBox_Tdx_Trade Project Overview +======================================================================== + +AppWizard has created this QuantBox_Tdx_Trade DLL for you. + +This file contains a summary of what you will find in each of the files that +make up your QuantBox_Tdx_Trade application. + + +QuantBox_Tdx_Trade.vcxproj + This is the main project file for VC++ projects generated using an Application Wizard. + It contains information about the version of Visual C++ that generated the file, and + information about the platforms, configurations, and project features selected with the + Application Wizard. + +QuantBox_Tdx_Trade.vcxproj.filters + This is the filters file for VC++ projects generated using an Application Wizard. + It contains information about the association between the files in your project + and the filters. This association is used in the IDE to show grouping of files with + similar extensions under a specific node (for e.g. ".cpp" files are associated with the + "Source Files" filter). + +QuantBox_Tdx_Trade.cpp + This is the main DLL source file. + + When created, this DLL does not export any symbols. As a result, it + will not produce a .lib file when it is built. If you wish this project + to be a project dependency of some other project, you will either need to + add code to export some symbols from the DLL so that an export library + will be produced, or you can set the Ignore Input Library property to Yes + on the General propert page of the Linker folder in the project's Property + Pages dialog box. + +///////////////////////////////////////////////////////////////////////////// +Other standard files: + +StdAfx.h, StdAfx.cpp + These files are used to build a precompiled header (PCH) file + named QuantBox_Tdx_Trade.pch and a precompiled types file named StdAfx.obj. + +///////////////////////////////////////////////////////////////////////////// +Other notes: + +AppWizard uses "TODO:" comments to indicate parts of the source code you +should add to or customize. + +///////////////////////////////////////////////////////////////////////////// diff --git a/QuantBox_Tdx_Trade/Struct.h b/QuantBox_Tdx_Trade/Struct.h new file mode 100644 index 0000000..4124838 --- /dev/null +++ b/QuantBox_Tdx_Trade/Struct.h @@ -0,0 +1,87 @@ +#pragma once + +/* +120_ͻ|134_|121_ʽʺ|125_ʺ|123_ɶ|110_ίзʽ|1207 +_ʼ|1227_|101_|5250_ͻȺ|5251_ͻӪҵ|5252_Ӳк +|5253_CPUID|5254_ýױʶ|5255_Ự|5256_ͻ| +=============== +143_ίʱ|123_ɶ|140_֤ȯ|141_֤ȯ|130_־|131_־|10 +0_|145_ίм۸|144_ί|153_ɽ۸|152_ɽ|162_|14 +6_ίб|194_۷ʽ|147_״̬˵|161_ʽ|1213_Ϣ| +*/ +//#define REQUEST_DRWT 1102 // ί + +/* +120_ͻ|134_|121_ʽʺ|125_ʺ|123_ɶ|110_ίзʽ|126_ +ʼ|127_ֹ|1207_ʼ|140_֤ȯ|1227_|5250_ͻȺ|5251_ +Ӫҵ|5252_Ӳк|5253_CPUID|5254_ýױʶ|5255_Ự|5256_ͻ| + +=============== +142_ί|123_ɶ|140_֤ȯ|141_֤ȯ|130_־|131_־|10 +0_|145_ίм۸|144_ί|153_ɽ۸|152_ɽ|162_|14 +6_ίб|194_۷ʽ|161_ʽ|1213_Ϣ| +*/ +//#define REQUEST_LSWT 1104 // ʷί + +struct WTLB_STRUCT +{ + int WTRQ; // 142_ί + int WTSJ; // 143_ίʱ + char GDDM[32]; // 123_ɶ + char ZQDM[32]; // 140_֤ȯ + char ZQMC[32]; // 141_֤ȯ + int MMBZ; // 130_־ + int WTLB; // 131_ί + int JYSDM; // 100_ + double WTJG; // 145_ίм۸ + int WTSL; // 144_ί + double CJJG; // 153_ɽ۸ + int CDSL; // 162_ + char WTBH[32]; // 146_ίб + int BJFS; // 194_۷ʽ + double DJZJ; // 161_ʽ +}; + + +/* +120_ͻ|134_|121_ʽʺ|125_ʺ|123_ɶ|110_ίзʽ|1207 +_ʼ|155_ɽ|101_|5250_ͻȺ|5251_ͻӪҵ|5252_Ӳ +к|5253_CPUID|5254_ýױʶ|5255_Ự|5256_ͻ| +=============== +151_ɽʱ|123_ɶ|140_֤ȯ|141_֤ȯ|130_־|131_־|15 +3_ɽ۸|152_ɽ|303_|155_ɽ|167_־|146_ίб|1213 +_Ϣ| +*/ +//#define REQUEST_DRCJ 1108 // ճɽ +/* +120_ͻ|134_|121_ʽʺ|125_ʺ|123_ɶ|110_ίзʽ|126_ +ʼ|127_ֹ|1207_ʼ|140_֤ȯ|101_|5250_ͻȺ|52 +51_ͻӪҵ|5252_Ӳк|5253_CPUID|5254_ýױʶ|5255_Ự|5256_ͻ +| +=============== +150_ɽ|151_ɽʱ|123_ɶ|140_֤ȯ|141_֤ȯ|130_־|13 +1_־|153_ɽ۸|152_ɽ|303_|304_ʣ|206_Ӷ|210_ӡ +˰|207_|208_ɽ|155_ɽ|146_ίб|1213_Ϣ| +*/ +//#define REQUEST_LSCJ 1110 // ʷɽ + +struct CJLB_STRUCT +{ + int CJRQ; // 150_ɽ + int CJSJ; // 151_ɽʱ + char GDDM[32]; // 123_ɶ + char ZQDM[32]; // 140_֤ȯ + char ZQMC[32]; // 141_֤ȯ + int MMBZ; // 130_־ + int WTLB; // 131_ί + double CJJG; // 153_ɽ۸ + int CJSL; // 152_ɽ + double FSJE; // 303_ + double SYJE; // 304_ʣ + double YJ; // 206_Ӷ + double YHS; // 210_ӡ˰ + double GHF; // 207_ + double CJF; // 208_ɽ + char CJBH[32]; // 155_ɽ + char WTBH[32]; // 146_ίб +}; \ No newline at end of file diff --git a/QuantBox_Tdx_Trade/TraderApi.cpp b/QuantBox_Tdx_Trade/TraderApi.cpp new file mode 100644 index 0000000..5331370 --- /dev/null +++ b/QuantBox_Tdx_Trade/TraderApi.cpp @@ -0,0 +1,1415 @@ +#include "stdafx.h" +#include "TraderApi.h" + +#include "../include/QueueEnum.h" +#include "../include/QueueHeader.h" + +#include "../include/ApiHeader.h" +#include "../include/ApiStruct.h" + +#include "../include/ApiProcess.h" +#include "../include/toolkit.h" + +#include "../QuantBox_Queue/MsgQueue.h" + +#include "TypeConvert.h" + +#include "../include/Tdx/tdx_function.h" + +#include +#include + + +void* __stdcall Query(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3) +{ + // 由内部调用,不用检查是否为空 + CTraderApi* pApi = (CTraderApi*)pApi2; + pApi->QueryInThread(type, pApi1, pApi2, double1, double2, ptr1, size1, ptr2, size2, ptr3, size3); + return nullptr; +} + +void CTraderApi::QueryInThread(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3) +{ + int iRet = 0; + switch (type) + { + case E_Init: + iRet = _Init(); + break; + case E_ReqUserLoginField: + iRet = _ReqUserLogin(type, pApi1, pApi2, double1, double2, ptr1, size1, ptr2, size2, ptr3, size3); + break; + case E_QryOrderField: + iRet = _ReqQryOrder(type, pApi1, pApi2, double1, double2, ptr1, size1, ptr2, size2, ptr3, size3); + break; + case E_QryTradeField: + iRet = _ReqQryTrade(type, pApi1, pApi2, double1, double2, ptr1, size1, ptr2, size2, ptr3, size3); + break; + case E_QryInvestorField: + iRet = _ReqQryInvestor(type, pApi1, pApi2, double1, double2, ptr1, size1, ptr2, size2, ptr3, size3); + break; + case E_InputOrderField: + iRet = _ReqOrderInsert(type, pApi1, pApi2, double1, double2, ptr1, size1, ptr2, size2, ptr3, size3); + break; + case E_InputOrderActionField: + iRet = _ReqOrderAction(type, pApi1, pApi2, double1, double2, ptr1, size1, ptr2, size2, ptr3, size3); + break; + case E_QryTradingAccountField: + iRet = _ReqQryTradingAccount(type, pApi1, pApi2, double1, double2, ptr1, size1, ptr2, size2, ptr3, size3); + break; + case E_QryInvestorPositionField: + iRet = _ReqQryInvestorPosition(type, pApi1, pApi2, double1, double2, ptr1, size1, ptr2, size2, ptr3, size3); + break; + case E_QryDepthMarketDataField: + iRet = _Subscribe(type, pApi1, pApi2, double1, double2, ptr1, size1, ptr2, size2, ptr3, size3); + break; + default: + break; + } + + if (0 == iRet) + { + //返回成功,填加到已发送池 + m_nSleep = 1; + } + else + { + m_msgQueue_Query->Input_Copy(type, pApi1, pApi2, double1, double2, ptr1, size1, ptr2, size2, ptr3, size3); + //失败,按4的幂进行延时,但不超过1s + m_nSleep *= 4; + m_nSleep %= 1023; + } + this_thread::sleep_for(chrono::milliseconds(m_nSleep)); +} + +void* __stdcall Test(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3) +{ + // 由内部调用,不用检查是否为空 + CTraderApi* pApi = (CTraderApi*)pApi2; + pApi->TestInThread(type, pApi1, pApi2, double1, double2, ptr1, size1, ptr2, size2, ptr3, size3); + return nullptr; +} + +void CTraderApi::TestInThread(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3) +{ + int iRet = 0; + bool bQryOrder = false; + bool bQryTrade = false; + //bool bQryInvestor = false; + + time_t _now = time(nullptr); + + // 想在整点时查询一下,因为整点时交易所和柜台变状态的可能性比较大这样 + + if (_now > m_QueryOrderTime) + { + bQryOrder = true; + } + else + { + + } + + if (_now > m_QueryTradeTime) + { + bQryTrade = true; + } + else + { + + } + + //if (_now > m_QueryGDLBTime) + //{ + // bQryInvestor = true; + //} + //else + //{ + + //} + + //if (bQryInvestor) + //{ + // double _queryTime = QUERY_TIME_MAX * 60; + // m_QueryGDLBTime = time(nullptr) + _queryTime; + // OutputQueryTime(m_QueryGDLBTime, _queryTime, "QueryInvestor"); + + // ReqQryInvestor(); + //} + + if (bQryOrder) + { + double _queryTime = QUERY_TIME_MAX; + m_QueryOrderTime = time(nullptr) + _queryTime; + OutputQueryTime(m_QueryOrderTime, _queryTime, "QueryOrder"); + + ReqQryOrder(); + } + + if (bQryTrade) + { + double _queryTime = QUERY_TIME_MAX; + m_QueryTradeTime = time(nullptr) + _queryTime; + OutputQueryTime(m_QueryTradeTime, _queryTime, "QueryTrade"); + + ReqQryTrade(); + } + + this_thread::sleep_for(chrono::milliseconds(1000)); + m_msgQueue_Test->Input_Copy(type, pApi1, pApi2, double1, double2, ptr1, size1, ptr2, size2, ptr3, size3); +} + +void CTraderApi::OutputQueryTime(time_t t, double db, const char* szSource) +{ + ErrorField* pField = (ErrorField*)m_msgQueue->new_block(sizeof(ErrorField)); + + pField->ErrorID = 0; + sprintf(pField->ErrorMsg, "Add:%d,Time:%s", (int)db, ctime(&t)); + strcpy(pField->Source, szSource); + + // 去了最后的回车 + int len = strlen(pField->ErrorMsg); + pField->ErrorMsg[len - 1] = 0; + + + m_msgQueue->Input_NoCopy(ResponeType::OnRtnError, m_msgQueue, m_pClass, true, 0, pField, sizeof(ErrorField), nullptr, 0, nullptr, 0); +} + + +int CTraderApi::_Init() +{ + if (m_pApi == nullptr) + { + m_pApi = CTdxApi::CreateApi(m_ServerInfo.ExtendInformation); + } + + Error_STRUCT* pErr = nullptr; + + m_pApi->LoadScript(m_ServerInfo.Address, true, false); + m_pApi->Init(m_ServerInfo.ExtendInformation, &pErr); + + if (pErr) + { + RspUserLoginField* pField = (RspUserLoginField*)m_msgQueue->new_block(sizeof(RspUserLoginField)); + + pField->ErrorID = pErr->ErrCode; + strcpy(pField->ErrorMsg, pErr->ErrInfo); + + m_msgQueue->Input_NoCopy(ResponeType::OnConnectionStatus, m_msgQueue, m_pClass, ConnectionStatus::Disconnected, 0, pField, sizeof(RspUserLoginField), nullptr, 0, nullptr, 0); + } + else + { + m_msgQueue->Input_NoCopy(ResponeType::OnConnectionStatus, m_msgQueue, m_pClass, ConnectionStatus::Initialized, 0, nullptr, 0, nullptr, 0, nullptr, 0); + + ReqUserLogin(); + } + + DeleteError(pErr); + + return 0; +} + +void CTraderApi::ReqUserLogin() +{ + if (m_UserInfo_Pos >= m_UserInfo_Count) + return; + + //STTraderLogin* pBody = (STTraderLogin*)m_msgQueue_Query->new_block(sizeof(STTraderLogin)); + + //strncpy(pBody->cust_no, m_pUserInfos[m_UserInfo_Pos].UserID, sizeof(TCustNoType)); + //strncpy(pBody->cust_pwd, m_pUserInfos[m_UserInfo_Pos].Password, sizeof(TCustPwdType)); + + m_msgQueue_Query->Input_NoCopy(RequestType::E_ReqUserLoginField, m_msgQueue_Query, this, 0, 0, + nullptr, 0, nullptr, 0, nullptr, 0); +} + +int CTraderApi::_ReqUserLogin(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3) +{ + char** ppResults = nullptr; + Error_STRUCT* pErr = nullptr; + + m_msgQueue->Input_NoCopy(ResponeType::OnConnectionStatus, m_msgQueue, m_pClass, ConnectionStatus::Logining, 0, nullptr, 0, nullptr, 0, nullptr, 0); + + m_pClient = m_pApi->Login(m_UserInfo.UserID, m_UserInfo.Password, m_UserInfo.ExtInfo, &ppResults, &pErr); + + if (m_pClient) + { + // 有授权信息要输出 + RspUserLoginField* pField = (RspUserLoginField*)m_msgQueue->new_block(sizeof(RspUserLoginField)); + if (pErr) + { + pField->ErrorID = pErr->ErrCode; + strcpy(pField->ErrorMsg, pErr->ErrInfo); + } + + m_msgQueue->Input_NoCopy(ResponeType::OnConnectionStatus, m_msgQueue, m_pClass, ConnectionStatus::Logined, 0, pField, sizeof(pField), nullptr, 0, nullptr, 0); + + // 以后支持多账号时这地方要改 + m_pApi->SetClient(m_pClient); + m_pApi->SetAccount(m_UserInfo.UserID); + + // 查询股东列表,华泰证券可能一开始查会返回非知请求[1122] + GDLB_STRUCT** ppRS = nullptr; + CharTable2Login(ppResults, &ppRS); + + int count = GetCountStructs((void**)ppRS); + + if (count>0) + { + for (int i = 0; i < count; ++i) + { + InvestorField* pField = (InvestorField*)m_msgQueue->new_block(sizeof(InvestorField)); + + GDLB_2_InvestorField(ppRS[i], pField); + + m_msgQueue->Input_NoCopy(ResponeType::OnRspQryInvestor, m_msgQueue, m_pClass, i == count - 1, 0, pField, sizeof(InvestorField), nullptr, 0, nullptr, 0); + } + } + else + { + // 查通达信仿真实验室账号不直接返回股东列表,需要主动查询 + ReqQryInvestor(); + } + + // 启动定时查询功能使用 + m_msgQueue_Test->Input_Copy(ResponeType::OnRtnOrder, m_msgQueue_Test, this, 0, 0, nullptr, 0, nullptr, 0, nullptr, 0); + + m_msgQueue->Input_NoCopy(ResponeType::OnConnectionStatus, m_msgQueue, m_pClass, ConnectionStatus::Done, 0, nullptr, 0, nullptr, 0, nullptr, 0); + + + // 登录下一个账号 + //++m_UserInfo_Pos; + //ReqUserLogin(); + } + else + { + if (pErr) + { + RspUserLoginField* pField = (RspUserLoginField*)m_msgQueue->new_block(sizeof(RspUserLoginField)); + + pField->ErrorID = pErr->ErrCode; + strcpy(pField->ErrorMsg, pErr->ErrInfo); + + m_msgQueue->Input_NoCopy(ResponeType::OnConnectionStatus, m_msgQueue, m_pClass, ConnectionStatus::Disconnected, 0, pField, sizeof(RspUserLoginField), nullptr, 0, nullptr, 0); + } + } + + DeleteError(pErr); + DeleteTableBody(ppResults); + + return 0; +} + +void CTraderApi::ReqQryInvestor() +{ + m_msgQueue_Query->Input_NoCopy(RequestType::E_QryInvestorField, m_msgQueue_Query, this, 0, 0, + nullptr, 0, nullptr, 0, nullptr, 0); +} + +int CTraderApi::_ReqQryInvestor(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3) +{ + if (m_pApi == nullptr) + return 0; + + FieldInfo_STRUCT** ppFieldInfos = nullptr; + char** ppResults = nullptr; + Error_STRUCT* pErr = nullptr; + + m_pApi->ReqQueryData(REQUEST_GDLB, &ppFieldInfos, &ppResults, &pErr); + + if (IsErrorRspInfo("ReqQryInvestor", pErr)) + { + //int _queryTime = QUERY_TIME_MIN; + //m_QueryGDLBTime = time(nullptr) + _queryTime; + //OutputQueryTime(m_QueryGDLBTime, _queryTime, "NextQueryInvestor_ReqQryInvestor"); + + DeleteTableBody(ppResults); + DeleteError(pErr); + + return 0; + } + + GDLB_STRUCT** ppRS = nullptr; + CharTable2GDLB(ppFieldInfos, ppResults, &ppRS); + + int count = GetCountStructs((void**)ppRS); + + for (int i = 0; i < count; ++i) + { + InvestorField* pField = (InvestorField*)m_msgQueue->new_block(sizeof(InvestorField)); + + GDLB_2_InvestorField(ppRS[i], pField); + + m_msgQueue->Input_NoCopy(ResponeType::OnRspQryInvestor, m_msgQueue, m_pClass, i == count - 1, 0, pField, sizeof(InvestorField), nullptr, 0, nullptr, 0); + } + + DeleteTableBody(ppResults); + DeleteError(pErr); + + return 0; +} + +CTraderApi::CTraderApi(void) +{ + m_pIDGenerator = nullptr; + m_pApi = nullptr; + m_pClient = nullptr; + m_lRequestID = 0; + m_nSleep = 1; + //m_FirstTradeID[0] = 0; + m_TradeListReverse = false; + m_LastIsMerge = false; + + // 自己维护两个消息队列 + m_msgQueue = new CMsgQueue(); + m_msgQueue_Query = new CMsgQueue(); + m_msgQueue_Test = new CMsgQueue(); + + m_msgQueue_Query->Register(Query,this); + m_msgQueue_Query->StartThread(); + + m_msgQueue_Test->Register(Test, this); + m_msgQueue_Test->StartThread(); +} + + +CTraderApi::~CTraderApi(void) +{ + Disconnect(); +} + +void CTraderApi::Register(void* pCallback, void* pClass) +{ + m_pClass = pClass; + if (m_msgQueue == nullptr) + return; + + m_msgQueue_Query->Register(Query,this); + m_msgQueue_Test->Register(Test, this); + m_msgQueue->Register(pCallback,this); + if (pCallback) + { + m_msgQueue_Query->StartThread(); + m_msgQueue->StartThread(); + m_msgQueue_Test->StartThread(); + } + else + { + m_msgQueue_Query->StopThread(); + m_msgQueue->StopThread(); + m_msgQueue_Test->StopThread(); + } +} + +bool CTraderApi::IsErrorRspInfo(const char* szSource, Error_STRUCT *pRspInfo) +{ + bool bRet = ((pRspInfo) && (pRspInfo->ErrType != 0)); + if (bRet) + { + ErrorField* pField = (ErrorField*)m_msgQueue->new_block(sizeof(ErrorField)); + + pField->ErrorID = pRspInfo->ErrCode; + strcpy(pField->ErrorMsg, pRspInfo->ErrInfo); + strcpy(pField->Source, szSource); + + m_msgQueue->Input_NoCopy(ResponeType::OnRtnError, m_msgQueue, m_pClass, true, 0, pField, sizeof(ErrorField), nullptr, 0, nullptr, 0); + } + return bRet; +} + +void CTraderApi::Connect(const string& szPath, + ServerInfoField* pServerInfo, + UserInfoField* pUserInfo, + int count) +{ + m_szPath = szPath; + memcpy(&m_ServerInfo, pServerInfo, sizeof(ServerInfoField)); + memcpy(&m_UserInfo, pUserInfo, sizeof(UserInfoField)); + + m_pUserInfos = (UserInfoField*)(new char[sizeof(UserInfoField)*count]); + memcpy(m_pUserInfos, pUserInfo, sizeof(UserInfoField)*count); + + m_UserInfo_Pos = 0; + m_UserInfo_Count = count; + + m_pIDGenerator = new CIDGenerator(); + m_pIDGenerator->SetPrefix(m_UserInfo.UserID); + + m_msgQueue_Query->Input_NoCopy(E_Init, m_msgQueue_Query, this, 0, 0, nullptr, 0, nullptr, 0, nullptr, 0); +} + +void CTraderApi::Disconnect() +{ + if (m_msgQueue_Query) + { + m_msgQueue_Query->StopThread(); + m_msgQueue_Query->Register(nullptr,nullptr); + m_msgQueue_Query->Clear(); + delete m_msgQueue_Query; + m_msgQueue_Query = nullptr; + } + + if (m_msgQueue_Test) + { + m_msgQueue_Test->StopThread(); + m_msgQueue_Test->Register(nullptr, nullptr); + m_msgQueue_Test->Clear(); + delete m_msgQueue_Test; + m_msgQueue_Test = nullptr; + } + + if(m_pApi) + { + // 还没有登出 + m_pApi->Logout(m_pClient); + m_pClient = nullptr; + m_pApi->Exit(); + + m_pApi->Release(); + m_pApi = nullptr; + + // 全清理,只留最后一个 + if (m_msgQueue) + { + m_msgQueue->Clear(); + m_msgQueue->Input_NoCopy(ResponeType::OnConnectionStatus, m_msgQueue, m_pClass, ConnectionStatus::Disconnected, 0, nullptr, 0, nullptr, 0, nullptr, 0); + // 主动触发 + m_msgQueue->Process(); + } + } + + if (m_msgQueue) + { + m_msgQueue->StopThread(); + m_msgQueue->Register(nullptr,nullptr); + m_msgQueue->Clear(); + delete m_msgQueue; + m_msgQueue = nullptr; + } + + if (m_pIDGenerator) + { + delete m_pIDGenerator; + m_pIDGenerator = nullptr; + } +} + +int CTraderApi::ReqOrderInsert( + OrderField* pOrder, + int count, + OrderIDType* pInOut) +{ + memset(pInOut, 0, sizeof(OrderIDType)*count); + + if (count < 1) + return 0; + + OrderField** ppOrders = new OrderField*[count]; + + // 生成本地ID,供上层进行定位使用 + for (int i = 0; i < count; ++i) + { + OrderField* pNewOrder = (OrderField*)m_msgQueue->new_block(sizeof(OrderField)); + memcpy(pNewOrder, pOrder, sizeof(OrderField)); + + strcpy(pInOut[i], m_pIDGenerator->GetIDString()); + strcpy(pNewOrder[i].LocalID, pInOut[i]); + ppOrders[i] = pNewOrder; + + // 注意这里保存了最开始发单的结构体的备份 + m_id_platform_order.insert(pair(pNewOrder->LocalID, pNewOrder)); + } + + m_msgQueue_Query->Input_Copy(RequestType::E_InputOrderField, m_msgQueue_Query, this, 0, 0, + ppOrders, sizeof(OrderField*)*count, nullptr, 0, nullptr, 0); + + delete[] ppOrders; + + return 0; +} + +int CTraderApi::_ReqOrderInsert(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3) +{ + if (m_pApi == nullptr) + return 0; + + // 得到报单指针列表 + OrderField** ppOrders = (OrderField**)ptr1; + int count = (int)size1 / sizeof(OrderField*); + + Order_STRUCT** ppTdxOrders = new Order_STRUCT*[count]; + for (int i = 0; i < count; ++i) + { + ppTdxOrders[i] = (Order_STRUCT*)m_msgQueue->new_block(sizeof(Order_STRUCT)); + OrderField_2_Order_STRUCT(ppOrders[i], ppTdxOrders[i]); + } + + FieldInfo_STRUCT** ppFieldInfos = nullptr; + char** ppResults = nullptr; + Error_STRUCT** ppErrs = nullptr; + + // 注意:pTdxOrders在这里被修改了,需要使用修改后的东西 + int n = m_pApi->SendMultiOrders(ppTdxOrders, count, &ppFieldInfos, &ppResults, &ppErrs); + + // 标记批量下单是否有发成功过单的 + bool bSuccess = false; + // 将结果立即取出来 + for (int i = 0; i < count;++i) + { + m_id_api_order.insert(pair(ppOrders[i]->LocalID, ppTdxOrders[i])); + // 处理错误 + if (ppErrs && ppErrs[i]) + { + ppOrders[i]->ErrorID = ppErrs[i]->ErrCode; + strcpy(ppOrders[i]->Text, ppErrs[i]->ErrInfo); + } + + // 处理结果 + if (ppResults && ppResults[i*COL_EACH_ROW + 0]) + { + bSuccess = true; + // 写上柜台的ID,以后将基于此进行定位 + strcpy(ppOrders[i]->ID, ppResults[i*COL_EACH_ROW + 0]); + + m_id_api_order.erase(ppOrders[i]->LocalID); + m_id_api_order.insert(pair(ppOrders[i]->ID, ppTdxOrders[i])); + + m_id_platform_order.erase(ppOrders[i]->LocalID); + m_id_platform_order.insert(pair(ppOrders[i]->ID, ppOrders[i])); + } + + // 现在有两个结构体,需要进行操作了 + // 1.通知下单的结果 + // 2.记录下单 + + OrderField* pField = ppOrders[i]; + if (pField->ErrorID != 0) + { + pField->ExecType = ExecType::ExecRejected; + pField->Status = OrderStatus::Rejected; + } + else + { + pField->ExecType = ExecType::ExecNew; + pField->Status = OrderStatus::New; + } + + m_msgQueue->Input_Copy(ResponeType::OnRtnOrder, m_msgQueue, m_pClass, 0, 0, pField, sizeof(OrderField), nullptr, 0, nullptr, 0); + } + + // 测试用,不能写这,太快了,要等一下 + //ReqQryTrade(); + + // 复制完了,可以删了以前东西 + delete[] ppTdxOrders; + + DeleteTableBody(ppResults, count); + DeleteErrors(ppErrs, count); + + if (bSuccess) + { + // 有挂单的,需要进行查询了 + + double _queryTime = QUERY_TIME_MIN; + + m_QueryOrderTime = time(nullptr) + _queryTime; + OutputQueryTime(m_QueryOrderTime, _queryTime, "NextQueryOrder_Send"); + } + + return 0; +} + +int CTraderApi::ReqOrderAction(OrderIDType* szId, int count, OrderIDType* pOutput) +{ + memset(pOutput, 0, sizeof(OrderIDType)*count); + + OrderField** ppOrders = new OrderField*[count]; + Order_STRUCT** ppTdxOrders = new Order_STRUCT*[count]; + + for (int i = 0; i < count; ++i) + { + ppOrders[i] = nullptr; + ppTdxOrders[i] = nullptr; + + { + unordered_map::iterator it = m_id_platform_order.find(szId[i]); + if (it != m_id_platform_order.end()) + ppOrders[i] = it->second; + } + + { + unordered_map::iterator it = m_id_api_order.find(szId[i]); + if (it != m_id_api_order.end()) + ppTdxOrders[i] = it->second; + } + } + + m_msgQueue_Query->Input_Copy(RequestType::E_InputOrderActionField, m_msgQueue_Query, this, 0, 0, + ppOrders, sizeof(OrderField*)*count, ppTdxOrders, sizeof(Order_STRUCT*)*count, nullptr, 0); + + delete[] ppOrders; + delete[] ppTdxOrders; + + return 0; +} + +int CTraderApi::_ReqOrderAction(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3) +{ + int count = (int)size1 / sizeof(OrderField*); + // 通过ID找到原始结构,用于撤单 + // 通过ID找到通用结构,用于接收回报 + OrderField** ppOrders = (OrderField**)ptr1; + Order_STRUCT** ppTdxOrders = (Order_STRUCT**)ptr2; + + FieldInfo_STRUCT** ppFieldInfos = nullptr; + char** ppResults = nullptr; + Error_STRUCT** ppErrs = nullptr; + + int n = m_pApi->CancelMultiOrders(ppTdxOrders, count, &ppFieldInfos, &ppResults, &ppErrs); + + bool bSuccess = false; + // 将结果立即取出来 + for (int i = 0; i < count; ++i) + { + if (ppErrs) + { + if (ppErrs[i]) + { + ppOrders[i]->ErrorID = ppErrs[i]->ErrCode; + strcpy(ppOrders[i]->Text, ppErrs[i]->ErrInfo); + + ppOrders[i]->ExecType = ExecType::ExecCancelReject; + // 注意报单状态问题 + } + else + { + bSuccess = true; + + // 会不会出现撤单时,当时不知道是否成功撤单,查询才得知没有撤成功? + //ppOrders[i]->ExecType = ExecType::ExecCancelled; + //ppOrders[i]->Status = OrderStatus::Cancelled; + continue; + } + } + // 撤单成功时,返回的东西还是null,所以这里使用错误信息来进行区分 + + //if (ppResults) + //{ + // if (ppResults[i*COL_EACH_ROW + 0]) + // { + // } + //} + + m_msgQueue->Input_Copy(ResponeType::OnRtnOrder, m_msgQueue, m_pClass, 0, 0, ppOrders[i], sizeof(OrderField), nullptr, 0, nullptr, 0); + } + + DeleteTableBody(ppResults, count); + DeleteErrors(ppErrs, count); + + if (bSuccess) + { + // 需要进行查询了 + double _queryTime = QUERY_TIME_MIN; + + m_QueryOrderTime = time(nullptr) + _queryTime; + OutputQueryTime(m_QueryOrderTime, _queryTime, "NextQueryOrder_Cancel"); + } + + return 0; +} + +void CTraderApi::ReqQryOrder() +{ + m_msgQueue_Query->Input_NoCopy(RequestType::E_QryOrderField, m_msgQueue_Query, this, 0, 0, + nullptr, 0, nullptr, 0, nullptr, 0); +} + +int CTraderApi::_ReqQryOrder(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3) +{ + FieldInfo_STRUCT** ppFieldInfos = nullptr; + char** ppResults = nullptr; + Error_STRUCT* pErr = nullptr; + + m_pApi->ReqQueryData(REQUEST_DRWT, &ppFieldInfos, &ppResults, &pErr); + // 测试用,事后要删除 + //m_pApi->ReqQueryData(REQUEST_LSWT, &ppFieldInfos, &ppResults, &pErr, "20150801", "20151031"); + + if (IsErrorRspInfo("ReqQryOrder", pErr)) + { + double _queryTime = 0.5 * QUERY_TIME_MAX + QUERY_TIME_MIN; + m_QueryOrderTime = time(nullptr) + _queryTime; + //OutputQueryTime(m_QueryOrderTime, _queryTime, "NextQueryOrder_QueryOrder_Error"); + + DeleteTableBody(ppResults); + DeleteError(pErr); + + return 0; + } + + WTLB_STRUCT** ppRS = nullptr; + CharTable2WTLB(ppFieldInfos, ppResults, &ppRS); + + // 操作前清空,按说之前已经清空过一次了 + m_NewOrderList.clear(); + + // 有未完成的,标记为true + bool IsDone = true; + // 有未申报的,标记为true + bool IsNotSent = false; + // 有更新的 + bool IsUpdated = false; + + if (ppRS) + { + int i = 0; + while (ppRS[i]) + { + // 将撤单委托过滤 + if (ppRS[i]->MMBZ_ != MMBZ_Cancel) + { + // 需要将它输入到一个地方用于计算 + OrderField* pField = (OrderField*)m_msgQueue->new_block(sizeof(OrderField)); + + WTLB_2_OrderField_0(ppRS[i], pField); + m_NewOrderList.push_back(pField); + + if (!ZTSM_IsDone(ppRS[i]->ZTSM_)) + { + IsDone = false; + } + if (ZTSM_IsNotSent(ppRS[i]->ZTSM_)) + { + IsNotSent = true; + } + } + ++i; + } + } + + // 委托列表 + // 1.新增的都需要输出 + // 2.老的看是否有变化 + ++m_OrderNotUpdateCount; + + int i = 0; + list::iterator it2 = m_OldOrderList.begin(); + for (list::iterator it = m_NewOrderList.begin(); it != m_NewOrderList.end(); ++it) + { + OrderField* pField = *it; + + bool bUpdate = false; + if (i >= m_OldOrderList.size()) + { + bUpdate = true; + } + else + { + // 相同位置的部分 + OrderField* pOldField = *it2; + if (pOldField->LeavesQty != pField->LeavesQty || pOldField->Status != pField->Status) + { + bUpdate = true; + } + } + + if (bUpdate) + { + IsUpdated = true; + m_OrderNotUpdateCount = 0; + + // 如果能找到下单时的委托,就修改后发出来 + unordered_map::iterator it = m_id_platform_order.find(pField->ID); + if (it != m_id_platform_order.end()) + { + OrderField* pField_ = it->second; + pField_->Date = pField->Date; + pField_->Time = pField->Time; + pField_->CumQty = pField->CumQty; + pField_->LeavesQty = pField->LeavesQty; + pField_->AvgPx = pField->AvgPx; + pField_->Status = pField->Status; + pField_->ExecType = pField->ExecType; + strcpy(pField_->Text, pField->Text); + + pField = pField_; + } + + m_msgQueue->Input_Copy(ResponeType::OnRtnOrder, m_msgQueue, m_pClass, 0, 0, pField, sizeof(OrderField), nullptr, 0, nullptr, 0); + } + + // 前一个可能为空,移动到下一个时需要注意 + if (it2 != m_OldOrderList.end()) + { + ++it2; + } + + ++i; + } + + // 将老数据清理,防止内存泄漏 + for (list::iterator it = m_OldOrderList.begin(); it != m_OldOrderList.end(); ++it) + { + OrderField* pField = *it; + m_msgQueue->delete_block(pField); + } + + // 做交换 + m_OldOrderList.clear(); + m_OldOrderList = m_NewOrderList; + m_NewOrderList.clear(); + + DeleteTableBody(ppResults); + DeleteError(pErr); + + double _queryTime = 0; + if (!IsDone) + { + if (!IsUpdated) + { + // 没有更新,是否要慢点查 + _queryTime = 0.5 * QUERY_TIME_MAX + QUERY_TIME_MIN; + } + + // 有没有完成的,需要定时查询 + if (IsNotSent) + { + // 有没申报的,是否没在交易时间?慢点查 + _queryTime = 0.5 * QUERY_TIME_MAX + QUERY_TIME_MIN; + } + else + { + // 可能是交易时间了,是否需要考虑 + _queryTime = 2 * QUERY_TIME_MIN; + // 可能有些挂单一天都不会成交,挂在这一直导致查太多,加一下查询计数 + if (m_OrderNotUpdateCount>=3) + { + _queryTime = 0.5 * QUERY_TIME_MAX + QUERY_TIME_MIN; + } + } + } + else + { + // 全完成了,可以不查或慢查 + _queryTime = 5 * QUERY_TIME_MAX; + } + + m_QueryOrderTime = time(nullptr) + _queryTime; + OutputQueryTime(m_QueryOrderTime, _queryTime, "NextQueryOrder_QueryOrder"); + + // 决定成交查询间隔 + if (IsUpdated) + { + // 委托可能是撤单,也有可能是成交了,赶紧查一下 + _queryTime = 0; + m_QueryTradeTime = time(nullptr) + _queryTime; + OutputQueryTime(m_QueryTradeTime, _queryTime, "NextQueryTrade_QueryOrder"); + } + else + { + // 委托没有变化,那成交就没有必要查那么快了 + _queryTime = 5 * QUERY_TIME_MAX; + m_QueryTradeTime = time(nullptr) + _queryTime; + OutputQueryTime(m_QueryTradeTime, _queryTime, "NextQueryTrade_QueryOrder"); + } + + + return 0; +} + +void CTraderApi::ReqQryTrade() +{ + m_msgQueue_Query->Input_NoCopy(RequestType::E_QryTradeField, m_msgQueue_Query, this, 0, 0, + nullptr, 0, nullptr, 0, nullptr, 0); +} + +////////////////////////////////////////////////////////////////////////// +double GetTradeListQty(list &tradeList,int count) +{ + double Qty = 0; + int i = 0; + for (list::iterator it = tradeList.begin(); it != tradeList.end(); ++it) + { + ++i; + if (i>count) + { + break; + } + + TradeField* pField = *it; + Qty += pField->Qty; + } + return Qty; +} + +void TradeList2TradeMap(list &tradeList, unordered_map &tradeMap) +{ + // 只在这个函数中new和delete应当没有问题 + for (unordered_map::iterator it = tradeMap.begin(); it != tradeMap.end(); ++it) + { + TradeField* pNewField = it->second; + delete[] pNewField; + } + tradeMap.clear(); + + // 将多个合约拼接成 + for (list::iterator it = tradeList.begin(); it != tradeList.end(); ++it) + { + TradeField* pField = *it; + unordered_map::iterator it2 = tradeMap.find(pField->ID); + if (it2 == tradeMap.end()) + { + TradeField* pNewField = new TradeField; + memcpy(pNewField, pField, sizeof(TradeField)); + tradeMap[pField->ID] = pNewField; + } + else + { + TradeField* pNewField = it2->second; + pNewField->Price = pField->Price; + pNewField->Qty += pField->Qty; + } + } +} + +void CTraderApi::CompareTradeMapAndEmit(unordered_map &oldMap, unordered_map &newMap) +{ + for (unordered_map::iterator it = newMap.begin(); it != newMap.end(); ++it) + { + TradeField* pNewField = it->second; + unordered_map::iterator it2 = oldMap.find(pNewField->ID); + if (it2 == oldMap.end()) + { + // 没找到,是新单 + m_msgQueue->Input_Copy(ResponeType::OnRtnTrade, m_msgQueue, m_pClass, 0, 0, pNewField, sizeof(TradeField), nullptr, 0, nullptr, 0); + } + else + { + TradeField* pOldField = it2->second; + int Qty = pNewField->Qty - pOldField->Qty; + if (Qty>0) + { + // 有变化的单 + TradeField* pField = new TradeField; + memcpy(pField, pNewField, sizeof(TradeField)); + pField->Qty = Qty; + m_msgQueue->Input_Copy(ResponeType::OnRtnTrade, m_msgQueue, m_pClass, 0, 0, pNewField, sizeof(TradeField), nullptr, 0, nullptr, 0); + delete[] pField; + } + } + } +} + +void CTraderApi::CompareTradeListAndEmit(list &oldList, list &newList) +{ + int i = 0; + list::iterator it2 = oldList.begin(); + for (list::iterator it = newList.begin(); it != newList.end(); ++it) + { + TradeField* pField = *it; + + bool bUpdate = false; + if (i >= oldList.size()) + { + bUpdate = true; + } + //else + //{ + // // 相同位置的部分 + // TradeField* pOldField = *it2; + // if (pOldField->Qty != pField->Qty) + // { + // bUpdate = true; + // } + //} + + if (bUpdate) + { + m_msgQueue->Input_Copy(ResponeType::OnRtnTrade, m_msgQueue, m_pClass, 0, 0, pField, sizeof(TradeField), nullptr, 0, nullptr, 0); + } + + // 前一个可能为空,移动到下一个时需要注意 + if (it2 != oldList.end()) + { + ++it2; + } + + ++i; + } +} +////////////////////////////////////////////////////////////////////////// + +int CTraderApi::_ReqQryTrade(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3) +{ + FieldInfo_STRUCT** ppFieldInfos = nullptr; + char** ppResults = nullptr; + Error_STRUCT* pErr = nullptr; + + m_pApi->ReqQueryData(REQUEST_DRCJ, &ppFieldInfos, &ppResults, &pErr); + + if (IsErrorRspInfo("ReqQryTrade", pErr)) + { + double _queryTime = 0.5 * QUERY_TIME_MAX + QUERY_TIME_MIN; + m_QueryTradeTime = time(nullptr) + _queryTime; + + DeleteTableBody(ppResults); + DeleteError(pErr); + + return 0; + } + + CJLB_STRUCT** ppRS = nullptr; + CharTable2CJLB(ppFieldInfos, ppResults, &ppRS); + + // 操作前清空,按说之前已经清空过一次了 + m_NewTradeList.clear(); + + if (ppRS) + { + // 利用成交编号的大小来判断正反序 + if (!m_TradeListReverse) + { + int count = GetCountStructs((void**)ppRS); + if (count>1) + { + // 转成数字的比较,是否会有非数字的情况出现? + long CJBH0 = atol(ppRS[0]->CJBH); + long CJBH1 = atol(ppRS[count - 1]->CJBH); + if (CJBH0>CJBH1) + { + m_TradeListReverse = true; + } + } + } + + int i = 0; + while (ppRS[i]) + { + TradeField* pField = (TradeField*)m_msgQueue->new_block(sizeof(TradeField)); + + CJLB_2_TradeField(ppRS[i], pField); + + if (m_TradeListReverse) + { + // 华泰查出来的表后生成的排第一,所以要处理一下 + m_NewTradeList.push_front(pField); + } + else + { + m_NewTradeList.push_back(pField); + } + + ++i; + } + } + + // 新查出来的反而少了,华泰有合并成交的情况,这种如何处理? + // 对同ID的需要累加,有发现累加不对应的,应当处理 + // 同样条数的,也有可能其中的有变化,如何处理? + bool bTryMerge = false; + int OldTradeListCount = m_OldTradeList.size(); + int NewTradeListCount = m_NewTradeList.size(); + + if (NewTradeListCount < OldTradeListCount) + { + // 行数变少了,应当是合并了 + bTryMerge = true; + } + else if (OldTradeListCount == 0) + { + // 如果上一次的为空,不管这次查出来的是合并还是没有合并,都没有关系,当成没合并处理即可 + } + else if (NewTradeListCount == OldTradeListCount) + { + // 行数不变,但有可能是其中的一条部分成交的更新,所以检查一下 + + double OldQty = GetTradeListQty(m_OldTradeList, m_OldTradeList.size()); + double NewQty = GetTradeListQty(m_NewTradeList, m_NewTradeList.size()); + if (NewQty != OldQty) + { + // 同样长度成交量发生了变化,可能是合并的列表其中一个新成交了 + bTryMerge = true; + } + } + else + { + // 行数变多了,只要其中上次的部分有变化就需要检查一下 + double OldQty = GetTradeListQty(m_OldTradeList, m_OldTradeList.size()); + double NewQty = GetTradeListQty(m_NewTradeList, m_NewTradeList.size()); + if (NewQty != OldQty) + { + bTryMerge = true; + } + } + + + + if (bTryMerge) + { + // 合并列表的处理方法 + // 如果上次是合并,这次就没有必要再生成一次了 + if (m_OldTradeMap.size() == 0 || !m_LastIsMerge) + { + for (unordered_map::iterator it = m_OldTradeMap.begin(); it != m_OldTradeMap.end(); ++it) + { + TradeField* pField = it->second; + delete[] pField; + } + m_OldTradeMap.clear(); + + TradeList2TradeMap(m_OldTradeList, m_OldTradeMap); + } + TradeList2TradeMap(m_NewTradeList, m_NewTradeMap); + CompareTradeMapAndEmit(m_OldTradeMap, m_NewTradeMap); + + // 交换 + for (unordered_map::iterator it = m_OldTradeMap.begin(); it != m_OldTradeMap.end(); ++it) + { + TradeField* pField = it->second; + delete[] pField; + } + m_OldTradeMap.clear(); + m_OldTradeMap = m_NewTradeMap; + m_NewTradeMap.clear(); + m_LastIsMerge = true; + } + else + { + // 普通的处理方法 + CompareTradeListAndEmit(m_OldTradeList, m_NewTradeList); + m_LastIsMerge = false; + } + + // 将老数据清理,防止内存泄漏 + for (list::iterator it = m_OldTradeList.begin(); it != m_OldTradeList.end(); ++it) + { + TradeField* pField = *it; + m_msgQueue->delete_block(pField); + } + + // 做交换 + m_OldTradeList.clear(); + m_OldTradeList = m_NewTradeList; + m_NewTradeList.clear(); + + DeleteTableBody(ppResults); + DeleteError(pErr); + + return 0; +} + +void CTraderApi::ReqQryInstrument(const string& szInstrumentId, const string& szExchange) +{ + +} + +void CTraderApi::ReqQryTradingAccount() +{ + m_msgQueue_Query->Input_NoCopy(RequestType::E_QryTradingAccountField, m_msgQueue_Query, this, 0, 0, + nullptr, 0, nullptr, 0, nullptr, 0); +} + +int CTraderApi::_ReqQryTradingAccount(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3) +{ + if (m_pApi == nullptr) + return 0; + + FieldInfo_STRUCT** ppFieldInfos = nullptr; + char** ppResults = nullptr; + Error_STRUCT* pErr = nullptr; + + m_pApi->ReqQueryData(REQUEST_ZJYE, &ppFieldInfos, &ppResults, &pErr); + + if (IsErrorRspInfo("ReqQryTradingAccount", pErr)) + { + DeleteTableBody(ppResults); + DeleteError(pErr); + + return 0; + } + + ZJYE_STRUCT** ppRS = nullptr; + CharTable2ZJYE(ppFieldInfos, ppResults, &ppRS); + + int count = GetCountStructs((void**)ppRS); + for (int i = 0; i < count; ++i) + { + AccountField* pField = (AccountField*)m_msgQueue->new_block(sizeof(AccountField)); + + ZJYE_2_AccountField(ppRS[i], pField); + + // 可能资金账号查不出来,手工填上 + if (strlen(pField->Account) <= 0) + { + // 多账户会有问题 + strcpy(pField->Account, m_pApi->GetAccount()); + } + + m_msgQueue->Input_NoCopy(ResponeType::OnRspQryTradingAccount, m_msgQueue, m_pClass, i == count - 1, 0, pField, sizeof(AccountField), nullptr, 0, nullptr, 0); + } + + DeleteTableBody(ppResults); + DeleteError(pErr); + + return 0; +} + +void CTraderApi::ReqQryInvestorPosition() +{ + m_msgQueue_Query->Input_NoCopy(RequestType::E_QryInvestorPositionField, m_msgQueue_Query, this, 0, 0, + nullptr, 0, nullptr, 0, nullptr, 0); +} + +int CTraderApi::_ReqQryInvestorPosition(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3) +{ + if (m_pApi == nullptr) + return 0; + + FieldInfo_STRUCT** ppFieldInfos = nullptr; + char** ppResults = nullptr; + Error_STRUCT* pErr = nullptr; + + m_pApi->ReqQueryData(REQUEST_GFLB, &ppFieldInfos, &ppResults, &pErr); + + if (IsErrorRspInfo("ReqQryInvestorPosition", pErr)) + { + DeleteTableBody(ppResults); + DeleteError(pErr); + + return 0; + } + + GFLB_STRUCT** ppRS = nullptr; + CharTable2GFLB(ppFieldInfos, ppResults, &ppRS); + + int count = GetCountStructs((void**)ppRS); + for (int i = 0; i < count; ++i) + { + PositionField* pField = (PositionField*)m_msgQueue->new_block(sizeof(PositionField)); + + // 应当处理一下,可能一个账号对应的有多个,如信用账户 + GFLB_2_PositionField(ppRS[i], pField); + + m_msgQueue->Input_NoCopy(ResponeType::OnRspQryInvestorPosition, m_msgQueue, m_pClass, i == count - 1, 0, pField, sizeof(PositionField), nullptr, 0, nullptr, 0); + } + + DeleteTableBody(ppResults); + DeleteError(pErr); + + return 0; +} + +void CTraderApi::Subscribe(const string& szInstrumentIDs, const string& szExchangeID) +{ + char buf[64] = { 0 }; + strcpy(buf, szInstrumentIDs.c_str()); + + m_msgQueue_Query->Input_Copy(RequestType::E_QryDepthMarketDataField, m_msgQueue_Query, this, 0, 0, + buf, sizeof(buf), nullptr, 0, nullptr, 0); +} + +int CTraderApi::_Subscribe(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3) +{ + if (m_pApi == nullptr) + return 0; + + FieldInfo_STRUCT** ppFieldInfos = nullptr; + char** ppResults = nullptr; + Error_STRUCT* pErr = nullptr; + + m_pApi->ReqQueryData(REQUEST_HQ, &ppFieldInfos, &ppResults, &pErr, "", "", (char*)ptr1); + + if (IsErrorRspInfo("Subscribe", pErr)) + { + DeleteTableBody(ppResults); + DeleteError(pErr); + + return 0; + } + + HQ_STRUCT** ppRS = nullptr; + CharTable2HQ(ppFieldInfos, ppResults, &ppRS); + + int count = GetCountStructs((void**)ppRS); + + for (int i = 0; i < count; ++i) + { + DepthMarketDataNField* pField = (DepthMarketDataNField*)m_msgQueue->new_block(sizeof(DepthMarketDataNField)+sizeof(DepthField)* 10); + + HQ_STRUCT* pDepthMarketData = ppRS[i]; + + strcpy(pField->InstrumentID, pDepthMarketData->ZQDM); + //pField->Exchange = JYSDM_2_ExchangeType(pDepthMarketData->JYSDM); + + sprintf(pField->Symbol, "%s.%s", pField->InstrumentID, ""); + + // 交易时间 + GetExchangeTime(time(nullptr), &pField->TradingDay, &pField->ActionDay, &pField->UpdateTime); + + + pField->LastPrice = pDepthMarketData->DQJ_; + //pField->Volume = 0; + //pField->Turnover = pDepthMarketData->Turnover; + //pField->OpenInterest = pDepthMarketData->OpenInterest; + //pField->AveragePrice = pDepthMarketData->AveragePrice; + pField->UpperLimitPrice = pDepthMarketData->ZTJG_; + pField->LowerLimitPrice = pDepthMarketData->DTJG_; + + pField->PreClosePrice = pDepthMarketData->ZSJ_; + pField->OpenPrice = pDepthMarketData->JKJ_; + + InitBidAsk(pField); + + do + { + if (pDepthMarketData->BidSize1_ == 0) + break; + AddBid(pField, pDepthMarketData->BidPrice1_, pDepthMarketData->BidSize1_, 0); + + if (pDepthMarketData->BidSize2_ == 0) + break; + AddBid(pField, pDepthMarketData->BidPrice2_, pDepthMarketData->BidSize2_, 0); + + if (pDepthMarketData->BidSize3_ == 0) + break; + AddBid(pField, pDepthMarketData->BidPrice3_, pDepthMarketData->BidSize3_, 0); + + if (pDepthMarketData->BidSize4_ == 0) + break; + AddBid(pField, pDepthMarketData->BidPrice4_, pDepthMarketData->BidSize4_, 0); + + if (pDepthMarketData->BidSize5_ == 0) + break; + AddBid(pField, pDepthMarketData->BidPrice5_, pDepthMarketData->BidSize5_, 0); + } while (false); + + do + { + if (pDepthMarketData->AskSize1_ == 0) + break; + AddAsk(pField, pDepthMarketData->AskPrice1_, pDepthMarketData->AskSize1_, 0); + + if (pDepthMarketData->AskSize2_ == 0) + break; + AddAsk(pField, pDepthMarketData->AskPrice2_, pDepthMarketData->AskSize2_, 0); + + if (pDepthMarketData->AskSize3_ == 0) + break; + AddAsk(pField, pDepthMarketData->AskPrice3_, pDepthMarketData->AskSize3_, 0); + + if (pDepthMarketData->AskSize4_ == 0) + break; + AddAsk(pField, pDepthMarketData->AskPrice4_, pDepthMarketData->AskSize4_, 0); + + if (pDepthMarketData->AskSize5_ == 0) + break; + AddAsk(pField, pDepthMarketData->AskPrice5_, pDepthMarketData->AskSize5_, 0); + } while (false); + + m_msgQueue->Input_NoCopy(ResponeType::OnRtnDepthMarketData, m_msgQueue, m_pClass, DepthLevelType::FULL, 0, pField, pField->Size, nullptr, 0, nullptr, 0); + } + + DeleteTableBody(ppResults); + DeleteError(pErr); + + return 0; +} \ No newline at end of file diff --git a/QuantBox_Tdx_Trade/TraderApi.h b/QuantBox_Tdx_Trade/TraderApi.h new file mode 100644 index 0000000..7901503 --- /dev/null +++ b/QuantBox_Tdx_Trade/TraderApi.h @@ -0,0 +1,261 @@ +#pragma once + +#include "../include/Tdx/TdxApi.h" +#include "../include/ApiStruct.h" +#include "../include/IDGenerator.h" + +#ifdef _WIN64 +#pragma comment(lib, "../include/Tdx/win64/TdxApi.lib") +#pragma comment(lib, "../lib/QuantBox_Queue_x64.lib") +#else +#pragma comment(lib, "../include/Tdx/win32/TdxApi.lib") +#pragma comment(lib, "../lib/QuantBox_Queue_x86.lib") +#endif + + +#include +#include +#include +#include +#include +#include +#include +#include + +#define QUERY_TIME_MIN (3) +#define QUERY_TIME_MAX (60) + +using namespace std; + +class CMsgQueue; + +class CTraderApi +{ + //请求数据包类型 + enum RequestType + { + E_Init, + E_ReqUserLoginField, + E_QryInvestorField, + E_InputOrderField, + E_InputOrderActionField, + E_QryOrderField, + E_QryTradeField, + E_QryTradingAccountField, + E_QryInvestorPositionField, + + E_QryDepthMarketDataField, + + + E_SettlementInfoConfirmField, + E_QryInstrumentField, + E_InputQuoteField, + E_InputQuoteActionField, + E_ParkedOrderField, + E_QryInvestorPositionDetailField, + E_QryInstrumentCommissionRateField, + E_QryInstrumentMarginRateField, + E_QrySettlementInfoField, + E_QryQuoteField, + }; + +public: + //static CTraderApi * pThis; + + CTraderApi(void); + virtual ~CTraderApi(void); + + void Register(void* pCallback, void* pClass); + + void Connect(const string& szPath, + ServerInfoField* pServerInfo, + UserInfoField* pUserInfo, + int count); + void Disconnect(); + + int ReqOrderInsert( + OrderField* pOrder, + int count, + OrderIDType* pInOut); + + //char* ReqParkedOrderInsert(int OrderRef, + // OrderField* pOrder1, + // OrderField* pOrder2); + + int ReqOrderAction(OrderIDType* szId, int count, OrderIDType* pOutput); + int ReqOrderAction(Order_STRUCT *pOrder, int count, OrderIDType* pOutput); + + //char* ReqQuoteInsert( + // int QuoteRef, + // QuoteField* pQuote); + + //int ReqQuoteAction(CThostFtdcQuoteField *pQuote); + ////int ReqQuoteAction(const string& szId); + + void ReqQryTradingAccount(); + void ReqQryInvestorPosition(); + //void ReqQryInvestorPositionDetail(const string& szInstrumentId); + void ReqQryInstrument(const string& szInstrumentId, const string& szExchange); + //void ReqQryInstrumentCommissionRate(const string& szInstrumentId); + ////void ReqQryInstrumentMarginRate(const string& szInstrumentId,TThostFtdcHedgeFlagType HedgeFlag = THOST_FTDC_HF_Speculation); + //void ReqQryDepthMarketData(const string& szInstrumentId); + //void ReqQrySettlementInfo(const string& szTradingDay); + + void ReqQryOrder(); + void ReqQryTrade(); + //void ReqQryQuote(); + + void ReqQryInvestor(); + + void Subscribe(const string& szInstrumentIDs, const string& szExchangeID); + +private: + //static void __stdcall OnReadPushData(ETX_APP_FUNCNO FuncNO, void* pEtxPushData); + //void _OnReadPushData(ETX_APP_FUNCNO FuncNO, void* pEtxPushData); + + friend void* __stdcall Query(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3); + virtual void QueryInThread(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3); + + friend void* __stdcall Test(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3); + virtual void TestInThread(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3); + + int _Init(); + + //登录请求 + void ReqUserLogin(); + int _ReqUserLogin(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3); + + int _ReqQryInvestor(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3); + + + int _ReqQryOrder(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3); + int _ReqQryTrade(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3); + + int _ReqOrderInsert(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3); + int _ReqOrderAction(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3); + + int _ReqQryTradingAccount(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3); + int _ReqQryInvestorPosition(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3); + + + int _Subscribe(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3); + + + //检查是否出错 + //bool IsErrorRspInfo(Error_STRUCT *pRspInfo, int nRequestID, bool bIsLast);//向消息队列输出信息 + bool IsErrorRspInfo(const char* szSource, Error_STRUCT *pRspInfo);//不输出信息 + void OutputQueryTime(time_t t, double db,const char* szSource); + + ////连接 + //virtual void OnFrontConnected(); + //virtual void OnFrontDisconnected(int nReason); + + ////认证 + //virtual void OnRspAuthenticate(CThostFtdcRspAuthenticateField *pRspAuthenticateField, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); + //virtual void OnRspUserLogin(CThostFtdcRspUserLoginField *pRspUserLogin, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); + //virtual void OnRspSettlementInfoConfirm(CThostFtdcSettlementInfoConfirmField *pSettlementInfoConfirm, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); + + ////下单 + //virtual void OnRspOrderInsert(CThostFtdcInputOrderField *pInputOrder, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); + //virtual void OnErrRtnOrderInsert(CThostFtdcInputOrderField *pInputOrder, CThostFtdcRspInfoField *pRspInfo); + + ////撤单 + //virtual void OnRspOrderAction(CThostFtdcInputOrderActionField *pInputOrderAction, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); + //virtual void OnErrRtnOrderAction(CThostFtdcOrderActionField *pOrderAction, CThostFtdcRspInfoField *pRspInfo); + + ////报单回报 + //virtual void OnRspQryOrder(CThostFtdcOrderField *pOrder, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); + //virtual void OnRtnOrder(CThostFtdcOrderField *pOrder); + + ////成交回报 + //virtual void OnRspQryTrade(CThostFtdcTradeField *pTrade, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); + //virtual void OnRtnTrade(CThostFtdcTradeField *pTrade); + + ////报价录入 + //virtual void OnRspQuoteInsert(CThostFtdcInputQuoteField *pInputQuote, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); + //virtual void OnErrRtnQuoteInsert(CThostFtdcInputQuoteField *pInputQuote, CThostFtdcRspInfoField *pRspInfo); + //virtual void OnRspQryQuote(CThostFtdcQuoteField *pQuote, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); + //virtual void OnRtnQuote(CThostFtdcQuoteField *pQuote); + + ////报价撤单 + //virtual void OnRspQuoteAction(CThostFtdcInputQuoteActionField *pInputQuoteAction, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); + //virtual void OnErrRtnQuoteAction(CThostFtdcQuoteActionField *pQuoteAction, CThostFtdcRspInfoField *pRspInfo); + + ////仓位 + //virtual void OnRspQryInvestorPosition(CThostFtdcInvestorPositionField *pInvestorPosition, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); + //virtual void OnRspQryInvestorPositionDetail(CThostFtdcInvestorPositionDetailField *pInvestorPositionDetail, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); + //virtual void OnRspQryInvestorPositionCombineDetail(CThostFtdcInvestorPositionCombineDetailField *pInvestorPositionCombineDetail, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast) {}; + + ////资金 + //virtual void OnRspQryTradingAccount(CThostFtdcTradingAccountField *pTradingAccount, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); + + ////合约、手续费 + //virtual void OnRspQryInstrument(CThostFtdcInstrumentField *pInstrument, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); + //virtual void OnRspQryInstrumentMarginRate(CThostFtdcInstrumentMarginRateField *pInstrumentMarginRate, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); + //virtual void OnRspQryInstrumentCommissionRate(CThostFtdcInstrumentCommissionRateField *pInstrumentCommissionRate, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); + + ////查询行情响应 + //virtual void OnRspQryDepthMarketData(CThostFtdcDepthMarketDataField *pDepthMarketData, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); + + ////请求查询投资者结算结果响应 + //virtual void OnRspQrySettlementInfo(CThostFtdcSettlementInfoField *pSettlementInfo, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); + + ////其它 + //virtual void OnRspError(CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); + //virtual void OnRtnInstrumentStatus(CThostFtdcInstrumentStatusField *pInstrumentStatus); +private: + void CompareTradeMapAndEmit(unordered_map &oldMap, unordered_map &newMap); + void CompareTradeListAndEmit(list &oldList, list &newList); + +private: + atomic m_lRequestID; //请求ID,得保持自增 + + OrderIDType m_orderInsert_Id; + + mutex m_csOrderRef; + int m_nMaxOrderRef; //报单引用,用于区分报单,保持自增 + + CTdxApi* m_pApi; //交易API + void* m_pClient; + + + string m_szPath; //生成配置文件的路径 + ServerInfoField m_ServerInfo; + UserInfoField m_UserInfo; + + int m_nSleep; + + unordered_map m_id_platform_order; + unordered_map m_id_api_order; + + unordered_map m_cust_acc_no; + + CMsgQueue* m_msgQueue; //消息队列指针 + CMsgQueue* m_msgQueue_Query; //发送消息队列指针 + CMsgQueue* m_msgQueue_Order; //报单消息队列指针 + CMsgQueue* m_msgQueue_Test; //测试用 + + UserInfoField* m_pUserInfos; + int m_UserInfo_Pos; + int m_UserInfo_Count; + + void* m_pClass; + + CIDGenerator* m_pIDGenerator; + + list m_OldTradeList; + list m_NewTradeList; + unordered_map m_NewTradeMap; + unordered_map m_OldTradeMap; + + + list m_OldOrderList; + list m_NewOrderList; + + time_t m_QueryTradeTime; + time_t m_QueryOrderTime; + int m_OrderNotUpdateCount; + bool m_TradeListReverse; + bool m_LastIsMerge; +}; + diff --git a/QuantBox_Tdx_Trade/TypeConvert.cpp b/QuantBox_Tdx_Trade/TypeConvert.cpp new file mode 100644 index 0000000..65cb2e4 --- /dev/null +++ b/QuantBox_Tdx_Trade/TypeConvert.cpp @@ -0,0 +1,239 @@ +#include "stdafx.h" +#include "TypeConvert.h" +#include "../include/Tdx/tdx_enum.h" + +OrderType WTFS_2_OrderType(int In) +{ + switch (In) + { + case WTFS_Limit: + return OrderType::Limit; + default: + return OrderType::Market; + } +} + +TimeInForce WTFS_2_TimeInForce(int In) +{ + switch (In) + { + case WTFS_Limit: + case WTFS_Best_Reverse: + case WTFS_Best_Forward: + return TimeInForce::Day; + case WTFS_IOC: + case WTFS_Five_IOC: + return TimeInForce::IOC; + case WTFS_FOK: + return TimeInForce::FOK; + case WTFS_Five_Limit: + return TimeInForce::Day; + default: + return TimeInForce::Day; + } +} + +OrderStatus ZTSM_2_OrderStatus(int In) +{ + switch (In) + { + case ZTSM_NotSent: + return OrderStatus::PendingNew; + case ZTSM_New: + return OrderStatus::New; + case ZTSM_Illegal: + return OrderStatus::Rejected; + case ZTSM_AllFilled: + return OrderStatus::Filled; + case ZTSM_AllCancelled: + return OrderStatus::Cancelled; + case ZTSM_PartiallyFilled: + return OrderStatus::PartiallyFilled; + default: + return OrderStatus::NotSent; + } +} + +ExecType ZTSM_2_ExecType(int In) +{ + switch (In) + { + case ZTSM_NotSent: + return ExecType::ExecNew; + case ZTSM_New: + return ExecType::ExecNew; + case ZTSM_Illegal: + return ExecType::ExecRejected; + case ZTSM_AllFilled: + case ZTSM_PartiallyFilled: + return ExecType::ExecTrade; + case ZTSM_AllCancelled: + case ZTSM_PartiallyCancelled: + return ExecType::ExecCancelled; + + return ExecType::ExecTrade; + default: + return ExecType::ExecNew; + } +} + +bool ZTSM_IsDone(int In) +{ + switch (In) + { + case ZTSM_Illegal: + case ZTSM_AllFilled: + case ZTSM_AllCancelled: + case ZTSM_PartiallyCancelled: + return true; + } + return false; +} + +bool ZTSM_IsNotSent(int In) +{ + switch (In) + { + case ZTSM_NotSent: + return true; + } + return false; +} + +// 将买卖方式转成买卖方向 +OrderSide MMBZ_2_OrderSide(int In) +{ + switch (In) + { + case MMBZ_Buy_Limit: + return OrderSide::Buy; + case MMBZ_Sell_Limit: + return OrderSide::Sell; + default: + break; + } + return OrderSide::Buy; +} + +void CJLB_2_TradeField(CJLB_STRUCT* pIn, TradeField* pOut) +{ + strcpy(pOut->ID, pIn->WTBH); + strcpy(pOut->InstrumentID, pIn->ZQDM); + pOut->Price = pIn->CJJG_; + pOut->Qty = pIn->CJSL_; + pOut->Date = pIn->CJRQ_; + pOut->Time = pIn->CJSJ_; + pOut->Side = MMBZ_2_OrderSide(pIn->MMBZ_); + + strcpy(pOut->TradeID, pIn->CJBH); + + pOut->Commission = pIn->YJ_ + pIn->YHS_ + pIn->GHF_ + pIn->CJF_; + + pOut->OpenClose = pOut->Side == OrderSide::Buy ? OpenCloseType::Open : OpenCloseType::Close; + pOut->HedgeFlag = HedgeFlagType::Speculation; + +} + +void WTLB_2_OrderField_0(WTLB_STRUCT* pIn, OrderField* pOut) +{ + strcpy(pOut->ID, pIn->WTBH); + strcpy(pOut->InstrumentID, pIn->ZQDM); + pOut->Price = pIn->WTJG_; + pOut->Qty = pIn->WTSL_; + pOut->Date = pIn->WTRQ_; + pOut->Time = pIn->WTSJ_; + pOut->Side = MMBZ_2_OrderSide(pIn->MMBZ_); + + pOut->Type = WTFS_2_OrderType(pIn->BJFS_); + pOut->TimeInForce = WTFS_2_TimeInForce(pIn->BJFS_); + + pOut->Status = ZTSM_2_OrderStatus(pIn->ZTSM_); + pOut->ExecType = ZTSM_2_ExecType(pIn->ZTSM_); + + pOut->OpenClose = pOut->Side == OrderSide::Buy ? OpenCloseType::Open : OpenCloseType::Close; + pOut->HedgeFlag = HedgeFlagType::Speculation; + + strcpy(pOut->Account, pIn->GDDM); + + pOut->AvgPx = pIn->CJJG_; + pOut->CumQty = pIn->CJSL_; + pOut->LeavesQty = pIn->WTSL_ - pIn->CJSL_ - pIn->CDSL_; + + strcpy(pOut->Text, pIn->ZTSM); +} + +int OrderType_2_WTFS(OrderType In) +{ + switch (In) + { + case Market: + case Stop: + case MarketOnClose: + case TrailingStop: + return WTFS_Five_IOC;// 只推荐使用五档模拟市价 + case Limit: + case StopLimit: + case TrailingStopLimit: + return WTFS_Limit; + case Pegged: + default: + return WTFS_Limit; + } +} + + +void OrderField_2_Order_STRUCT(OrderField* pIn, Order_STRUCT* pOut) +{ + strcpy(pOut->ZQDM, pIn->InstrumentID); + pOut->Price = pIn->Price; + pOut->Qty = pIn->Qty; + pOut->WTFS = OrderType_2_WTFS(pIn->Type); + pOut->RZRQBS = RZRQBS_NO; + + // 这个地方后期要再改,因为没有处理基金等情况 + switch (pIn->Type) + { + case OrderType::Market: + if (pIn->Side == OrderSide::Buy) + pOut->MMBZ = MMBZ_Buy_Market; + else + pOut->MMBZ = MMBZ_Sell_Market; + break; + case OrderType::Limit: + if (pIn->Side == OrderSide::Buy) + pOut->MMBZ = MMBZ_Buy_Limit; + else + pOut->MMBZ = MMBZ_Sell_Limit; + break; + } +} + +void GDLB_2_InvestorField(GDLB_STRUCT* pIn, InvestorField* pOut) +{ + strcpy(pOut->InvestorID, pIn->GDDM); + strcpy(pOut->InvestorName, pIn->GDMC); +} + +void ZJYE_2_AccountField(ZJYE_STRUCT* pIn, AccountField* pOut) +{ + strcpy(pOut->Account, pIn->ZJZH); + //pIn->BZ; + pOut->Available = pIn->KYZJ_; + + // 还有很多不知道如何对应,有可能需要扩展XAPI部分 + pOut->Balance = pIn->ZZC_; + +} + +void GFLB_2_PositionField(GFLB_STRUCT* pIn, PositionField* pOut) +{ + pOut->Side = PositionSide::Long; + pOut->Position = pIn->ZQSL_; + pOut->TdPosition = pIn->DJSL_; + pOut->YdPosition = pIn->KMSL_; + pOut->HedgeFlag = HedgeFlagType::Speculation; + strcpy(pOut->InstrumentID, pIn->ZQDM); + strcpy(pOut->Symbol, pIn->ZQDM); + + // 还有一些信息没有 +} \ No newline at end of file diff --git a/QuantBox_Tdx_Trade/TypeConvert.h b/QuantBox_Tdx_Trade/TypeConvert.h new file mode 100644 index 0000000..86a7d6f --- /dev/null +++ b/QuantBox_Tdx_Trade/TypeConvert.h @@ -0,0 +1,23 @@ +#pragma once + +#include "../include/ApiStruct.h" + +#include "../include/Tdx/tdx_struct.h" + +// 两种情况: +// 1.完全重建 +// 2.部分重建 +bool ZTSM_IsDone(int In); +bool ZTSM_IsNotSent(int In); + +void GDLB_2_InvestorField(GDLB_STRUCT* pIn, InvestorField* pOut); +void ZJYE_2_AccountField(ZJYE_STRUCT* pIn, AccountField* pOut); +void GFLB_2_PositionField(GFLB_STRUCT* pIn, PositionField* pOut); + +void CJLB_2_TradeField(CJLB_STRUCT* pIn, TradeField* pOut); + +// +void WTLB_2_OrderField_0(WTLB_STRUCT* pIn, OrderField* pOut); +//void WTLB_2_OrderField_1(WTLB_STRUCT* pIn, OrderField* pOut); + +void OrderField_2_Order_STRUCT(OrderField* pIn, Order_STRUCT* pOut); diff --git a/QuantBox_Tdx_Trade/dllmain.cpp b/QuantBox_Tdx_Trade/dllmain.cpp new file mode 100644 index 0000000..69b5891 --- /dev/null +++ b/QuantBox_Tdx_Trade/dllmain.cpp @@ -0,0 +1,19 @@ +// dllmain.cpp : Defines the entry point for the DLL application. +#include "stdafx.h" + +BOOL APIENTRY DllMain( HMODULE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} + diff --git a/QuantBox_Tdx_Trade/main.cpp b/QuantBox_Tdx_Trade/main.cpp new file mode 100644 index 0000000..b8829e7 --- /dev/null +++ b/QuantBox_Tdx_Trade/main.cpp @@ -0,0 +1,85 @@ +#include "stdafx.h" +#include "../include/ApiHeader.h" +#include "../include/QueueEnum.h" +#include "TraderApi.h" + +inline CTraderApi* GetApi(void* pApi) +{ + return static_cast(pApi); +} + +void* __stdcall XRequest(char type, void* pApi1, void* pApi2, double double1, double double2, void* ptr1, int size1, void* ptr2, int size2, void* ptr3, int size3) +{ + RequestType rt = (RequestType)type; + switch (rt) + { + case GetApiType: + return (void*)(ApiType::Trade | ApiType::MarketData | ApiType::Query_); + case GetApiVersion: + return (void*)"0.1.0.20151020"; + case GetApiName: + return (void*)"Tdx"; + case Create: + return new CTraderApi(); + default: + break; + } + + if (pApi1 == nullptr) + { + return nullptr; + } + + CTraderApi* pApi = GetApi(pApi1); + + switch (rt) + { + case Release: + delete pApi; + return nullptr; + case Register: + pApi->Register(ptr1, ptr2); + break; + case Connect: + pApi->Connect((const char*)ptr3, (ServerInfoField*)ptr1, (UserInfoField*)ptr2,size2); + break; + case Disconnect: + pApi->Disconnect(); + break; + case ReqQryOrder: + pApi->ReqQryOrder(); + break; + case ReqQryTrade: + pApi->ReqQryTrade(); + break; + case ReqQryInvestorPosition: + pApi->ReqQryInvestorPosition(); + break; + case ReqQryTradingAccount: + pApi->ReqQryTradingAccount(); + break; + /*case ReqQryInstrument: + pApi->ReqQryInstrument((const char*)ptr1, (const char*)ptr2); + break; + case ReqQrySettlementInfo: + pApi->ReqQrySettlementInfo((const char*)ptr1); + break;*/ + case ReqOrderInsert: + return (void*)pApi->ReqOrderInsert((OrderField*)ptr1, size1, (OrderIDType*)ptr2); + case ReqOrderAction: + return (void*)pApi->ReqOrderAction((OrderIDType*)ptr1, size1, (OrderIDType*)ptr2); + case ReqQryInvestor: + pApi->ReqQryInvestor(); + break; + case Subscribe: + pApi->Subscribe((const char*)ptr1, (const char*)ptr2); + break; + //case Unsubscribe: + // pApi->Unsubscribe((const char*)ptr1, (const char*)ptr2); + // break; + default: + break; + } + + return pApi1; +} diff --git a/QuantBox_Tdx_Trade/stdafx.cpp b/QuantBox_Tdx_Trade/stdafx.cpp new file mode 100644 index 0000000..06ec8f9 --- /dev/null +++ b/QuantBox_Tdx_Trade/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// QuantBox_Tdx_Trade.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/QuantBox_Tdx_Trade/stdafx.h b/QuantBox_Tdx_Trade/stdafx.h new file mode 100644 index 0000000..f3a0737 --- /dev/null +++ b/QuantBox_Tdx_Trade/stdafx.h @@ -0,0 +1,16 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +#include "targetver.h" + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +// Windows Header Files: +#include + + + +// TODO: reference additional headers your program requires here diff --git a/QuantBox_Tdx_Trade/targetver.h b/QuantBox_Tdx_Trade/targetver.h new file mode 100644 index 0000000..87c0086 --- /dev/null +++ b/QuantBox_Tdx_Trade/targetver.h @@ -0,0 +1,8 @@ +#pragma once + +// Including SDKDDKVer.h defines the highest available Windows platform. + +// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and +// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. + +#include diff --git a/QuantBox_TongShi_Quote/TypeConvert.cpp b/QuantBox_TongShi_Quote/TypeConvert.cpp index d427f22..c661d78 100644 --- a/QuantBox_TongShi_Quote/TypeConvert.cpp +++ b/QuantBox_TongShi_Quote/TypeConvert.cpp @@ -8,7 +8,7 @@ ExchangeType Market_2_ExchangeType(WORD In) case SH_MARKET_EX: return ExchangeType::SSE; case SZ_MARKET_EX: - return ExchangeType::SZE; + return ExchangeType::SZSE; case HK_MARKET_EX: return ExchangeType::HKEx; case SB_MARKET_EX: diff --git a/QuantBox_TongShi_Quote/main.cpp b/QuantBox_TongShi_Quote/main.cpp index 0ba8df3..7958ab0 100644 --- a/QuantBox_TongShi_Quote/main.cpp +++ b/QuantBox_TongShi_Quote/main.cpp @@ -15,7 +15,7 @@ void* __stdcall XRequest(char type, void* pApi1, void* pApi2, double double1, do switch (rt) { case GetApiType: - return (void*)(ApiType::MarketData); + return (void*)(ApiType::MarketData | ApiType::Instrument); case GetApiVersion: return (void*)"0.2.0.20150419"; case GetApiName: diff --git a/QuantBox_XAPI_TEST/QuantBox_XAPI_TEST.cpp b/QuantBox_XAPI_TEST/QuantBox_XAPI_TEST.cpp index 6c7798f..77b5e31 100644 --- a/QuantBox_XAPI_TEST/QuantBox_XAPI_TEST.cpp +++ b/QuantBox_XAPI_TEST/QuantBox_XAPI_TEST.cpp @@ -28,6 +28,10 @@ class CXSpiImpl :public CXSpi virtual void OnConnectionStatus(CXApi* pApi, ConnectionStatus status, RspUserLoginField* pUserLogin, int size1) { printf("%d\r\n", status); + if (pUserLogin) + { + printf("%s\r\n", pUserLogin->ErrorMsg); + } if (status == ConnectionStatus::Done) { if ((pApi->GetApiType() & ApiType::MarketData) == ApiType::MarketData) @@ -99,7 +103,7 @@ class CXSpiImpl :public CXSpi // 只要上海与深圳,不处理三板 return exchange != ExchangeType::NEEQ; - //type = ExchangeType::SZE; + //type = ExchangeType::SZSE; //double1 = 399300; int prefix1 = instrument_part1 / 100000; @@ -108,7 +112,7 @@ class CXSpiImpl :public CXSpi { case ExchangeType::SSE: return (prefix1 == 6); - case ExchangeType::SZE: + case ExchangeType::SZSE: return (prefix1 == 0) || (prefix3 == 300); default: break; @@ -209,7 +213,7 @@ int main_1(int argc, char* argv[]) -int main(int argc, char* argv[]) +int main_2(int argc, char* argv[]) { CXSpiImpl* p = new CXSpiImpl(); @@ -297,5 +301,62 @@ int main_4(int argc, char* argv[]) pApi1->Disconnect(); } + return 0; +} + +int main(int argc, char* argv[]) +{ + CXSpiImpl* p = new CXSpiImpl(); +#if defined WINDOWS || _WIN32 + char DLLPath1[250] = "C:\\Program Files\\SmartQuant Ltd\\OpenQuant 2014\\XAPI\\Tdx\\x86\\QuantBox_Tdx_Trade.dll"; +#else + char DLLPath1[250] = "libQuantBox_CTP_Quote.so"; +#endif + + ServerInfoField m_ServerInfo1 = { 0 }; + UserInfoField m_UserInfo = { 0 }; + + strcpy(m_ServerInfo1.Address, "D:\\new_hbzq_qq\\Login.lua"); + strcpy(m_ServerInfo1.ExtendInformation, "D:\\new_hbzq_qq\\"); + + strcpy(m_UserInfo.UserID, "05000000"); + strcpy(m_UserInfo.Password, "4"); + + CXApi* pApi1 = CXApi::CreateApi(DLLPath1); + if (pApi1) + { + if (!pApi1->Init()) + { + printf("%s\r\n", pApi1->GetLastError()); + pApi1->Disconnect(); + return -1; + } + + //p->m_pApi = pApi1; + pApi1->RegisterSpi(p); + +#if defined WINDOWS || _WIN32 + pApi1->Connect("D:\\", &m_ServerInfo1, &m_UserInfo, 1); +#else + pApi1->Connect("./", &m_ServerInfo1, &m_UserInfo, 1); +#endif + + getchar(); + + pApi1->Disconnect(); + pApi1->Disconnect(); + + getchar(); + + do + { + int c = getchar(); + if (c == 'q') + break; + } while (true); + + pApi1->Disconnect(); + } + return 0; } \ No newline at end of file diff --git a/QuantBox_XAPI_Windows.sln b/QuantBox_XAPI_Windows.sln index 50ead1e..c4d5dd1 100644 --- a/QuantBox_XAPI_Windows.sln +++ b/QuantBox_XAPI_Windows.sln @@ -53,12 +53,16 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "QuantBox_XAPI", "QuantBox_X EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "QuantBox_XAPI_TEST", "QuantBox_XAPI_TEST\QuantBox_XAPI_TEST.vcxproj", "{C77ADBF7-E610-4E57-BE4D-C122FC5BE611}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "QuantBox_Tdx_Trade", "QuantBox_Tdx_Trade\QuantBox_Tdx_Trade.vcxproj", "{BD258801-95E6-4512-9F2D-38370E33DD4E}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "QuantBox_LTS_Quote_v2", "QuantBox_LTS_Quote_v2\QuantBox_LTS_Quote_v2.vcxproj", "{D4387736-0623-4442-A4AC-AF79239F9419}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "QuantBox_LTS_Trade_v2", "QuantBox_LTS_Trade_v2\QuantBox_LTS_Trade_v2.vcxproj", "{683AECBB-89EB-4692-99C5-A527853326D4}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "QuantBox_Tdx_Trade", "QuantBox_Tdx_Trade\QuantBox_Tdx_Trade.vcxproj", "{01D3F1DE-99B3-4D41-97C3-F4680CDB980B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "QuantBox_LTS_Query_v2", "QuantBox_LTS_Query_v2\QuantBox_LTS_Query_v2.vcxproj", "{51D11C21-C4A7-4F07-9658-B8BA223684B8}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FakeAPI", "FakeAPI\FakeAPI.vcxproj", "{358586C9-A4B8-43E4-8376-59C68F0F6211}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -531,24 +535,6 @@ Global {C77ADBF7-E610-4E57-BE4D-C122FC5BE611}.Release|Win32.ActiveCfg = Release|Win32 {C77ADBF7-E610-4E57-BE4D-C122FC5BE611}.Release|Win32.Build.0 = Release|Win32 {C77ADBF7-E610-4E57-BE4D-C122FC5BE611}.Release|x64.ActiveCfg = Release|Win32 - {BD258801-95E6-4512-9F2D-38370E33DD4E}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {BD258801-95E6-4512-9F2D-38370E33DD4E}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {BD258801-95E6-4512-9F2D-38370E33DD4E}.Debug|Mixed Platforms.Build.0 = Debug|Win32 - {BD258801-95E6-4512-9F2D-38370E33DD4E}.Debug|Win32.ActiveCfg = Debug|Win32 - {BD258801-95E6-4512-9F2D-38370E33DD4E}.Debug|Win32.Build.0 = Debug|Win32 - {BD258801-95E6-4512-9F2D-38370E33DD4E}.Debug|x64.ActiveCfg = Debug|Win32 - {BD258801-95E6-4512-9F2D-38370E33DD4E}.Debug64|Any CPU.ActiveCfg = Debug|Win32 - {BD258801-95E6-4512-9F2D-38370E33DD4E}.Debug64|Mixed Platforms.ActiveCfg = Debug|Win32 - {BD258801-95E6-4512-9F2D-38370E33DD4E}.Debug64|Mixed Platforms.Build.0 = Debug|Win32 - {BD258801-95E6-4512-9F2D-38370E33DD4E}.Debug64|Win32.ActiveCfg = Debug|Win32 - {BD258801-95E6-4512-9F2D-38370E33DD4E}.Debug64|Win32.Build.0 = Debug|Win32 - {BD258801-95E6-4512-9F2D-38370E33DD4E}.Debug64|x64.ActiveCfg = Debug|Win32 - {BD258801-95E6-4512-9F2D-38370E33DD4E}.Release|Any CPU.ActiveCfg = Release|Win32 - {BD258801-95E6-4512-9F2D-38370E33DD4E}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {BD258801-95E6-4512-9F2D-38370E33DD4E}.Release|Mixed Platforms.Build.0 = Release|Win32 - {BD258801-95E6-4512-9F2D-38370E33DD4E}.Release|Win32.ActiveCfg = Release|Win32 - {BD258801-95E6-4512-9F2D-38370E33DD4E}.Release|Win32.Build.0 = Release|Win32 - {BD258801-95E6-4512-9F2D-38370E33DD4E}.Release|x64.ActiveCfg = Release|Win32 {D4387736-0623-4442-A4AC-AF79239F9419}.Debug|Any CPU.ActiveCfg = Debug|Win32 {D4387736-0623-4442-A4AC-AF79239F9419}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 {D4387736-0623-4442-A4AC-AF79239F9419}.Debug|Mixed Platforms.Build.0 = Debug|Win32 @@ -591,6 +577,60 @@ Global {683AECBB-89EB-4692-99C5-A527853326D4}.Release|Win32.Build.0 = Release|Win32 {683AECBB-89EB-4692-99C5-A527853326D4}.Release|x64.ActiveCfg = Release|x64 {683AECBB-89EB-4692-99C5-A527853326D4}.Release|x64.Build.0 = Release|x64 + {01D3F1DE-99B3-4D41-97C3-F4680CDB980B}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {01D3F1DE-99B3-4D41-97C3-F4680CDB980B}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {01D3F1DE-99B3-4D41-97C3-F4680CDB980B}.Debug|Mixed Platforms.Build.0 = Debug|Win32 + {01D3F1DE-99B3-4D41-97C3-F4680CDB980B}.Debug|Win32.ActiveCfg = Debug|Win32 + {01D3F1DE-99B3-4D41-97C3-F4680CDB980B}.Debug|Win32.Build.0 = Debug|Win32 + {01D3F1DE-99B3-4D41-97C3-F4680CDB980B}.Debug|x64.ActiveCfg = Debug|Win32 + {01D3F1DE-99B3-4D41-97C3-F4680CDB980B}.Debug64|Any CPU.ActiveCfg = Debug|Win32 + {01D3F1DE-99B3-4D41-97C3-F4680CDB980B}.Debug64|Mixed Platforms.ActiveCfg = Debug|Win32 + {01D3F1DE-99B3-4D41-97C3-F4680CDB980B}.Debug64|Mixed Platforms.Build.0 = Debug|Win32 + {01D3F1DE-99B3-4D41-97C3-F4680CDB980B}.Debug64|Win32.ActiveCfg = Debug|Win32 + {01D3F1DE-99B3-4D41-97C3-F4680CDB980B}.Debug64|Win32.Build.0 = Debug|Win32 + {01D3F1DE-99B3-4D41-97C3-F4680CDB980B}.Debug64|x64.ActiveCfg = Debug|Win32 + {01D3F1DE-99B3-4D41-97C3-F4680CDB980B}.Release|Any CPU.ActiveCfg = Release|Win32 + {01D3F1DE-99B3-4D41-97C3-F4680CDB980B}.Release|Mixed Platforms.ActiveCfg = Release|Win32 + {01D3F1DE-99B3-4D41-97C3-F4680CDB980B}.Release|Mixed Platforms.Build.0 = Release|Win32 + {01D3F1DE-99B3-4D41-97C3-F4680CDB980B}.Release|Win32.ActiveCfg = Release|Win32 + {01D3F1DE-99B3-4D41-97C3-F4680CDB980B}.Release|Win32.Build.0 = Release|Win32 + {01D3F1DE-99B3-4D41-97C3-F4680CDB980B}.Release|x64.ActiveCfg = Release|Win32 + {51D11C21-C4A7-4F07-9658-B8BA223684B8}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {51D11C21-C4A7-4F07-9658-B8BA223684B8}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {51D11C21-C4A7-4F07-9658-B8BA223684B8}.Debug|Mixed Platforms.Build.0 = Debug|Win32 + {51D11C21-C4A7-4F07-9658-B8BA223684B8}.Debug|Win32.ActiveCfg = Debug|Win32 + {51D11C21-C4A7-4F07-9658-B8BA223684B8}.Debug|Win32.Build.0 = Debug|Win32 + {51D11C21-C4A7-4F07-9658-B8BA223684B8}.Debug|x64.ActiveCfg = Debug|Win32 + {51D11C21-C4A7-4F07-9658-B8BA223684B8}.Debug64|Any CPU.ActiveCfg = Debug|Win32 + {51D11C21-C4A7-4F07-9658-B8BA223684B8}.Debug64|Mixed Platforms.ActiveCfg = Debug|Win32 + {51D11C21-C4A7-4F07-9658-B8BA223684B8}.Debug64|Mixed Platforms.Build.0 = Debug|Win32 + {51D11C21-C4A7-4F07-9658-B8BA223684B8}.Debug64|Win32.ActiveCfg = Debug|Win32 + {51D11C21-C4A7-4F07-9658-B8BA223684B8}.Debug64|Win32.Build.0 = Debug|Win32 + {51D11C21-C4A7-4F07-9658-B8BA223684B8}.Debug64|x64.ActiveCfg = Debug|Win32 + {51D11C21-C4A7-4F07-9658-B8BA223684B8}.Release|Any CPU.ActiveCfg = Release|Win32 + {51D11C21-C4A7-4F07-9658-B8BA223684B8}.Release|Mixed Platforms.ActiveCfg = Release|Win32 + {51D11C21-C4A7-4F07-9658-B8BA223684B8}.Release|Mixed Platforms.Build.0 = Release|Win32 + {51D11C21-C4A7-4F07-9658-B8BA223684B8}.Release|Win32.ActiveCfg = Release|Win32 + {51D11C21-C4A7-4F07-9658-B8BA223684B8}.Release|Win32.Build.0 = Release|Win32 + {51D11C21-C4A7-4F07-9658-B8BA223684B8}.Release|x64.ActiveCfg = Release|Win32 + {358586C9-A4B8-43E4-8376-59C68F0F6211}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {358586C9-A4B8-43E4-8376-59C68F0F6211}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {358586C9-A4B8-43E4-8376-59C68F0F6211}.Debug|Mixed Platforms.Build.0 = Debug|Win32 + {358586C9-A4B8-43E4-8376-59C68F0F6211}.Debug|Win32.ActiveCfg = Debug|Win32 + {358586C9-A4B8-43E4-8376-59C68F0F6211}.Debug|Win32.Build.0 = Debug|Win32 + {358586C9-A4B8-43E4-8376-59C68F0F6211}.Debug|x64.ActiveCfg = Debug|Win32 + {358586C9-A4B8-43E4-8376-59C68F0F6211}.Debug64|Any CPU.ActiveCfg = Debug|Win32 + {358586C9-A4B8-43E4-8376-59C68F0F6211}.Debug64|Mixed Platforms.ActiveCfg = Debug|Win32 + {358586C9-A4B8-43E4-8376-59C68F0F6211}.Debug64|Mixed Platforms.Build.0 = Debug|Win32 + {358586C9-A4B8-43E4-8376-59C68F0F6211}.Debug64|Win32.ActiveCfg = Debug|Win32 + {358586C9-A4B8-43E4-8376-59C68F0F6211}.Debug64|Win32.Build.0 = Debug|Win32 + {358586C9-A4B8-43E4-8376-59C68F0F6211}.Debug64|x64.ActiveCfg = Debug|Win32 + {358586C9-A4B8-43E4-8376-59C68F0F6211}.Release|Any CPU.ActiveCfg = Release|Win32 + {358586C9-A4B8-43E4-8376-59C68F0F6211}.Release|Mixed Platforms.ActiveCfg = Release|Win32 + {358586C9-A4B8-43E4-8376-59C68F0F6211}.Release|Mixed Platforms.Build.0 = Release|Win32 + {358586C9-A4B8-43E4-8376-59C68F0F6211}.Release|Win32.ActiveCfg = Release|Win32 + {358586C9-A4B8-43E4-8376-59C68F0F6211}.Release|Win32.Build.0 = Release|Win32 + {358586C9-A4B8-43E4-8376-59C68F0F6211}.Release|x64.ActiveCfg = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/QuantBox_XSpeedStock_Quote/MdUserApi.cpp b/QuantBox_XSpeedStock_Quote/MdUserApi.cpp index dcf595e..c939f8f 100644 --- a/QuantBox_XSpeedStock_Quote/MdUserApi.cpp +++ b/QuantBox_XSpeedStock_Quote/MdUserApi.cpp @@ -119,7 +119,7 @@ ConfigInfoField* CMdUserApi::Config(ConfigInfoField* pConfigInfo) return nullptr; } -bool CMdUserApi::IsErrorRspInfo_Output(struct DFITCSECRspInfoField *pRspInfo) +bool CMdUserApi::IsErrorRspInfo_Output(const char* szSource, struct DFITCSECRspInfoField *pRspInfo) { bool bRet = ((pRspInfo) && (pRspInfo->errorID != 0)); @@ -129,6 +129,7 @@ bool CMdUserApi::IsErrorRspInfo_Output(struct DFITCSECRspInfoField *pRspInfo) pField->ErrorID = pRspInfo->errorID; strcpy(pField->ErrorMsg, pRspInfo->errorMsg); + strcpy(pField->Source, szSource); m_msgQueue->Input_NoCopy(ResponeType::OnRtnError, m_msgQueue, m_pClass, true, 0, pField, sizeof(ErrorField), nullptr, 0, nullptr, 0); } @@ -416,13 +417,13 @@ void CMdUserApi::OnRspStockUserLogin(struct DFITCSECRspUserLoginField * pRspUser void CMdUserApi::OnRspError(struct DFITCSECRspInfoField *pRspInfo) { - IsErrorRspInfo_Output(pRspInfo); + IsErrorRspInfo_Output("OnRspError", pRspInfo); } void CMdUserApi::OnRspStockSubMarketData(struct DFITCSECSpecificInstrumentField * pSpecificInstrument, struct DFITCSECRspInfoField * pRspInfo) { //ģƽ̨ᴥҪԼάһѾĵĺԼб - if (!IsErrorRspInfo_Output(pRspInfo) + if (!IsErrorRspInfo_Output("OnRspStockSubMarketData", pRspInfo) && pSpecificInstrument) { lock_guard cl(m_csMapInstrumentIDs); @@ -442,7 +443,7 @@ void CMdUserApi::OnRspStockSubMarketData(struct DFITCSECSpecificInstrumentField void CMdUserApi::OnRspStockUnSubMarketData(struct DFITCSECSpecificInstrumentField * pSpecificInstrument, struct DFITCSECRspInfoField * pRspInfo) { //ģƽ̨ᴥ - if (!IsErrorRspInfo_Output(pRspInfo) + if (!IsErrorRspInfo_Output("OnRspStockUnSubMarketData", pRspInfo) && pSpecificInstrument) { lock_guard cl(m_csMapInstrumentIDs); @@ -600,7 +601,7 @@ int CMdUserApi::_ReqStockAvailableQuotQry(char type, void* pApi1, void* pApi2, d void CMdUserApi::OnRspStockAvailableQuot(struct DFITCRspQuotQryField * pAvailableQuotInfo, struct DFITCSECRspInfoField * pRspInfo, bool flag) { - if (!IsErrorRspInfo(pRspInfo)) + if (!IsErrorRspInfo_Output("OnRspStockAvailableQuot", pRspInfo)) { if (pAvailableQuotInfo) { diff --git a/QuantBox_XSpeedStock_Quote/MdUserApi.h b/QuantBox_XSpeedStock_Quote/MdUserApi.h index f0ccd6a..1351e95 100644 --- a/QuantBox_XSpeedStock_Quote/MdUserApi.h +++ b/QuantBox_XSpeedStock_Quote/MdUserApi.h @@ -110,7 +110,7 @@ class CMdUserApi : //virtual void OnRspSopAvailableQuot(struct DFITCRspQuotQryField * pAvailableQuotInfo, struct DFITCSECRspInfoField * pRspInfo, bool flag); //Ƿ - bool IsErrorRspInfo_Output(struct DFITCSECRspInfoField *pRspInfo);//Ϣ͵Ϣ + bool IsErrorRspInfo_Output(const char* szSource, struct DFITCSECRspInfoField *pRspInfo);//Ϣ͵Ϣ bool IsErrorRspInfo(struct DFITCSECRspInfoField *pRspInfo);//ͳϢ private: diff --git a/QuantBox_XSpeedStock_Trade/TraderApi.cpp b/QuantBox_XSpeedStock_Trade/TraderApi.cpp index cfb9de1..d32a48b 100644 --- a/QuantBox_XSpeedStock_Trade/TraderApi.cpp +++ b/QuantBox_XSpeedStock_Trade/TraderApi.cpp @@ -93,7 +93,7 @@ void CTraderApi::Register(void* pCallback, void* pClass) } } -bool CTraderApi::IsErrorRspInfo_Output(struct DFITCSECRspInfoField *pRspInfo) +bool CTraderApi::IsErrorRspInfo_Output(const char* szSource, struct DFITCSECRspInfoField *pRspInfo) { bool bRet = ((pRspInfo) && (pRspInfo->errorID != 0)); if (bRet) @@ -102,6 +102,7 @@ bool CTraderApi::IsErrorRspInfo_Output(struct DFITCSECRspInfoField *pRspInfo) pField->ErrorID = pRspInfo->errorID; strcpy(pField->ErrorMsg, pRspInfo->errorMsg); + strcpy(pField->Source, szSource); m_msgQueue->Input_NoCopy(ResponeType::OnRtnError, m_msgQueue, m_pClass, true, 0, pField, sizeof(ErrorField), nullptr, 0, nullptr, 0); } diff --git a/QuantBox_XSpeedStock_Trade/TraderApi.h b/QuantBox_XSpeedStock_Trade/TraderApi.h index 388fc01..e45d11f 100644 --- a/QuantBox_XSpeedStock_Trade/TraderApi.h +++ b/QuantBox_XSpeedStock_Trade/TraderApi.h @@ -121,7 +121,7 @@ class CTraderApi : int ReqInit(); //Ƿ - bool IsErrorRspInfo_Output(struct DFITCSECRspInfoField *pRspInfo);//Ϣ͵Ϣ + bool IsErrorRspInfo_Output(const char* szSource, struct DFITCSECRspInfoField *pRspInfo);//Ϣ͵Ϣ bool IsErrorRspInfo(struct DFITCSECRspInfoField *pRspInfo); //Ϣ // diff --git a/QuantBox_XSpeedStock_Trade/TypeConvert.cpp b/QuantBox_XSpeedStock_Trade/TypeConvert.cpp index 37d5317..dd478c5 100644 --- a/QuantBox_XSpeedStock_Trade/TypeConvert.cpp +++ b/QuantBox_XSpeedStock_Trade/TypeConvert.cpp @@ -275,7 +275,7 @@ ExchangeType DFITCSECExchangeIDType_2_ExchangeType(DFITCSECExchangeIDType In) case 'H': return ExchangeType::SSE; case 'Z': - return ExchangeType::SZE; + return ExchangeType::SZSE; default: return ExchangeType::Undefined_; } diff --git a/QuantBox_XSpeedStock_Trade/main.cpp b/QuantBox_XSpeedStock_Trade/main.cpp index 60f20b6..0b06962 100644 --- a/QuantBox_XSpeedStock_Trade/main.cpp +++ b/QuantBox_XSpeedStock_Trade/main.cpp @@ -15,7 +15,7 @@ void* __stdcall XRequest(char type, void* pApi1, void* pApi2, double double1, do switch (rt) { case GetApiType: - return (void*)(ApiType::Trade | ApiType::QuoteRequest | ApiType::Instrument); + return (void*)(ApiType::Trade | ApiType::QuoteRequest | ApiType::Instrument | ApiType::Query_); case GetApiVersion: return (void*)"0.3.0.20150407"; case GetApiName: diff --git a/QuantBox_XSpeed_Quote/MdUserApi.cpp b/QuantBox_XSpeed_Quote/MdUserApi.cpp index c0ae8c7..4c853ae 100644 --- a/QuantBox_XSpeed_Quote/MdUserApi.cpp +++ b/QuantBox_XSpeed_Quote/MdUserApi.cpp @@ -105,7 +105,7 @@ ConfigInfoField* CMdUserApi::Config(ConfigInfoField* pConfigInfo) return nullptr; } -bool CMdUserApi::IsErrorRspInfo_Output(struct DFITCErrorRtnField *pRspInfo) +bool CMdUserApi::IsErrorRspInfo_Output(const char* szSource, struct DFITCErrorRtnField *pRspInfo) { bool bRet = ((pRspInfo) && (pRspInfo->nErrorID != 0)); if (bRet) @@ -114,6 +114,7 @@ bool CMdUserApi::IsErrorRspInfo_Output(struct DFITCErrorRtnField *pRspInfo) pField->ErrorID = pRspInfo->nErrorID; strcpy(pField->ErrorMsg, pRspInfo->errorMsg); + strcpy(pField->Source, szSource); m_msgQueue->Input_NoCopy(ResponeType::OnRtnError, m_msgQueue, m_pClass, true, 0, pField, sizeof(ErrorField), nullptr, 0, nullptr, 0); } @@ -448,13 +449,13 @@ void CMdUserApi::OnRspUserLogin(struct DFITCUserLoginInfoRtnField * pRspUserLogi void CMdUserApi::OnRspError(struct DFITCErrorRtnField *pRspInfo) { - IsErrorRspInfo_Output(pRspInfo); + IsErrorRspInfo_Output("OnRspError",pRspInfo); } void CMdUserApi::OnRspSubMarketData(struct DFITCSpecificInstrumentField * pSpecificInstrument, struct DFITCErrorRtnField * pRspInfo) { //ģƽ̨ᴥҪԼάһѾĵĺԼб - if(!IsErrorRspInfo(pRspInfo) + if (!IsErrorRspInfo_Output("OnRspSubMarketData", pRspInfo) &&pSpecificInstrument) { lock_guard cl(m_csMapInstrumentIDs); @@ -466,7 +467,7 @@ void CMdUserApi::OnRspSubMarketData(struct DFITCSpecificInstrumentField * pSpeci void CMdUserApi::OnRspUnSubMarketData(struct DFITCSpecificInstrumentField * pSpecificInstrument, struct DFITCErrorRtnField * pRspInfo) { //ģƽ̨ᴥ - if(!IsErrorRspInfo(pRspInfo) + if (!IsErrorRspInfo_Output("OnRspUnSubMarketData", pRspInfo) &&pSpecificInstrument) { lock_guard cl(m_csMapInstrumentIDs); diff --git a/QuantBox_XSpeed_Quote/MdUserApi.h b/QuantBox_XSpeed_Quote/MdUserApi.h index 1a08348..bafaed2 100644 --- a/QuantBox_XSpeed_Quote/MdUserApi.h +++ b/QuantBox_XSpeed_Quote/MdUserApi.h @@ -87,7 +87,7 @@ class CMdUserApi : virtual void OnRspTradingDay(struct DFITCTradingDayRtnField * pTradingDayRtnData); //Ƿ - bool IsErrorRspInfo_Output(struct DFITCErrorRtnField *pRspInfo);//Ϣ͵Ϣ + bool IsErrorRspInfo_Output(const char* szSource, struct DFITCErrorRtnField *pRspInfo);//Ϣ͵Ϣ bool IsErrorRspInfo(struct DFITCErrorRtnField *pRspInfo);//ͳϢ private: diff --git a/QuantBox_XSpeed_Trade/TraderApi.cpp b/QuantBox_XSpeed_Trade/TraderApi.cpp index 3450546..2b0013a 100644 --- a/QuantBox_XSpeed_Trade/TraderApi.cpp +++ b/QuantBox_XSpeed_Trade/TraderApi.cpp @@ -93,7 +93,7 @@ void CTraderApi::Register(void* pCallback, void* pClass) } } -bool CTraderApi::IsErrorRspInfo_Output(struct DFITCErrorRtnField *pRspInfo) +bool CTraderApi::IsErrorRspInfo_Output(const char* szSource, struct DFITCErrorRtnField *pRspInfo) { bool bRet = ((pRspInfo) && (pRspInfo->nErrorID != 0)); if (bRet) @@ -102,6 +102,7 @@ bool CTraderApi::IsErrorRspInfo_Output(struct DFITCErrorRtnField *pRspInfo) pField->ErrorID = pRspInfo->nErrorID; strcpy(pField->ErrorMsg, pRspInfo->errorMsg); + strcpy(pField->Source, szSource); m_msgQueue->Input_NoCopy(ResponeType::OnRtnError, m_msgQueue, m_pClass, true, 0, pField, sizeof(ErrorField), nullptr, 0, nullptr, 0); } @@ -356,6 +357,7 @@ int CTraderApi::ReqOrderInsert( OrderField* pField = new OrderField(); memcpy(pField, pOrder, sizeof(OrderField)); strcpy(pField->ID, m_orderInsert_Id); + strcpy(pField->LocalID, pField->ID); m_id_platform_order.insert(pair(m_orderInsert_Id, pField)); } strncpy((char*)pInOut, m_orderInsert_Id, sizeof(OrderIDType)); @@ -1184,6 +1186,7 @@ void CTraderApi::OnOrder(DFITCOrderRtnField *pOrder) pField = (OrderField*)m_msgQueue->new_block(sizeof(OrderField)); strcpy(pField->ID, orderId); + strcpy(pField->LocalID, pField->ID); strcpy(pField->InstrumentID, pOrder->instrumentID); strcpy(pField->ExchangeID, pOrder->exchangeID); pField->HedgeFlag = DFITCSpeculatorType_2_HedgeFlagType(pOrder->speculator); @@ -1207,6 +1210,7 @@ void CTraderApi::OnOrder(DFITCOrderRtnField *pOrder) { pField = it->second; strcpy(pField->ID, orderId); + strcpy(pField->LocalID, pField->ID); //pField->LeavesQty = pOrder->; pField->Price = pOrder->insertPrice; pField->Status = DFITCOrderRtnField_2_OrderStatus(pOrder); diff --git a/QuantBox_XSpeed_Trade/TraderApi.h b/QuantBox_XSpeed_Trade/TraderApi.h index 7dcab53..d5aaebb 100644 --- a/QuantBox_XSpeed_Trade/TraderApi.h +++ b/QuantBox_XSpeed_Trade/TraderApi.h @@ -118,7 +118,7 @@ class CTraderApi : //void ReqSettlementInfoConfirm(); //Ƿ - bool IsErrorRspInfo_Output(struct DFITCErrorRtnField *pRspInfo);//Ϣ͵Ϣ + bool IsErrorRspInfo_Output(const char* szSource, struct DFITCErrorRtnField *pRspInfo);//Ϣ͵Ϣ bool IsErrorRspInfo(struct DFITCErrorRtnField *pRspInfo); //Ϣ // diff --git a/QuantBox_XSpeed_Trade/main.cpp b/QuantBox_XSpeed_Trade/main.cpp index 544585c..e2b8bf4 100644 --- a/QuantBox_XSpeed_Trade/main.cpp +++ b/QuantBox_XSpeed_Trade/main.cpp @@ -15,7 +15,7 @@ void* __stdcall XRequest(char type, void* pApi1, void* pApi2, double double1, do switch (rt) { case GetApiType: - return (void*)(ApiType::Trade | ApiType::QuoteRequest | ApiType::Instrument); + return (void*)(ApiType::Trade | ApiType::QuoteRequest | ApiType::Instrument | ApiType::Query_); case GetApiVersion: return (void*)"0.3.0.20150407"; case GetApiName: diff --git a/clear.bat b/clear.bat index cf25d4a..17e57de 100644 --- a/clear.bat +++ b/clear.bat @@ -28,6 +28,7 @@ rd QuantBox_XSpeedStock_Quote\Debug /S /Q rd QuantBox_XSpeedStock_Trade\Debug /S /Q rd QuantBox_ZeroMQ_Quote\Debug /S /Q rd QuantBox_TongShi_Quote\Debug /S /Q +rd QuantBox_Tdx_Trade\Debug /S /Q rd QuantBox_CTP_Quote\Debug64 /S /Q rd QuantBox_CTP_Trade\Debug64 /S /Q diff --git a/csharp/QuantBox.XAPI/Enum.cs b/csharp/QuantBox.XAPI/Enum.cs index 5dbb74d..6334ff0 100644 --- a/csharp/QuantBox.XAPI/Enum.cs +++ b/csharp/QuantBox.XAPI/Enum.cs @@ -94,6 +94,7 @@ public enum ApiType : byte QuoteRequest = 8, HistoricalData = 16, Instrument = 32, + Query = 64, }; public enum DepthLevelType : byte @@ -175,7 +176,9 @@ public enum PositionSide : byte public enum ExecType : byte { ExecNew, + ExecStopped, ExecRejected, + ExecExpired, ExecTrade, ExecPendingCancel, ExecCancelled, diff --git a/csharp/QuantBox.XAPI/Event/XApiWrapper.cs b/csharp/QuantBox.XAPI/Event/XApiWrapper.cs index df360b3..7e342a1 100644 --- a/csharp/QuantBox.XAPI/Event/XApiWrapper.cs +++ b/csharp/QuantBox.XAPI/Event/XApiWrapper.cs @@ -55,6 +55,8 @@ public XApiWrapper():base() base.OnRspQryHistoricalTicks = OnRspQryHistoricalTicks_callback; base.OnRspQryHistoricalBars = OnRspQryHistoricalBars_callback; + + base.OnRspQryInvestor = OnRspQryInvestor_callback; } public void Show() diff --git a/csharp/QuantBox.XAPI/Extensions.cs b/csharp/QuantBox.XAPI/Extensions.cs index 34f9f8b..b6852e3 100644 --- a/csharp/QuantBox.XAPI/Extensions.cs +++ b/csharp/QuantBox.XAPI/Extensions.cs @@ -39,6 +39,11 @@ public static string ErrorMsg([In]this ErrorField field) return PInvokeUtility.GetUnicodeString(field.ErrorMsg); } + public static string Source([In]this ErrorField field) + { + return PInvokeUtility.GetUnicodeString(field.Source); + } + public static string InvestorName([In]this InvestorField field) { return PInvokeUtility.GetUnicodeString(field.InvestorName); @@ -137,18 +142,18 @@ public static class Extensions_Output { public static string ToFormattedString([In]this ErrorField field) { - return string.Format("[ErrorID={0},ErrorMsg={1}]", - field.ErrorID, field.ErrorMsg()); + return string.Format("[ErrorID={0};ErrorMsg={1};Source={2}]", + field.ErrorID, field.ErrorMsg(), field.Source()); } public static string ToFormattedString([In]this OrderField field) { - return string.Format("[InstrumentID={0};ExchangeID={1};Side={2};Qty={3};Price={4};OpenClose={5};HedgeFlag={6};" - + "ID={7};OrderID={8};Time={9};" - + "Type={10};TimeInForce={11};Status={12};ExecType={13};" - + "ErrorID={14};Text={15}]", - field.InstrumentID, field.ExchangeID, Enum.ToString(field.Side), field.Qty, field.Price, Enum.ToString(field.OpenClose), Enum.ToString(field.HedgeFlag), - field.ID, field.OrderID, field.Time, + return string.Format("[InstrumentID={0};ExchangeID={1};Side={2};Qty={3};LeavesQty={4};Price={5};OpenClose={6};HedgeFlag={7};" + + "LocalID={8};ID={9};OrderID={10};Date={11};Time={12};" + + "Type={13};TimeInForce={14};Status={15};ExecType={16};" + + "ErrorID={17};Text={18}]", + field.InstrumentID, field.ExchangeID, Enum.ToString(field.Side), field.Qty,field.LeavesQty, field.Price, Enum.ToString(field.OpenClose), Enum.ToString(field.HedgeFlag), + field.LocalID, field.ID, field.OrderID, field.Date, field.Time, Enum.ToString(field.Type), Enum.ToString(field.TimeInForce), Enum.ToString(field.Status), Enum.ToString(field.ExecType), field.ErrorID, field.Text()); } @@ -157,23 +162,23 @@ public static string ToFormattedString([In]this TradeField field) { return string.Format("[InstrumentID={0};ExchangeID={1};Side={2};Qty={3};Price={4};OpenClose={5};HedgeFlag={6};" + "ID={7};TradeID={8};" - + "Time={9};Commission={10}]", + + "Date={9};Time={10};Commission={11}]", field.InstrumentID, field.ExchangeID, Enum.ToString(field.Side), field.Qty, field.Price, Enum.ToString(field.OpenClose), Enum.ToString(field.HedgeFlag), field.ID, field.TradeID, - field.Time, field.Commission); + field.Date, field.Time, field.Commission); } public static string ToFormattedString([In]this QuoteField field) { return string.Format("[InstrumentID={0};ExchangeID={1};" + "AskPrice={2};AskQty={3};BidPrice={4};BidQty={5};" - + "ID={6};AskOrderID={7};BidOrderID={8};" - + "Status={9};ExecType={10};" - + "ErrorID={11};Text={12};" - + "AskOpenClose={13};AskHedgeFlag={14};BidOpenClose={15};BidHedgeFlag={16}]", + + "LocalID={6};ID={7};AskOrderID={8};BidOrderID={9};" + + "Status={10};ExecType={11};" + + "ErrorID={12};Text={13};" + + "AskOpenClose={14};AskHedgeFlag={15};BidOpenClose={16};BidHedgeFlag={17}]", field.InstrumentID, field.ExchangeID, field.AskPrice, field.AskQty, field.BidPrice, field.BidQty, - field.ID,field.AskOrderID,field.BidOrderID, + field.LocalID,field.ID,field.AskOrderID,field.BidOrderID, Enum.ToString(field.Status), Enum.ToString(field.ExecType), field.ErrorID, field.Text(), Enum.ToString(field.AskOpenClose), Enum.ToString(field.AskHedgeFlag), Enum.ToString(field.BidOpenClose), Enum.ToString(field.BidHedgeFlag)); diff --git a/csharp/QuantBox.XAPI/Program.cs b/csharp/QuantBox.XAPI/Program.cs index 342ae2b..591b793 100644 --- a/csharp/QuantBox.XAPI/Program.cs +++ b/csharp/QuantBox.XAPI/Program.cs @@ -90,7 +90,7 @@ static void Main(string[] args) { //for (int i = 0; i < 10000; ++i) { - test_TongShi_Main(args); + test_Tdx_Main(args); } Console.ReadKey(); } @@ -286,5 +286,32 @@ static void test_KingstarGold_Main(string[] args) Console.ReadKey(); } + + static void test_Tdx_Main(string[] args) + { + api = new XApi(@"C:\Program Files\SmartQuant Ltd\OpenQuant 2014\XAPI\Tdx\x86\QuantBox_Tdx_Trade.dll"); + + api.Server.BrokerID = ""; + api.Server.Address = @"D:\new_hbzq_qq\Login.lua"; + api.Server.ExtendInformation = @"D:\new_hbzq_qq\"; + + api.User.UserID = "05000000000"; + api.User.Password = "123456"; + + api.OnConnectionStatus = OnConnectionStatus; + api.OnRtnDepthMarketData = OnRtnDepthMarketData; + + api.Connect(); + + Console.ReadKey(); + + Console.ReadKey(); + + api.Dispose(); + + Console.ReadKey(); + + Console.ReadKey(); + } } } diff --git a/csharp/QuantBox.XAPI/Properties/AssemblyInfo.cs b/csharp/QuantBox.XAPI/Properties/AssemblyInfo.cs index 1dbf844..bb86af5 100644 --- a/csharp/QuantBox.XAPI/Properties/AssemblyInfo.cs +++ b/csharp/QuantBox.XAPI/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.2.0.2")] -[assembly: AssemblyFileVersion("1.2.0.2")] +[assembly: AssemblyVersion("1.3.0.0")] +[assembly: AssemblyFileVersion("1.3.0.0")] diff --git a/csharp/QuantBox.XAPI/Struct.cs b/csharp/QuantBox.XAPI/Struct.cs index 1c5e789..d5500c2 100644 --- a/csharp/QuantBox.XAPI/Struct.cs +++ b/csharp/QuantBox.XAPI/Struct.cs @@ -10,7 +10,7 @@ namespace QuantBox.XAPI /// /// 用户信息 /// - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] public struct UserInfoField { /// @@ -23,12 +23,17 @@ public struct UserInfoField /// [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 41)] public string Password; + /// + /// 扩展信息,通达信中用来做通讯密码 + /// + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] + public string ExtInfo; } /// /// 用户信息 /// - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] public struct ServerInfoField { /// @@ -86,7 +91,7 @@ public struct ServerInfoField /// /// 深度行情 /// - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] public struct ErrorField { /// @@ -94,6 +99,11 @@ public struct ErrorField /// public int ErrorID; /// + /// 信息来源 + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] + public byte[] Source; + /// /// 错误信息 /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)] @@ -103,7 +113,7 @@ public struct ErrorField /// /// 登录回报 /// - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] public struct RspUserLoginField { /// @@ -135,184 +145,10 @@ public struct RspUserLoginField public byte[] InvestorName; } - ///// - ///// 深度行情 - ///// - //[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] - //public struct DepthMarketDataField - //{ - // public int TradingDay; - // public int ActionDay; - // public int UpdateTime; - // public int UpdateMillisec; - - // /// - // /// 最新价 - // /// - // public double LastPrice; - // /// - // /// 数量 - // /// - // public double Volume; - // /// - // /// 成交金额 - // /// - // public double Turnover; - // /// - // /// 持仓量 - // /// - // public double OpenInterest; - // /// - // /// 当日均价 - // /// - // public double AveragePrice; - - - // /// - // /// 今开盘 - // /// - // public double OpenPrice; - // /// - // /// 最高价 - // /// - // public double HighestPrice; - // /// - // /// 最低价 - // /// - // public double LowestPrice; - // /// - // /// 今收盘 - // /// - // public double ClosePrice; - // /// - // /// 本次结算价 - // /// - // public double SettlementPrice; - - // /// - // /// 涨停板价 - // /// - // public double UpperLimitPrice; - // /// - // /// 跌停板价 - // /// - // public double LowerLimitPrice; - // /// - // /// 昨收盘 - // /// - // public double PreClosePrice; - // /// - // /// 上次结算价 - // /// - // public double PreSettlementPrice; - // /// - // /// 昨持仓量 - // /// - // public double PreOpenInterest; - - // /// - // /// 申买价一 - // /// - // public double BidPrice1; - // /// - // /// 申买量一 - // /// - // public int BidVolume1; - // /// - // /// 申卖价一 - // /// - // public double AskPrice1; - // /// - // /// 申卖量一 - // /// - // public int AskVolume1; - // /// - // /// 申买价二 - // /// - // public double BidPrice2; - // /// - // /// 申买量二 - // /// - // public int BidVolume2; - // /// - // /// 申卖价二 - // /// - // public double AskPrice2; - // /// - // /// 申卖量二 - // /// - // public int AskVolume2; - // /// - // /// 申买价三 - // /// - // public double BidPrice3; - // /// - // /// 申买量三 - // /// - // public int BidVolume3; - // /// - // /// 申卖价三 - // /// - // public double AskPrice3; - // /// - // /// 申卖量三 - // /// - // public int AskVolume3; - // /// - // /// 申买价四 - // /// - // public double BidPrice4; - // /// - // /// 申买量四 - // /// - // public int BidVolume4; - // /// - // /// 申卖价四 - // /// - // public double AskPrice4; - // /// - // /// 申卖量四 - // /// - // public int AskVolume4; - // /// - // /// 申买价五 - // /// - // public double BidPrice5; - // /// - // /// 申买量五 - // /// - // public int BidVolume5; - // /// - // /// 申卖价五 - // /// - // public double AskPrice5; - // /// - // /// 申卖量五 - // /// - // public int AskVolume5; - - // /// - // /// 交易所代码 - // /// - // public ExchangeType Exchange; - - // /// - // /// 合约代码 - // /// - // [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] - // public string Symbol; - // /// - // /// 合约代码 - // /// - // [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 31)] - // public string InstrumentID; - - //} - /// /// 深度行情N档 /// - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] public struct DepthMarketDataNField { ///占用总字节大小 @@ -411,7 +247,7 @@ public struct DepthMarketDataNField /// /// DepthField行情 /// - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] public struct DepthField { public double Price; @@ -422,7 +258,7 @@ public struct DepthField /// /// Tick行情 /// - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] public struct TickField { public int Date; @@ -441,7 +277,7 @@ public struct TickField /// /// Bar行情 /// - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] public struct BarField { public int Date; @@ -459,7 +295,7 @@ public struct BarField /// /// 发给做市商的询价请求 /// - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] public struct QuoteRequestField { /// @@ -498,7 +334,7 @@ public struct QuoteRequestField /// /// 合约信息 /// - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] public struct InstrumentField { /// @@ -561,7 +397,7 @@ public struct InstrumentField /// /// 账号 /// - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] public struct AccountField { [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] @@ -635,7 +471,7 @@ public struct AccountField /// /// 账号 /// - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] public struct SettlementInfoField { /// @@ -652,7 +488,7 @@ public struct SettlementInfoField /// /// 订单信息 /// - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] public struct QuoteField { public double AskQty; @@ -687,6 +523,8 @@ public struct QuoteField [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] public string QuoteReqID; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] + public string LocalID; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] public string ID; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] @@ -707,7 +545,7 @@ public struct QuoteField /// /// 订单信息 /// - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] public struct OrderField { /// @@ -734,6 +572,7 @@ public struct OrderField /// 错误代码 /// public int ErrorID; + public int Date; public int Time; /// @@ -753,17 +592,20 @@ public struct OrderField [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)] public byte[] Text; - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] - public string ID; - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] - public string OrderID; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] public string ClientID; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] public string Account; + + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] + public string LocalID; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] + public string ID; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] + public string OrderID; } - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] public struct OrderIDType { [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] @@ -773,7 +615,7 @@ public struct OrderIDType /// /// 订单信息 /// - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] public struct TradeField { /// @@ -785,6 +627,7 @@ public struct TradeField public OpenCloseType OpenClose; public HedgeFlagType HedgeFlag; public double Commission; + public int Date; public int Time; /// /// 合约代码 @@ -802,7 +645,7 @@ public struct TradeField public string TradeID; } - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] public struct PositionField { /// @@ -833,7 +676,7 @@ public struct PositionField /// /// 投资者 /// - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] public struct InvestorField { public IdCardType IdentifiedCardType; @@ -850,7 +693,7 @@ public struct InvestorField /// /// 合约信息 /// - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] public struct HistoricalDataRequestField { public int Date1; @@ -883,7 +726,7 @@ public struct HistoricalDataRequestField public string ExchangeID; } - + [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)] public class DepthMarketDataNClass { public int TradingDay; diff --git a/include/ApiDataType.h b/include/ApiDataType.h index acf590e..f16b46f 100644 --- a/include/ApiDataType.h +++ b/include/ApiDataType.h @@ -1,156 +1,166 @@ -#ifndef _API_DATA_TYPE_H_ +#ifndef _API_DATA_TYPE_H_ #define _API_DATA_TYPE_H_ ///////////////////////////////////////////////////////////////////////// -///ErrorIDTypeһ +///ErrorIDType是一个错误代码类型 ///////////////////////////////////////////////////////////////////////// typedef int ErrorIDType; ///////////////////////////////////////////////////////////////////////// -///ErrorMsgTypeһϢ +///ErrorMsgType是一个错误信息类型 ///////////////////////////////////////////////////////////////////////// typedef char ErrorMsgType[256]; ///////////////////////////////////////////////////////////////////////// -///PriceTypeһ۸ +///PriceType是一个价格类型 ///////////////////////////////////////////////////////////////////////// typedef double PriceType; ///////////////////////////////////////////////////////////////////////// -///VolumeTypeһ +///VolumeType是一个交易量类型 ///////////////////////////////////////////////////////////////////////// typedef int VolumeType; ///////////////////////////////////////////////////////////////////////// -///QtyTypeһ +///QtyType是一个交易量类型 ///////////////////////////////////////////////////////////////////////// typedef double QtyType; ///////////////////////////////////////////////////////////////////////// -///LargeVolumeTypeһ +///LargeVolumeType是一个大额数量类型 ///////////////////////////////////////////////////////////////////////// typedef double LargeVolumeType; ///////////////////////////////////////////////////////////////////////// -///InstrumentIDTypeһԼ +///InstrumentIDType是一个合约代码类型 ///////////////////////////////////////////////////////////////////////// typedef char InstrumentIDType[31]; ///////////////////////////////////////////////////////////////////////// -///SymbolTypeһԼΨһ +///SymbolType是一个合约唯一符号类型 ///////////////////////////////////////////////////////////////////////// typedef char SymbolType[64]; ///////////////////////////////////////////////////////////////////////// -///DateTimeTypeһʱ +///DateTimeType是一个日期时间类型 ///////////////////////////////////////////////////////////////////////// typedef char DateTimeType[32]; ///////////////////////////////////////////////////////////////////////// -///ExchangeIDTypeһ +///ExchangeIDType是一个交易所代码类型 ///////////////////////////////////////////////////////////////////////// typedef char ExchangeIDType[9]; ///////////////////////////////////////////////////////////////////////// -///MoneyTypeһʽ +///MoneyType是一个资金类型 ///////////////////////////////////////////////////////////////////////// typedef double MoneyType; ///////////////////////////////////////////////////////////////////////// -///DateTypeһ +///DateType是一个日期类型 ///////////////////////////////////////////////////////////////////////// typedef char DateType[9]; typedef int DateIntType; ///////////////////////////////////////////////////////////////////////// -///TimeTypeһʱ +///TimeType是一个时间类型 ///////////////////////////////////////////////////////////////////////// typedef char TimeType[9]; typedef int TimeIntType; ///////////////////////////////////////////////////////////////////////// -///UserIDTypeһû +///UserIDType是一个用户代码类型 ///////////////////////////////////////////////////////////////////////// typedef char UserIDType[32]; typedef char AccountIDType[32]; ///////////////////////////////////////////////////////////////////////// -///TFtdcPasswordTypeһ +///PasswordType是一个密码类型 ///////////////////////////////////////////////////////////////////////// typedef char PasswordType[41]; ///////////////////////////////////////////////////////////////////////// -/// PartyNameTypeһ +/// PartyNameType是一个参与人名称类型 ///////////////////////////////////////////////////////////////////////// typedef char PartyNameType[81]; ///////////////////////////////////////////////////////////////////////// -/// IdentifiedCardNoTypeһ֤ +/// IdentifiedCardNoType是一个证件号码类型 ///////////////////////////////////////////////////////////////////////// typedef char IdentifiedCardNoType[51]; ///////////////////////////////////////////////////////////////////////// -///ProductInfoTypeһƷϢ +///ProductInfoType是一个产品信息类型 ///////////////////////////////////////////////////////////////////////// typedef char ProductInfoType[11]; ///////////////////////////////////////////////////////////////////////// -///BrokerIDTypeһ͹˾ +///BrokerIDType是一个经纪公司代码类型 ///////////////////////////////////////////////////////////////////////// typedef char BrokerIDType[11]; ///////////////////////////////////////////////////////////////////////// -///AuthCodeTypeһͻ֤ +///AuthCodeType是一个客户端认证码类型 ///////////////////////////////////////////////////////////////////////// typedef char AuthCodeType[17]; ///////////////////////////////////////////////////////////////////////// -///AddressTypeһַ +///AddressType是一个地址类型 ///////////////////////////////////////////////////////////////////////// typedef char AddressType[512]; ///////////////////////////////////////////////////////////////////////// -///ExtendInformationTypeһչϢ +///ExtendInformationType是一个扩展信息类型 ///////////////////////////////////////////////////////////////////////// typedef char ExtendInformationType[128]; ///////////////////////////////////////////////////////////////////////// -///VolumeMultipleTypeһԼ +///VolumeMultipleType是一个合约数量乘数类型 ///////////////////////////////////////////////////////////////////////// typedef int VolumeMultipleType; ///////////////////////////////////////////////////////////////////////// -///InstrumentNameTypeһԼ +///InstrumentNameType是一个合约名称类型 ///////////////////////////////////////////////////////////////////////// typedef char InstrumentNameType[64]; ///////////////////////////////////////////////////////////////////////// -///ContentTypeһϢ +///ContentType是一个消息正文类型 ///////////////////////////////////////////////////////////////////////// typedef char ContentType[501]; ///////////////////////////////////////////////////////////////////////// -///SessionIDTypeһỰ +///SessionIDType是一个会话编号类型 ///////////////////////////////////////////////////////////////////////// typedef char SessionIDType[32]; ///////////////////////////////////////////////////////////////////////// -///OrderIDTypeһΨһ +///OrderIDType是一个订单唯一编号类型 ///////////////////////////////////////////////////////////////////////// typedef char OrderIDType[64]; ///////////////////////////////////////////////////////////////////////// -///TradeIDTypeһɽ +///TradeIDType是一个成交编号类型 ///////////////////////////////////////////////////////////////////////// typedef char TradeIDType[64]; ///////////////////////////////////////////////////////////////////////// -///PositionIDTypeһֱֲ +///PositionIDType是一个持仓编号类型 ///////////////////////////////////////////////////////////////////////// typedef char PositionIDType[64]; ///////////////////////////////////////////////////////////////////////// -///BarSizeTypeһBarSize +///SourceType是一个消息来源类型 +///////////////////////////////////////////////////////////////////////// +typedef char SourceType[64]; + +///////////////////////////////////////////////////////////////////////// +///ExtInfoType是一个密码类型 +///////////////////////////////////////////////////////////////////////// +typedef char ExtInfoType[64]; + +///////////////////////////////////////////////////////////////////////// +///BarSizeType是一个BarSize类型 ///////////////////////////////////////////////////////////////////////// typedef long BarSizeType; diff --git a/include/ApiEnum.h b/include/ApiEnum.h index ed01333..d19d6b3 100644 --- a/include/ApiEnum.h +++ b/include/ApiEnum.h @@ -29,6 +29,7 @@ enum ApiType :char QuoteRequest = 8, HistoricalData = 16, Instrument = 32, + Query_ = 64, }; enum DepthLevelType:char @@ -112,7 +113,9 @@ enum PositionSide :char enum ExecType : char { ExecNew, + ExecStopped, ExecRejected, + ExecExpired, ExecTrade, ExecPendingCancel, ExecCancelled, @@ -222,7 +225,7 @@ enum ExchangeType :char CFFEX, // 中金所 INE, // 能源中心 SSE, // 上交所 - SZE, // 深交所 + SZSE, // 深交所 NEEQ, // 全国中小企业股份转让系统,三板,临时这么写 HKEx, }; diff --git a/include/ApiProcess.cpp b/include/ApiProcess.cpp index d901c74..b203315 100644 --- a/include/ApiProcess.cpp +++ b/include/ApiProcess.cpp @@ -73,8 +73,8 @@ char* ExchangeType_2_String(ExchangeType exchange) return "INE"; case SSE: return "SSE"; - case SZE: - return "SZE"; + case SZSE: + return "SZSE"; case NEEQ: return "NEEQ"; case HKEx: diff --git a/include/ApiStruct.h b/include/ApiStruct.h index b8d8f83..1d6f299 100644 --- a/include/ApiStruct.h +++ b/include/ApiStruct.h @@ -4,6 +4,7 @@ #include "ApiDataType.h" #include "ApiEnum.h" +#pragma pack(push,1) struct PositionField { @@ -44,6 +45,7 @@ struct QuoteField ///询价编号 OrderIDType QuoteReqID; + OrderIDType LocalID; OrderIDType ID; OrderIDType AskID; OrderIDType BidID; @@ -55,7 +57,6 @@ struct QuoteField struct OrderField { - OrderType Type; OrderSide Side; QtyType Qty; @@ -72,15 +73,25 @@ struct OrderField QtyType CumQty; PriceType AvgPx; ErrorIDType ErrorID; + DateIntType Date; TimeIntType Time; InstrumentIDType InstrumentID; ExchangeIDType ExchangeID; ErrorMsgType Text; - OrderIDType ID; - OrderIDType OrderID; UserIDType ClientID; AccountIDType Account; + + ////////////////////////////////////////////////////////////////////////// + // 20151021 此处做了大调整,主要是因为股票接口无法立即得到ID,只能从回报是获得 + // 所以为了实现异步只能先生成一个ID,然后做映射 + + // 本地ID,可能在重启后发生变化 + OrderIDType LocalID; + // 系统ID,其实是柜台ID,唯一 + OrderIDType ID; + // 交易所生成的ID,此字段可供比较报单先后。不同交易所可能出现一样的ID + OrderIDType OrderID; }; struct TradeField @@ -91,12 +102,13 @@ struct TradeField OpenCloseType OpenClose; HedgeFlagType HedgeFlag; MoneyType Commission; + DateIntType Date; TimeIntType Time; InstrumentIDType InstrumentID; ExchangeIDType ExchangeID; - OrderIDType ID; + // 交易所产生的成交ID,可用于判断自成交 TradeIDType TradeID; }; @@ -129,6 +141,8 @@ struct UserInfoField UserIDType UserID; ///密码 PasswordType Password; + ///扩展信息,通达信中用来做通讯密码 + ExtInfoType ExtInfo; }; @@ -137,6 +151,8 @@ struct ErrorField { // 错误代码 ErrorIDType ErrorID; + // 消息来源 + SourceType Source; // 错误信息 ErrorMsgType ErrorMsg; }; @@ -498,4 +514,6 @@ struct HistoricalDataRequestField ExchangeIDType ExchangeID; }; +#pragma pack(pop)//恢复对齐状态 + #endif diff --git a/include/IDGenerator.cpp b/include/IDGenerator.cpp new file mode 100644 index 0000000..c672cca --- /dev/null +++ b/include/IDGenerator.cpp @@ -0,0 +1,29 @@ +#include "stdafx.h" +#include "IDGenerator.h" + +CIDGenerator::CIDGenerator() +{ + m_id = 0; + memset(m_IDString, 0, sizeof(OrderIDType)); + memset(m_Prefix, 0, sizeof(OrderIDType)); +} + +CIDGenerator::~CIDGenerator() +{ +} + +void CIDGenerator::SetPrefix(const char* prefix) +{ + strncpy(m_Prefix, prefix, 32); +} + +long CIDGenerator::GetID() +{ + return m_id++; +} + +const char* CIDGenerator::GetIDString() +{ + sprintf(m_IDString, "%s:%d", m_Prefix, m_id++); + return m_IDString; +} \ No newline at end of file diff --git a/include/IDGenerator.h b/include/IDGenerator.h new file mode 100644 index 0000000..430f955 --- /dev/null +++ b/include/IDGenerator.h @@ -0,0 +1,25 @@ +#pragma once + +#include + +#include "ApiStruct.h" + +using namespace std; + +class CIDGenerator +{ +public: + CIDGenerator(); + ~CIDGenerator(); + + // ̫ˣҪԶضϣĿǰƻܳ32 + void SetPrefix(const char* prefix); + + const char* GetIDString(); + long GetID(); +private: + atomic m_id; + OrderIDType m_IDString; + OrderIDType m_Prefix; +}; + diff --git a/include/LTS_v2/SecurityFtdcUserApiDataType.h b/include/LTS_v2/SecurityFtdcUserApiDataType.h index 2e0aff3..f2fa12a 100644 --- a/include/LTS_v2/SecurityFtdcUserApiDataType.h +++ b/include/LTS_v2/SecurityFtdcUserApiDataType.h @@ -688,6 +688,16 @@ typedef char TSecurityFtdcAllWithoutTradeType; typedef char TSecurityFtdcHandlePositionAlgoIDType; +///////////////////////////////////////////////////////////////////////// +///TFtdcOpenRestrictTypeTypeһȨ +///////////////////////////////////////////////////////////////////////// +///뿪 +#define SECURITY_FTDC_ORT_BuyOpen '0' +///п +#define SECURITY_FTDC_ORT_AllOpen '1' + +typedef char TSecurityFtdcOpenRestrictTypeType; + ///////////////////////////////////////////////////////////////////////// ///TFtdcTradeParamIDTypeһϵͳ ///////////////////////////////////////////////////////////////////////// @@ -709,6 +719,10 @@ typedef char TSecurityFtdcHandlePositionAlgoIDType; #define SECURITY_FTDC_TPID_DeriveWithdrawRatio 'D' ///ȨȨʼʱ #define SECURITY_FTDC_TPID_ExecuteStartTime 'T' +///ֻɳʷȯծ +#define SECURITY_FTDC_TPID_OnlyRepayHisStock 'H' +///Ȩ +#define SECURITY_FTDC_TPID_OpenRestrictType 'X' typedef char TSecurityFtdcTradeParamIDType; @@ -742,6 +756,11 @@ typedef char TSecurityFtdcMarketIDType[31]; ///////////////////////////////////////////////////////////////////////// typedef char TSecurityFtdcMacAddressType[21]; +///////////////////////////////////////////////////////////////////////// +///TFtdcHDSerialNumberTypeһӲк +///////////////////////////////////////////////////////////////////////// +typedef char TSecurityFtdcHDSerialNumberType[21]; + ///////////////////////////////////////////////////////////////////////// ///TFtdcInstrumentNameTypeһԼ ///////////////////////////////////////////////////////////////////////// @@ -2101,7 +2120,7 @@ typedef char TSecurityFtdcCloseDirectionType; ///;֤ȯ #define SECURITY_FTDC_DT_UnavailStock '2' ///;ʽ -#define SECURITY_FTDC_DT_UnavailRedMoney '2' +#define SECURITY_FTDC_DT_UnavailRedMoney '3' typedef char TSecurityFtdcDelivTypeType; @@ -2145,4 +2164,36 @@ typedef char TSecurityFtdcFundClassType; typedef char TSecurityFtdcTradingPhaseType; +///////////////////////////////////////////////////////////////////////// +///TFtdcOpenRestrictionTypeһ +///////////////////////////////////////////////////////////////////////// +///޿ +#define SECURITY_FTDC_OR_None '0' +///Ʊҿ +#define SECURITY_FTDC_OR_NoCoverOpen '1' +/// +#define SECURITY_FTDC_OR_NoSellOpen '2' +///֡ҿ +#define SECURITY_FTDC_OR_NoSellAndCoverOpen '3' +///뿪 +#define SECURITY_FTDC_OR_NoBuyOpen '4' +///뿪֡ҿ +#define SECURITY_FTDC_OR_NoBuyAndCoverOpen '5' +///뿪֡ +#define SECURITY_FTDC_OR_NoBuyAndSellOpen '6' +///뿪֡֡ҿ +#define SECURITY_FTDC_OR_NoBuySellAndCoverOpen '7' + +typedef char TSecurityFtdcOpenRestrictionType; + +///////////////////////////////////////////////////////////////////////// +///TFtdcOfferTypeTypeһ +///////////////////////////////////////////////////////////////////////// +///ͨ +#define SECURITY_FTDC_OT_Normal '0' +///Ȩ +#define SECURITY_FTDC_OT_Options '1' + +typedef char TSecurityFtdcOfferTypeType; + #endif diff --git a/include/LTS_v2/SecurityFtdcUserApiStruct.h b/include/LTS_v2/SecurityFtdcUserApiStruct.h index 7cefb67..5d345f3 100644 --- a/include/LTS_v2/SecurityFtdcUserApiStruct.h +++ b/include/LTS_v2/SecurityFtdcUserApiStruct.h @@ -418,6 +418,8 @@ struct CSecurityFtdcDepthMarketDataField TSecurityFtdcPriceType PreIOPV; ///ֵ TSecurityFtdcPriceType IOPV; + ///̬ο۸ + TSecurityFtdcPriceType AuctionPrice; ///޸ʱ TSecurityFtdcTimeType UpdateTime; ///޸ĺ @@ -468,6 +470,8 @@ struct CSecurityFtdcDepthMarketDataField TSecurityFtdcDateType ActionDay; ///׽׶ TSecurityFtdcTradingPhaseType TradingPhase; + /// + TSecurityFtdcOpenRestrictionType OpenRestriction; }; ///ͶߺԼȨ @@ -751,18 +755,18 @@ struct CSecurityFtdcInvestorOptionsPositionField TSecurityFtdcInstrumentIDType InstrumentID; ///ͷλ TSecurityFtdcLargeVolumeType MaxLongPositionLimit; - /// - TSecurityFtdcLargeVolumeType MaxBuyVolLimit; + ///󿪲 + TSecurityFtdcLargeVolumeType MaxOpenVolLimit; ///ܲλ TSecurityFtdcLargeVolumeType MaxPositionLimit; ///ͷֲ TSecurityFtdcLargeVolumeType LongPosition; ///ͷֲ TSecurityFtdcLargeVolumeType ShortPosition; - /// - TSecurityFtdcLargeVolumeType BuyVolume; - ///򿪶 - TSecurityFtdcLargeVolumeType BuyFrozenVolume; + ///տ + TSecurityFtdcLargeVolumeType TodayOpenVolume; + ///տֶ + TSecurityFtdcLargeVolumeType TodayOpenFrozenVolume; ///ͷֲ TSecurityFtdcLargeVolumeType LongFrozenPosition; ///ͷֲ @@ -943,6 +947,8 @@ struct CSecurityFtdcTraderOfferField TSecurityFtdcParticipantIDType ParticipantID; /// TSecurityFtdcPasswordType Password; + /// + TSecurityFtdcOfferTypeType OfferType; ///װ TSecurityFtdcInstallIDType InstallID; ///ر @@ -982,6 +988,8 @@ struct CSecurityFtdcMDTraderOfferField TSecurityFtdcParticipantIDType ParticipantID; /// TSecurityFtdcPasswordType Password; + /// + TSecurityFtdcOfferTypeType OfferType; ///װ TSecurityFtdcInstallIDType InstallID; ///ر @@ -1165,7 +1173,7 @@ struct CSecurityFtdcOrderField TSecurityFtdcOrderSysIDType RelativeOrderSysID; ///Ӫҵ TSecurityFtdcBranchIDType BranchID; - ///ɽ + ///ɽ TSecurityFtdcMoneyType TradeAmount; ///ǷETF TSecurityFtdcBoolType IsETF; @@ -2213,6 +2221,8 @@ struct CSecurityFtdcReqUserLoginField TSecurityFtdcAuthCodeType AuthCode; /// TSecurityFtdcAuthCodeType RandCode; + ///Ӳк + TSecurityFtdcHDSerialNumberType HDSerialNumber; }; ///û¼Ӧ @@ -2421,6 +2431,8 @@ struct CSecurityFtdcMarketDataStaticField TSecurityFtdcRatioType CurrDelta; ///ֵ TSecurityFtdcPriceType IOPV; + ///̬ο۸ + TSecurityFtdcPriceType AuctionPrice; }; ///³ɽ @@ -2514,6 +2526,8 @@ struct CSecurityFtdcMarketDataUpdateTimeField TSecurityFtdcDateType ActionDay; ///׽׶ TSecurityFtdcTradingPhaseType TradingPhase; + /// + TSecurityFtdcOpenRestrictionType OpenRestriction; }; ///ɽ diff --git a/include/LTS_v2/linux64/libsecuritymduserapi.so b/include/LTS_v2/linux64/libsecuritymduserapi.so index 89155ee..d5037ed 100644 Binary files a/include/LTS_v2/linux64/libsecuritymduserapi.so and b/include/LTS_v2/linux64/libsecuritymduserapi.so differ diff --git a/include/LTS_v2/linux64/libsecurityqueryapi.so b/include/LTS_v2/linux64/libsecurityqueryapi.so index 51e67bd..2160065 100644 Binary files a/include/LTS_v2/linux64/libsecurityqueryapi.so and b/include/LTS_v2/linux64/libsecurityqueryapi.so differ diff --git a/include/LTS_v2/linux64/libsecuritytraderapi.so b/include/LTS_v2/linux64/libsecuritytraderapi.so index 8452414..ad3c7f9 100644 Binary files a/include/LTS_v2/linux64/libsecuritytraderapi.so and b/include/LTS_v2/linux64/libsecuritytraderapi.so differ diff --git a/include/LTS_v2/version.txt b/include/LTS_v2/version.txt index c8d6440..15e22cd 100644 --- a/include/LTS_v2/version.txt +++ b/include/LTS_v2/version.txt @@ -1 +1 @@ -20150810 \ No newline at end of file +20150925 \ No newline at end of file diff --git a/include/LTS_v2/win32/securitymduserapi.dll b/include/LTS_v2/win32/securitymduserapi.dll index f5b5486..d668463 100644 Binary files a/include/LTS_v2/win32/securitymduserapi.dll and b/include/LTS_v2/win32/securitymduserapi.dll differ diff --git a/include/LTS_v2/win32/securitymduserapi.lib b/include/LTS_v2/win32/securitymduserapi.lib index f11e9ab..a804e45 100644 Binary files a/include/LTS_v2/win32/securitymduserapi.lib and b/include/LTS_v2/win32/securitymduserapi.lib differ diff --git a/include/LTS_v2/win32/securityqueryapi.dll b/include/LTS_v2/win32/securityqueryapi.dll index e4cb199..bd5281c 100644 Binary files a/include/LTS_v2/win32/securityqueryapi.dll and b/include/LTS_v2/win32/securityqueryapi.dll differ diff --git a/include/LTS_v2/win32/securityqueryapi.lib b/include/LTS_v2/win32/securityqueryapi.lib index f730c42..ef5e372 100644 Binary files a/include/LTS_v2/win32/securityqueryapi.lib and b/include/LTS_v2/win32/securityqueryapi.lib differ diff --git a/include/LTS_v2/win32/securitytraderapi.dll b/include/LTS_v2/win32/securitytraderapi.dll index be7d03f..88d7604 100644 Binary files a/include/LTS_v2/win32/securitytraderapi.dll and b/include/LTS_v2/win32/securitytraderapi.dll differ diff --git a/include/LTS_v2/win32/securitytraderapi.lib b/include/LTS_v2/win32/securitytraderapi.lib index 95341cd..9cdddae 100644 Binary files a/include/LTS_v2/win32/securitytraderapi.lib and b/include/LTS_v2/win32/securitytraderapi.lib differ diff --git a/include/QueueStruct.h b/include/QueueStruct.h index 4f877f5..e1d1632 100644 --- a/include/QueueStruct.h +++ b/include/QueueStruct.h @@ -1,6 +1,7 @@ #ifndef _QUEUE_STRUCT_H_ #define _QUEUE_STRUCT_H_ + struct ResponeItem { char type; // (RequestType) @@ -21,4 +22,5 @@ struct ResponeItem bool bNeedDelete; }; + #endif//end of _QUEUE_HEADER_H_ diff --git a/include/Tdx/TdxApi.h b/include/Tdx/TdxApi.h new file mode 100644 index 0000000..b12d158 --- /dev/null +++ b/include/Tdx/TdxApi.h @@ -0,0 +1,69 @@ +#if !defined(_TDX_API_H) +#define _TDX_API_H + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#ifdef TDXAPI_EXPORTS +#define TDXAPI_API __declspec(dllexport) +#else +#define TDXAPI_API __declspec(dllimport) +#endif + +#include "tdx_enum.h" +#include "tdx_struct.h" +#include "tdx_function.h" +#include "tdx_request.h" +#include "tdx_field.h" + +class TDXAPI_API CTdxApi +{ +public: + // 创建API + // TdxPath*:通达信安装目录,需以"\\"结束。 + static CTdxApi* CreateApi(const char* TdxPath); + virtual void Release() = 0; + +public: + virtual void LoadScript(const char* LuaFileOrString, bool bFileOrString, bool bEncrypted) = 0; + + virtual void Init(const char* TdxPath, Error_STRUCT** ppErr) = 0; + virtual void Exit() = 0; + + virtual void* Login(const char* szAccount, const char* szPassword, const char* szCode, char*** pppResults, Error_STRUCT** ppErr) = 0; + virtual void Logout(void* client) = 0; + +public: + // 弹出通达信内部的版本对话框 + virtual void Version() = 0; + + // 下单时必须指定股东代码,所以需要先查询股东列表才能实现下单。下单时会进行授权查询,失败时不会发单出去 + virtual int SendMultiOrders(Order_STRUCT* pOrders, int count, FieldInfo_STRUCT*** pppFieldInfos, char*** pppResults, Error_STRUCT*** pppErrs) = 0; + virtual int SendMultiOrders(Order_STRUCT** ppOrders, int count, FieldInfo_STRUCT*** pppFieldInfos, char*** pppResults, Error_STRUCT*** pppErrs) = 0; + + virtual int CancelMultiOrders(Order_STRUCT* pOrders, int count, FieldInfo_STRUCT*** pppFieldInfos, char*** pppResults, Error_STRUCT*** pppErrs) = 0; + virtual int CancelMultiOrders(Order_STRUCT** ppOrders, int count, FieldInfo_STRUCT*** pppFieldInfos, char*** pppResults, Error_STRUCT*** pppErrs) = 0; + // 发送查询请求 + // 有些请求是当日数据,后面的起始和结束日期自动忽略 + // 对于历史数据,需要查询的区别,格式“yyyyMMdd”,客户端上有60天或90天的时间限制,这里没有,但如果数据太多,间隔设成一周或一月 + // 订阅行情时只需要最后的股票代码 + virtual void* ReqQueryData(int requestType, FieldInfo_STRUCT*** pppFieldInfos, char*** pppResults, Error_STRUCT** ppErr, char * szKSRQ = "", char* szZZRQ = "", char* szZQDM = "") = 0; + +public: + // 设置会话 + virtual void SetClient(void* client) = 0; + + virtual void* GetClient() = 0; + // 设置资金账号 + virtual void SetAccount(const char* szAccount) = 0; + // 得到资金账号 + virtual const char* GetAccount() = 0; + +protected: + CTdxApi(); + ~CTdxApi(){}; +}; + +#endif + diff --git a/include/Tdx/tdx_enum.h b/include/Tdx/tdx_enum.h new file mode 100644 index 0000000..67fa276 --- /dev/null +++ b/include/Tdx/tdx_enum.h @@ -0,0 +1,72 @@ +#pragma once + +#ifndef _TDX_ENUM_H_ +#define _TDX_ENUM_H_ + +#define COL_EACH_ROW (64) //每行多少例,相当重要 + +// 125_帐号类别 + + +// 130_买卖标志 +// 下单时使用买卖标志来指定报单类型 +// 查询时,单子只简单的表示了买卖方向,是否要启用委托类别? +#define MMBZ_Buy_Limit 0 // 限价买 +#define MMBZ_Sell_Limit 1 // 限价卖 +#define MMBZ_Cancel 2 // 撤买/撤卖 +#define MMBZ_3 3 // 融券 +#define MMBZ_Buy_Market 67 // 市价买 +#define MMBZ_Sell_Market 68 // 市价卖 +#define MMBZ_Creation 79 // 基金申购 +#define MMBZ_Redemption 80 // 基金赎回 +#define MMBZ_Merge 12 // 基金合并 +#define MMBZ_Split 13 // 基金分拆 + +// 5565_委托类别 +#define WTLB_MM 0; // 买卖 +#define WTLB_CD 1; // 撤单 + +// 131_委托类别 +// 3|投票 +// 3|融券 +// 0|买入 +// 1|卖出 + +// 166_委托方式 +// 上海只有046,深圳只有012345,所以市价只发4最简单 +// 0 限1,买卖 +// 1 对 +// 2 本 +// 3 剩 撤 +// 4 五 撤 +// 5 全 撤 +// 6 转 +#define WTFS_Limit 0 // 限价,限价委托,买卖 +#define WTFS_Best_Reverse 1 // 对手方最优价格委托,对方最优价格,对手方最优价格委托, +#define WTFS_Best_Forward 2 // 本方最优价格委托,本方最优价格,本方最优价格委托, +#define WTFS_IOC 3 // 即时成交剩余撤销委托,即时成交剩余撤销,即时成交剩余撤销委托, +#define WTFS_Five_IOC 4 // 五档即时成交剩余撤销,五档即成剩撤,最优五档即时成交剩余撤消委托, +#define WTFS_FOK 5 // 全额成交或撤销委托,全额成交或撤销,全额成交或撤销委托, +#define WTFS_Five_Limit 6 // 五档即时成交剩余转限,五档即成转限价,最优五档即时成交剩余转限价委托, + + + +// 281_融资融券标识 +#define RZRQBS_NO 0 // 非融资融券 +#define RZRQBS_YES 1 // 融资融券 + +// 147_状态说明 +#define ZTSM_NotSent 0 // 0-未申报 +#define ZTSM_1 1 // +#define ZTSM_New 2 // 2-已申报未成交,未成交,已报 +#define ZTSM_Illegal 3 // 3-非法委托 +#define ZTSM_4 4 // +#define ZTSM_PartiallyFilled 5 // 5-部分成交 +#define ZTSM_AllFilled 6 // 6-全部成交,已成,全部成交 +#define ZTSM_PartiallyCancelled 7 // 部撤,这是猜的,需要以后修正 +#define ZTSM_AllCancelled 8 // 8-全部撤单,已撤,全部撤单 +#define ZTSM_CancelRejected 9 // 9-撤单未成 只会出现撤单记录中 + +// 已成,部成,废单,已撤,部撤 + +#endif \ No newline at end of file diff --git a/include/Tdx/tdx_field.h b/include/Tdx/tdx_field.h new file mode 100644 index 0000000..9a4bcf5 --- /dev/null +++ b/include/Tdx/tdx_field.h @@ -0,0 +1,158 @@ +#pragma once + +#ifndef _TDX_FIELD_H_ +#define _TDX_FIELD_H_ +/* +下面这张表目前是基于华宝证券个股期权客户端,不知道换券商或升级后是否会不一样 +ID一样,中文名可能不一样 +*/ + +#define FIELD_JYSDM 100 // 100_交易所代码 +#define FIELD_JYSMC 101 // 101_交易所名称 +#define FIELD_WTFS_110 110 // 110_委托方式 +#define FIELD_CZBZ 113 // 113_操作标志 +#define FIELD_ZDJY 116 // 116_指定交易 +#define FIELD_KHH 120 // 120_客户号 +#define FIELD_ZJZH 121 // 121_资金帐号 +#define FIELD_KHMC 122 // 122_客户名称 +#define FIELD_GDDM 123 // 123_股东代码 +#define FIELD_GDMC 124 // 124_股东名称 +#define FIELD_ZHLB 125 // 125_帐号类别 +#define FIELD_KSRQ 126 // 126_开始日期 +#define FIELD_ZZRQ 127 // 127_终止日期 +#define FIELD_MMBZ 130 // 130_买卖标志 +#define FIELD_WTLB 131 // 131_委托类别 华宝仿真显示131_买卖标志,华宝实盘显示131_委托类别 +#define FIELD_BZ 132 // 132_币种 +#define FIELD_JYDW 133 // 133_交易单位 +#define FIELD_JYMM 134 // 134_交易密码 +#define FIELD_ZQDM 140 // 140_证券代码 +#define FIELD_ZQMC 141 // 141_证券名称 +#define FIELD_WTRQ 142 // 142_委托日期 +#define FIELD_WTSJ 143 // 143_委托时间 +#define FIELD_WTSL 144 // 144_委托数量 +#define FIELD_WTJG 145 // 145_委托价格 +#define FIELD_WTBH 146 // 146_委托编号 +#define FIELD_ZTSM 147 // 147_状态说明 +#define FIELD_WTJE 148 // 148_委托金额 +#define FIELD_FHXX 149 // 149_返回信息 +#define FIELD_CJRQ 150 // 150_成交日期 +#define FIELD_CJSJ 151 // 151_成交时间 +#define FIELD_CJSL 152 // 152_成交数量 +#define FIELD_CJJG 153 // 153_成交价格 +#define FIELD_CJBH 155 // 155_成交编号 +#define FIELD_DJSL 160 // 160_冻结数量 +#define FIELD_DJZJ 161 // 161_冻结资金 +#define FIELD_CDSL 162 // 162_撤单数量 +#define FIELD_WTFS 166 // 166_委托方式 +#define FIELD_CDBZ 167 // 167_撤单标志 +#define FIELD_168 168 // ? +#define FIELD_XWDM 173 // 173_席位代码 +#define FIELD_ZXJYGS 187 // 187_最小交易股数 +#define FIELD_BJFS 194 // 194_报价方式 +#define FIELD_ZQSL 200 // 200_证券数量 +#define FIELD_KMSL 201 // 201_可卖数量 +#define FIELD_TBCBJ 202 // 202_摊簿成本价 +#define FIELD_TBFDYK 204 // 204_摊簿浮动盈亏 +#define FIELD_ZXSZ 205 // 205_最新市值 +#define FIELD_YJ 206 // 206_佣金 +#define FIELD_GHF 207 // 207_过户费 +#define FIELD_CJF 208 // 208_成交费 +#define FIELD_JSF 209 // 209_结算费 +#define FIELD_YHS 210 // 210_印花税 +#define FIELD_ZXMRBDJW 226 // 226_最小买入变动价位 +#define FIELD_ZXMCBDJW 227 // 227_最小卖出变动价位 +#define FIELD_CKYKBL 230 // 230_参考盈亏比例(%) +#define FIELD_SXYK 232 // 232_实现盈亏 +#define FIELD_LX 234 // 234_类型 +#define FIELD_ZHZT 238 // 238_帐户状态 +#define FIELD_RZRQBS 281 // 281_融资融券标识 +#define FIELD_FJZH 294 // 294_附加账号 +#define FIELD_ZJYE 300 // 300_资金余额 +#define FIELD_KYZJ 301 // 301_可用资金 +#define FIELD_KQZJ 302 // 302_可取资金 +#define FIELD_FSJE 303 // 303_发生金额 +#define FIELD_SYJE 304 // 304_剩余金额 +#define FIELD_ZY 305 // 305_摘要 +#define FIELD_ZZC_310 310 // 310_总资产 +#define FIELD_FNLX 333 // 333_方案类型 +#define FIELD_ZZC_350 350 // 350_总资产 +#define FIELD_CPDM 391 // 391_产品代码 +#define FIELD_TJRDM 485 // 485_推荐人代码 +#define FIELD_HYDM 510 // 510_合约代码 +#define FIELD_HYMC 511 // 511_合约名称 +#define FIELD_KPBZ 513 // 513_开平标志 +#define FIELD_TBBZ 514 // 514_投保标志 +#define FIELD_JGYF 540 // 540_交割月份 +#define FIELD_BZJ 541 // 541_保证金 +#define FIELD_PCH 606 // 606_批次号 +#define FIELD_FXD 700 // 700_风险度 +#define FIELD_718 718 // ? +#define FIELD_QSXH 1207 // 1207_起始序号 +#define FIELD_BLXX 1213 // 1213_保留信息 +#define FIELD_JCFXBZ 1223 // 1223_检查风险标志 +#define FIELD_BZ_1217 1217 // 1217_备注 +#define FIELD_CS 1227 // 1227_参数 +#define FIELD_XSYS 1231 // 1231_显示颜色 + +#define FIELD_KHQZ 5250 // 5250_客户群组 +#define FIELD_KHYYB 5251 // 5251_客户营业部 +#define FIELD_YPXLH 5252 // 5252_硬盘序列号 +#define FIELD_CPUID 5253 // 5253_CPUID +#define FIELD_XYJYBS 5254 // 5254_信用交易标识 +#define FIELD_HHH 5255 // 5255_会话号 +#define FIELD_KHDM 5256 // 5256_客户代码 + +#define FIELD_WTLB_5565 5565 // 5565_委托类别 +#define FIELD_JSHL 5599 // 5599_结算汇率 + +#define FIELD_JYF 5630 // 5630_交易费 +#define FIELD_DSGF 5638 // 5638_代收规费 +#define FIELD_GYWTBS 5639 // 5639_隔夜委托标识 +#define FIELD_ZZHBH 5673 // 5673_子账户编号 +#define FIELD_JSJG 5674 // 5674_结算机构 +#define FIELD_JSZH 5675 // 5675_结算账号 +#define FIELD_DJRQ 5676 // 5676_登记日期 + +#define FIELD_YMTZH 5925 // 5925_一码通账号 +#define FIELD_MMFX 5935 // 5935_买卖方向 +#define FIELD_BJFS_6027 6027 // 6027_报价方式 + + +#define FIELD_BID_SIZE_1 900 // 900_买一量 +#define FIELD_BID_SIZE_2 901 // 901_买二量 +#define FIELD_BID_SIZE_3 902 // 902_买三量 +#define FIELD_BID_SIZE_4 903 // 903_买四量 +#define FIELD_BID_SIZE_5 904 // 904_买五量 + +#define FIELD_BID_PRICE_1 910 // 910_买一价 +#define FIELD_BID_PRICE_2 911 // 911_买二价 +#define FIELD_BID_PRICE_3 912 // 912_买三价 +#define FIELD_BID_PRICE_4 913 // 913_买四价 +#define FIELD_BID_PRICE_5 914 // 914_买五价 + +#define FIELD_ASK_SIZE_1 920 // 920_卖一量 +#define FIELD_ASK_SIZE_2 921 // 921_卖二量 +#define FIELD_ASK_SIZE_3 922 // 922_卖三量 +#define FIELD_ASK_SIZE_4 923 // 923_卖四量 +#define FIELD_ASK_SIZE_5 924 // 924_卖五量 + +#define FIELD_ASK_PRICE_1 930 // 930_卖一价 +#define FIELD_ASK_PRICE_2 931 // 931_卖二价 +#define FIELD_ASK_PRICE_3 932 // 932_卖三价 +#define FIELD_ASK_PRICE_4 933 // 933_卖四价 +#define FIELD_ASK_PRICE_5 934 // 934_卖五价 + +#define FIELD_ZTJG 940 // 940_涨停价格 +#define FIELD_DTJG 941 // 941_跌停价格 + +#define FIELD_JKJ 945 // 945_今开价 +#define FIELD_ZSJ 946 // 946_昨收价 +#define FIELD_GZLX 948 // 948_国债利息 +#define FIELD_DQJ 949 // 949_当前价 +#define FIELD_QGTHQ 956 // 956_取柜台行情 +#define FIELD_GZBS 958 // 958_国债标识 + + + + +#endif \ No newline at end of file diff --git a/include/Tdx/tdx_function.cpp b/include/Tdx/tdx_function.cpp new file mode 100644 index 0000000..8118292 --- /dev/null +++ b/include/Tdx/tdx_function.cpp @@ -0,0 +1,1283 @@ +#include "stdafx.h" +#include +#include +#include +#include + +#include "tdx_function.h" +#include "tdx_enum.h" +#include "tdx_field.h" +#include "tdx_request.h" + +using namespace std; + +#ifdef TDXAPI_EXPORTS + +/* +注意:以下代码只是几个数据表的读写方式,当做示例使用 +此cpp请不要添加到项目中,而是只添加h文件 +因为由哪里生成的内存块就由哪里删除,由dll生成的内存,由dll中的函数来删 +如果把这个函数编译到exe中,会导致是由外部的exe中函数来删除了,会出错 + +*/ + +void GetUpdateTime_HH_mm_ss(char* UpdateTime, int* _HH, int* _mm, int* _ss) +{ + *_HH = atoi(&UpdateTime[0]); + *_mm = atoi(&UpdateTime[3]); + *_ss = atoi(&UpdateTime[6]); +} + + +void PrintTableHeader(FieldInfo_STRUCT** ppHeader) +{ + if (ppHeader == nullptr) + return; + + int i = 0; + FieldInfo_STRUCT* pRow = ppHeader[i]; + while (pRow != 0) + { + char buf[512] = { 0 }; + printf("%d_%s|",//"%d,%s,%d,%d,%d,%d,%d", + pRow->FieldID, pRow->FieldName, pRow->a, pRow->b, pRow->Len, pRow->d, pRow->e); + + ++i; + pRow = ppHeader[i]; + } + printf("\n"); +} + +void OutputCSVTableHeader(FILE* pFile, FieldInfo_STRUCT** ppHeader) +{ + if (ppHeader == nullptr || pFile == nullptr) + return; + + int i = 0; + FieldInfo_STRUCT* pRow = ppHeader[i]; + while (pRow != 0) + { + char buf[512] = { 0 }; + fprintf(pFile,"%d_%s,",//"%d,%s,%d,%d,%d,%d,%d", + pRow->FieldID, pRow->FieldName, pRow->a, pRow->b, pRow->Len, pRow->d, pRow->e); + + ++i; + pRow = ppHeader[i]; + } + fprintf(pFile, "\n"); +} + +FieldInfo_STRUCT** CopyTableHeader(FieldInfo_STRUCT** ppHeader) +{ + if (ppHeader == nullptr) + return nullptr; + + int count = GetCountTableHeader(ppHeader)+1; + FieldInfo_STRUCT** ppNew = new FieldInfo_STRUCT*[count]; + ppNew[count - 1] = nullptr; + + for (int i = 0; i < count;++i) + { + //ppNew[i] = ppHeader[i]; + ppNew[i] = new FieldInfo_STRUCT; + memcpy(ppNew[i], ppHeader[i], sizeof(FieldInfo_STRUCT)); + } + return ppNew; +} + +void DeleteTableHeader(FieldInfo_STRUCT** ppHeader) +{ + if (ppHeader == nullptr) + return; + + //原有创建方法是一个连续区域,使用时容易出错 + //delete[] ppHeader; + + int i = 0; + while (ppHeader[i] != 0) + { + delete[] ppHeader[i]; + + ++i; + } + + delete[] ppHeader; +} + +int GetIndexByFieldName(FieldInfo_STRUCT** ppHeader, char* FieldName) +{ + if (ppHeader == nullptr) + return -1; + + int i = 0; + FieldInfo_STRUCT* pRow = ppHeader[i]; + while (pRow != 0) + { + if (strcmp(pRow->FieldName,FieldName)==0) + { + return i; + } + + ++i; + pRow = ppHeader[i]; + } + return -1; +} + +int GetIndexByFieldID(FieldInfo_STRUCT** ppHeader, int FieldID) +{ + if (ppHeader == nullptr) + return -1; + + int i = 0; + FieldInfo_STRUCT* pRow = ppHeader[i]; + while (pRow != 0) + { + if (pRow->FieldID == FieldID) + { + return i; + } + + ++i; + pRow = ppHeader[i]; + } + return -1; +} + +int GetCountTableHeader(FieldInfo_STRUCT** ppHeader) +{ + if (ppHeader == nullptr) + return -1; + + int i = 0; + FieldInfo_STRUCT* pRow = ppHeader[i]; + while (pRow != 0) + { + ++i; + pRow = ppHeader[i]; + } + return i; +} + +void PrintTableBody(char** ppTable) +{ + if (ppTable == nullptr) + return; + + // 如果有数据,第一列就不为空 + int i = 0; + int j = 0; + char* p = ppTable[i * COL_EACH_ROW + j]; + while (p != nullptr) + { + printf("%d:",i); + for (j = 0; j < COL_EACH_ROW; ++j) + { + p = ppTable[i * COL_EACH_ROW + j]; + if (p) + { + printf("%s|", p); + } + else + break; + } + printf("\n"); + j = 0; + ++i; + p = ppTable[i * COL_EACH_ROW + j]; + } + + return; +} + +void PrintTableBody(char** ppTable, int count) +{ + if (ppTable == nullptr) + return; + + for (int i = 0; i < count;++i) + { + printf("%d:", i); + for (int j = 0; j < COL_EACH_ROW; ++j) + { + char* p = ppTable[i * COL_EACH_ROW + j]; + if (p) + { + printf("%s|", p); + + } + else + break; + } + printf("\n"); + } + + return; +} + +void OutputCSVTableBody(FILE* pFile, char** ppTable) +{ + if (ppTable == nullptr || pFile == nullptr) + return; + + // 如果有数据,第一列就不为空 + int i = 0; + int j = 0; + char* p = ppTable[i * COL_EACH_ROW + j]; + while (p != nullptr) + { + //printf("%d:", i); + for (j = 0; j < COL_EACH_ROW; ++j) + { + p = ppTable[i * COL_EACH_ROW + j]; + if (p) + { + fprintf(pFile, "%s,", p); + } + else + break; + } + fprintf(pFile, "\n"); + j = 0; + ++i; + p = ppTable[i * COL_EACH_ROW + j]; + } + + return; +} + +void OutputCSVTableBody(FILE* pFile, char** ppTable, int count) +{ + if (ppTable == nullptr || pFile == nullptr) + return; + + for (int i = 0; i < count; ++i) + { + //printf("%d:", i); + for (int j = 0; j < COL_EACH_ROW; ++j) + { + char* p = ppTable[i * COL_EACH_ROW + j]; + if (p) + { + fprintf(pFile, "%s,", p); + + } + else + break; + } + fprintf(pFile, "\n"); + } + + return; +} + +// 得到某一行某一列 +char* GetAtTableBody(char** ppTable, int row, int col) +{ + if (ppTable == nullptr) + return nullptr; + + if (col >= COL_EACH_ROW) + return nullptr; + + if (row >= GetRowCountTableBody(ppTable)) + { + return nullptr; + } + + return ppTable[row * COL_EACH_ROW + col]; +} + +int GetRowCountTableBody(char** ppTable) +{ + if (ppTable == nullptr) + return -1; + + // 如果有数据,第一列就不为空 + int i = 0; + int j = 0; + char* p = ppTable[i * COL_EACH_ROW + j]; + while (p != nullptr) + { + ++i; + p = ppTable[i * COL_EACH_ROW + j]; + } + + return i; +} + +void DeleteTableBody(char** ppTable) +{ + // 要注意的是什么时候停止删除 + if (ppTable == nullptr) + return; + + // 如果有数据,第一列就不为空 + int i = 0; + int j = 0; + char* p = ppTable[i * COL_EACH_ROW + j]; + while (p != nullptr) + { + for (j = 0; j < COL_EACH_ROW; ++j) + { + delete[] ppTable[i * COL_EACH_ROW + j]; + } + j = 0; + ++i; + p = ppTable[i * COL_EACH_ROW + j]; + } + + delete[] ppTable; + + return; +} + +void DeleteTableBody(char** ppTable, int count) +{ + if (ppTable == nullptr) + return; + + for (int i = 0; i < count; ++i) + { + for (int j = 0; j < COL_EACH_ROW; ++j) + { + char* p = ppTable[i * COL_EACH_ROW + j]; + if (p) + { + delete[] ppTable[i * COL_EACH_ROW + j]; + } + else + break; + } + } + + delete[] ppTable; +} + +void PrintError(Error_STRUCT* pErr) +{ + if (pErr == nullptr) + { + return; + } + + printf("%d,%d,%s\n", pErr->ErrType, pErr->ErrCode, pErr->ErrInfo); +} + +void PrintErrors(Error_STRUCT** pErrs) +{ + if (pErrs == nullptr) + return; + + int i = 0; + Error_STRUCT* pErr = pErrs[i]; + while (pErr != nullptr) + { + printf("%d:%d,%d,%s\n",i, pErr->ErrType, pErr->ErrCode, pErr->ErrInfo); + + ++i; + pErr = pErrs[i]; + } +} + +void PrintErrors(Error_STRUCT** pErrs, int count) +{ + if (pErrs == nullptr) + { + return; + } + + for (int i = 0; i < count;++i) + { + Error_STRUCT* pErr = pErrs[i]; + if (pErr) + { + printf("%d:%d,%d,%s\n", i, pErr->ErrType, pErr->ErrCode, pErr->ErrInfo); + } + } +} + +void OutputCSVError(FILE* pFile, Error_STRUCT* pErr) +{ + if (pErr == nullptr) + { + return; + } + + fprintf(pFile, "%d,%d,%s\n", pErr->ErrType, pErr->ErrCode, pErr->ErrInfo); +} + +void OutputCSVErrors(FILE* pFile, Error_STRUCT** pErrs) +{ + if (pErrs == nullptr) + return; + + int i = 0; + Error_STRUCT* pErr = pErrs[i]; + while (pErr != nullptr) + { + fprintf(pFile, "%d:%d,%d,%s\n", i, pErr->ErrType, pErr->ErrCode, pErr->ErrInfo); + + ++i; + pErr = pErrs[i]; + } +} + +void OutputCSVErrors(FILE* pFile, Error_STRUCT** pErrs, int count) +{ + if (pErrs == nullptr) + { + return; + } + + for (int i = 0; i < count; ++i) + { + Error_STRUCT* pErr = pErrs[i]; + if (pErr) + { + fprintf(pFile, "%d:%d,%d,%s\n", i, pErr->ErrType, pErr->ErrCode, pErr->ErrInfo); + } + else + fprintf(pFile, "\n"); + } +} + +void DeleteError(Error_STRUCT* pErr) +{ + delete[] pErr; +} + +void DeleteErrors(Error_STRUCT** pErrs) +{ + if (pErrs == nullptr) + return; + + int i = 0; + while (pErrs[i] != 0) + { + delete[] pErrs[i]; + + ++i; + } + + delete[] pErrs; +} + +void DeleteErrors(Error_STRUCT** pErrs, int count) +{ + if (pErrs == nullptr) + return; + + for (int i = 0; i < count; ++i) + { + delete[] pErrs[i]; + } + + delete[] pErrs; +} + +int GetCountErrors(Error_STRUCT** pErrs) +{ + if (pErrs == nullptr) + return -1; + + int i = 0; + Error_STRUCT* pRow = pErrs[i]; + while (pRow != 0) + { + ++i; + pRow = pErrs[i]; + } + return i; +} + +////////////////////////////////////////////////////////////////////////// + +int ZTSM_str_2_int(char* pIn) +{ + char* pCheng = strstr(pIn, "成"); + char* pChe = strstr(pIn, "撤"); + char* pBu = strstr(pIn, "部"); + + if (pChe) + { + if (pBu) + { + return ZTSM_PartiallyCancelled; + } + return ZTSM_AllCancelled; + } + else if (pCheng) + { + if (pBu) + { + // 部成是啥?这里需要完成 + return ZTSM_PartiallyFilled; + } + return ZTSM_AllFilled; + } + + char* pQ = strstr(pIn, "全"); + char* pY = strstr(pIn, "已"); + char* pBao = strstr(pIn, "报"); + char* pF = strstr(pIn, "废"); + + if (pF) + { + return ZTSM_Illegal; + } + + return ZTSM_New; +} + +// 将中文的报价方式转成委托方式,这是根据字符串的特点进行分类 +int BJFS_2_WTFS(char* pIn) +{ + char* pX1 = strstr(pIn, "限"); + + if (pX1 == pIn) + { + // 第一个字是限价 + return WTFS_Limit; + } + else + { + char* pMM = strstr(pIn, "买卖"); + if (pMM) + { + // 华泰返回买卖是表示限价 + return WTFS_Limit; + } + char* pC = strstr(pIn, "撤"); + if (pC) + { + char* p5 = strstr(pIn, "五"); + if (p5) + { + return WTFS_Five_IOC; + } + char* pQ = strstr(pIn, "全"); + if (pQ) + { + return WTFS_FOK; + } + return WTFS_IOC; // 剩 + } + else + { + char* pZ = strstr(pIn, "转"); + if (pZ) + { + return WTFS_Five_Limit; + } + char* pD = strstr(pIn, "对"); + if (pD) + { + return WTFS_Best_Reverse; + } + return WTFS_Best_Forward; // 本 + } + } +} + +////////////////////////////////////////////////////////////////////////// + +void CharTable2GDLB(FieldInfo_STRUCT** ppFieldInfos, char** ppTable, GDLB_STRUCT*** pppResults) +{ + *pppResults = nullptr; + if (ppTable == nullptr) + return; + + int count = GetRowCountTableBody(ppTable); + if (count <= 0) + return; + + GDLB_STRUCT** ppResults = new GDLB_STRUCT*[count + 1](); + ppResults[count] = nullptr; + *pppResults = ppResults; + + int col_123 = GetIndexByFieldID(ppFieldInfos, FIELD_GDDM); + int col_124 = GetIndexByFieldID(ppFieldInfos, FIELD_GDMC); + int col_125 = GetIndexByFieldID(ppFieldInfos, FIELD_ZHLB); + int col_121 = GetIndexByFieldID(ppFieldInfos, FIELD_ZJZH); + int col_173 = GetIndexByFieldID(ppFieldInfos, FIELD_XWDM); + int col_281 = GetIndexByFieldID(ppFieldInfos, FIELD_RZRQBS); + int col_1213 = GetIndexByFieldID(ppFieldInfos, FIELD_BLXX); + + for (int i = 0; i < count; ++i) + { + ppResults[i] = new GDLB_STRUCT(); + + //if (col_123 >= 0) + strcpy_s(ppResults[i]->GDDM, ppTable[i * COL_EACH_ROW + col_123]); + //if (col_124 >= 0) + strcpy_s(ppResults[i]->GDMC, ppTable[i * COL_EACH_ROW + col_124]); + if (col_121 >= 0) + strcpy_s(ppResults[i]->ZJZH, ppTable[i * COL_EACH_ROW + col_121]); + //if (col_125 >= 0) + strcpy_s(ppResults[i]->ZHLB, ppTable[i * COL_EACH_ROW + col_125]); + if (col_173 >= 0) + strcpy_s(ppResults[i]->XWDM, ppTable[i * COL_EACH_ROW + col_173]); + if (col_281 >= 0) + strcpy_s(ppResults[i]->RZRQBS, ppTable[i * COL_EACH_ROW + col_281]); + if (col_1213 >= 0) + strcpy_s(ppResults[i]->BLXX, ppTable[i * COL_EACH_ROW + col_1213]); + + ppResults[i]->ZHLB_ = atoi(ppResults[i]->ZHLB); + ppResults[i]->RZRQBS_ = atoi(ppResults[i]->RZRQBS); + } +} + + + +void CharTable2WTLB(FieldInfo_STRUCT** ppFieldInfos, char** ppTable, WTLB_STRUCT*** pppResults) +{ + *pppResults = nullptr; + if (ppTable == nullptr) + return; + + int count = GetRowCountTableBody(ppTable); + if (count <= 0) + return; + + WTLB_STRUCT** ppResults = new WTLB_STRUCT*[count + 1](); + ppResults[count] = nullptr; + *pppResults = ppResults; + + int col_142 = GetIndexByFieldID(ppFieldInfos, FIELD_WTRQ); + int col_143 = GetIndexByFieldID(ppFieldInfos, FIELD_WTSJ); + int col_123 = GetIndexByFieldID(ppFieldInfos, FIELD_GDDM); + int col_140 = GetIndexByFieldID(ppFieldInfos, FIELD_ZQDM); + int col_141 = GetIndexByFieldID(ppFieldInfos, FIELD_ZQMC); + int col_130 = GetIndexByFieldID(ppFieldInfos, FIELD_MMBZ); + int col_131 = GetIndexByFieldID(ppFieldInfos, FIELD_WTLB); + int col_100 = GetIndexByFieldID(ppFieldInfos, FIELD_JYSDM); + int col_145 = GetIndexByFieldID(ppFieldInfos, FIELD_WTJG); + int col_144 = GetIndexByFieldID(ppFieldInfos, FIELD_WTSL); + int col_153 = GetIndexByFieldID(ppFieldInfos, FIELD_CJJG); + int col_152 = GetIndexByFieldID(ppFieldInfos, FIELD_CJSL); + int col_162 = GetIndexByFieldID(ppFieldInfos, FIELD_CDSL); + int col_146 = GetIndexByFieldID(ppFieldInfos, FIELD_WTBH); + int col_194 = GetIndexByFieldID(ppFieldInfos, FIELD_BJFS); + int col_147 = GetIndexByFieldID(ppFieldInfos, FIELD_ZTSM); + int col_161 = GetIndexByFieldID(ppFieldInfos, FIELD_DJZJ); + int col_1213 = GetIndexByFieldID(ppFieldInfos, FIELD_BLXX); + + for (int i = 0; i < count; ++i) + { + ppResults[i] = new WTLB_STRUCT(); + + if (col_142 >= 0) + strcpy_s(ppResults[i]->WTRQ, ppTable[i * COL_EACH_ROW + col_142]); + if (col_143 >= 0) + strcpy_s(ppResults[i]->WTSJ, ppTable[i * COL_EACH_ROW + col_143]); + //if (col_123 >= 0) + strcpy_s(ppResults[i]->GDDM, ppTable[i * COL_EACH_ROW + col_123]); + //if (col_140 >= 0) + strcpy_s(ppResults[i]->ZQDM, ppTable[i * COL_EACH_ROW + col_140]); + //if (col_141 >= 0) + strcpy_s(ppResults[i]->ZQMC, ppTable[i * COL_EACH_ROW + col_141]); + //if (col_130 >= 0) + strcpy_s(ppResults[i]->MMBZ, ppTable[i * COL_EACH_ROW + col_130]); + //if (col_131 >= 0) + strcpy_s(ppResults[i]->WTLB, ppTable[i * COL_EACH_ROW + col_131]); + //if (col_100 >= 0) + strcpy_s(ppResults[i]->JYSDM, ppTable[i * COL_EACH_ROW + col_100]); + //if (col_145 >= 0) + strcpy_s(ppResults[i]->WTJG, ppTable[i * COL_EACH_ROW + col_145]); + //if (col_144 >= 0) + strcpy_s(ppResults[i]->WTSL, ppTable[i * COL_EACH_ROW + col_144]); + //if (col_153 >= 0) + strcpy_s(ppResults[i]->CJJG, ppTable[i * COL_EACH_ROW + col_153]); + //if (col_152 >= 0) + strcpy_s(ppResults[i]->CJSL, ppTable[i * COL_EACH_ROW + col_152]); + if (col_162 >= 0) + strcpy_s(ppResults[i]->CDSL, ppTable[i * COL_EACH_ROW + col_162]); + //if (col_146 >= 0) + strcpy_s(ppResults[i]->WTBH, ppTable[i * COL_EACH_ROW + col_146]); + //if (col_194 >= 0) + strcpy_s(ppResults[i]->BJFS, ppTable[i * COL_EACH_ROW + col_194]); + if (col_147 >= 0) + strcpy_s(ppResults[i]->ZTSM, ppTable[i * COL_EACH_ROW + col_147]); + if (col_161 >= 0) + strcpy_s(ppResults[i]->DJZJ, ppTable[i * COL_EACH_ROW + col_161]); + if (col_1213 >= 0) + strcpy_s(ppResults[i]->BLXX, ppTable[i * COL_EACH_ROW + col_1213]); + + ppResults[i]->WTRQ_ = atoi(ppResults[i]->WTRQ); + ppResults[i]->MMBZ_ = atoi(ppResults[i]->MMBZ); + ppResults[i]->JYSDM_ = atoi(ppResults[i]->JYSDM); + ppResults[i]->WTJG_ = atof(ppResults[i]->WTJG); + ppResults[i]->WTSL_ = atoi(ppResults[i]->WTSL); + ppResults[i]->CJJG_ = atof(ppResults[i]->CJJG); + ppResults[i]->CJSL_ = atoi(ppResults[i]->CJSL); + ppResults[i]->DJZJ_ = atof(ppResults[i]->DJZJ); + + // 可能没有,怎么办 + ppResults[i]->CDSL_ = atoi(ppResults[i]->CDSL); + + int HH = 0, mm = 0, ss = 0; + GetUpdateTime_HH_mm_ss(ppResults[i]->WTSJ, &HH, &mm, &ss); + ppResults[i]->WTSJ_ = HH * 10000 + mm * 100 + ss; + + // 第一个的字符,并转成数字 + if (ppResults[i]->ZTSM[1] == '-') + { + ppResults[i]->ZTSM_ = ppResults[i]->ZTSM[0] - '0'; + } + else + { + ppResults[i]->ZTSM_ = ZTSM_str_2_int(ppResults[i]->ZTSM); + } + + ppResults[i]->BJFS_ = BJFS_2_WTFS(ppResults[i]->BJFS); + } +} + +void CharTable2CJLB(FieldInfo_STRUCT** ppFieldInfos, char** ppTable, CJLB_STRUCT*** pppResults) +{ + *pppResults = nullptr; + if (ppTable == nullptr) + return; + + int count = GetRowCountTableBody(ppTable); + if (count <= 0) + return; + + CJLB_STRUCT** ppResults = new CJLB_STRUCT*[count + 1](); + ppResults[count] = nullptr; + *pppResults = ppResults; + + int col_150 = GetIndexByFieldID(ppFieldInfos, FIELD_CJRQ); + int col_151 = GetIndexByFieldID(ppFieldInfos, FIELD_CJSJ); + int col_123 = GetIndexByFieldID(ppFieldInfos, FIELD_GDDM); + int col_140 = GetIndexByFieldID(ppFieldInfos, FIELD_ZQDM); + int col_141 = GetIndexByFieldID(ppFieldInfos, FIELD_ZQMC); + int col_130 = GetIndexByFieldID(ppFieldInfos, FIELD_MMBZ); + int col_131 = GetIndexByFieldID(ppFieldInfos, FIELD_WTLB); + int col_153 = GetIndexByFieldID(ppFieldInfos, FIELD_CJJG); + int col_152 = GetIndexByFieldID(ppFieldInfos, FIELD_CJSL); + int col_303 = GetIndexByFieldID(ppFieldInfos, FIELD_FSJE); + int col_304 = GetIndexByFieldID(ppFieldInfos, FIELD_SYJE); + int col_206 = GetIndexByFieldID(ppFieldInfos, FIELD_YJ); + int col_210 = GetIndexByFieldID(ppFieldInfos, FIELD_YHS); + int col_207 = GetIndexByFieldID(ppFieldInfos, FIELD_GHF); + int col_208 = GetIndexByFieldID(ppFieldInfos, FIELD_CJF); + int col_155 = GetIndexByFieldID(ppFieldInfos, FIELD_CJBH); + int col_167 = GetIndexByFieldID(ppFieldInfos, FIELD_CDBZ); + int col_146 = GetIndexByFieldID(ppFieldInfos, FIELD_WTBH); + + for (int i = 0; i < count; ++i) + { + ppResults[i] = new CJLB_STRUCT(); + + if (col_150 >= 0) + strcpy_s(ppResults[i]->CJRQ, ppTable[i * COL_EACH_ROW + col_150]); + if (col_151 >= 0) + strcpy_s(ppResults[i]->CJSJ, ppTable[i * COL_EACH_ROW + col_151]); + //if (col_123 >= 0) + strcpy_s(ppResults[i]->GDDM, ppTable[i * COL_EACH_ROW + col_123]); + //if (col_140 >= 0) + strcpy_s(ppResults[i]->ZQDM, ppTable[i * COL_EACH_ROW + col_140]); + //if (col_141 >= 0) + strcpy_s(ppResults[i]->ZQMC, ppTable[i * COL_EACH_ROW + col_141]); + //if (col_130 >= 0) + strcpy_s(ppResults[i]->MMBZ, ppTable[i * COL_EACH_ROW + col_130]); + //if (col_131 >= 0) + strcpy_s(ppResults[i]->WTLB, ppTable[i * COL_EACH_ROW + col_131]); + //if (col_153 >= 0) + strcpy_s(ppResults[i]->CJJG, ppTable[i * COL_EACH_ROW + col_153]); + //if (col_152 >= 0) + strcpy_s(ppResults[i]->CJSL, ppTable[i * COL_EACH_ROW + col_152]); + if (col_303 >= 0) + strcpy_s(ppResults[i]->FSJE, ppTable[i * COL_EACH_ROW + col_303]); + if (col_304 >= 0) + strcpy_s(ppResults[i]->SYJE, ppTable[i * COL_EACH_ROW + col_304]); + if (col_206 >= 0) + strcpy_s(ppResults[i]->YJ, ppTable[i * COL_EACH_ROW + col_206]); + if (col_210 >= 0) + strcpy_s(ppResults[i]->YHS, ppTable[i * COL_EACH_ROW + col_210]); + if (col_207 >= 0) + strcpy_s(ppResults[i]->GHF, ppTable[i * COL_EACH_ROW + col_207]); + if (col_208 >= 0) + strcpy_s(ppResults[i]->CJF, ppTable[i * COL_EACH_ROW + col_208]); + //if (col_155 >= 0) + strcpy_s(ppResults[i]->CJBH, ppTable[i * COL_EACH_ROW + col_155]); + if (col_167 >= 0) + strcpy_s(ppResults[i]->CDBZ, ppTable[i * COL_EACH_ROW + col_167]); + if (col_146 >= 0) + strcpy_s(ppResults[i]->WTBH, ppTable[i * COL_EACH_ROW + col_146]); + + + ppResults[i]->CJRQ_ = atoi(ppResults[i]->CJRQ); + //ppResults[i]->CJSJ_ = atoi(ppResults[i]->CJSJ); + ppResults[i]->MMBZ_ = atoi(ppResults[i]->MMBZ); + ppResults[i]->WTLB_ = atoi(ppResults[i]->WTLB); + ppResults[i]->CJJG_ = atof(ppResults[i]->CJJG); + ppResults[i]->CJSL_ = atoi(ppResults[i]->CJSL); + ppResults[i]->SYJE_ = atof(ppResults[i]->SYJE); + ppResults[i]->YJ_ = atof(ppResults[i]->YJ); + ppResults[i]->YHS_ = atof(ppResults[i]->YHS); + ppResults[i]->GHF_ = atof(ppResults[i]->GHF); + ppResults[i]->CJF_ = atof(ppResults[i]->CJF); + ppResults[i]->CDBZ_ = atoi(ppResults[i]->CDBZ); + + // 可能没有 + ppResults[i]->FSJE_ = atof(ppResults[i]->FSJE); + + int HH = 0, mm = 0, ss = 0; + GetUpdateTime_HH_mm_ss(ppResults[i]->CJSJ, &HH, &mm, &ss); + ppResults[i]->CJSJ_ = HH * 10000 + mm * 100 + ss; + } +} + +void CharTable2GFLB(FieldInfo_STRUCT** ppFieldInfos, char** ppTable, GFLB_STRUCT*** pppResults) +{ + *pppResults = nullptr; + if (ppTable == nullptr) + return; + + int count = GetRowCountTableBody(ppTable); + if (count <= 0) + return; + + GFLB_STRUCT** ppResults = new GFLB_STRUCT*[count + 1](); + ppResults[count] = nullptr; + *pppResults = ppResults; + + int col_140 = GetIndexByFieldID(ppFieldInfos, FIELD_ZQDM); + int col_141 = GetIndexByFieldID(ppFieldInfos, FIELD_ZQMC); + int col_200 = GetIndexByFieldID(ppFieldInfos, FIELD_ZQSL); + int col_201 = GetIndexByFieldID(ppFieldInfos, FIELD_KMSL); + int col_202 = GetIndexByFieldID(ppFieldInfos, FIELD_TBCBJ); + int col_949 = GetIndexByFieldID(ppFieldInfos, FIELD_DQJ); + int col_205 = GetIndexByFieldID(ppFieldInfos, FIELD_ZXSZ); + int col_204 = GetIndexByFieldID(ppFieldInfos, FIELD_TBFDYK); + int col_232 = GetIndexByFieldID(ppFieldInfos, FIELD_SXYK); + int col_230 = GetIndexByFieldID(ppFieldInfos, FIELD_CKYKBL); + int col_160 = GetIndexByFieldID(ppFieldInfos, FIELD_DJSL); + int col_123 = GetIndexByFieldID(ppFieldInfos, FIELD_GDDM); + int col_100 = GetIndexByFieldID(ppFieldInfos, FIELD_JYSDM); + int col_101 = GetIndexByFieldID(ppFieldInfos, FIELD_JYSMC); + int col_1213 = GetIndexByFieldID(ppFieldInfos, FIELD_BLXX); + + for (int i = 0; i < count; ++i) + { + ppResults[i] = new GFLB_STRUCT(); + + //if (col_140 >= 0) + strcpy_s(ppResults[i]->ZQDM, ppTable[i * COL_EACH_ROW + col_140]); + //if (col_141 >= 0) + strcpy_s(ppResults[i]->ZQMC, ppTable[i * COL_EACH_ROW + col_141]); + //if (col_200 >= 0) + strcpy_s(ppResults[i]->ZQSL, ppTable[i * COL_EACH_ROW + col_200]); + //if (col_201 >= 0) + strcpy_s(ppResults[i]->KMSL, ppTable[i * COL_EACH_ROW + col_201]); + //if (col_202 >= 0) + strcpy_s(ppResults[i]->TBCBJ, ppTable[i * COL_EACH_ROW + col_202]); + //if (col_949 >= 0) + strcpy_s(ppResults[i]->DQJ, ppTable[i * COL_EACH_ROW + col_949]); + //if (col_205 >= 0) + strcpy_s(ppResults[i]->ZXSZ, ppTable[i * COL_EACH_ROW + col_205]); + //if (col_204 >= 0) + strcpy_s(ppResults[i]->TBFDYK, ppTable[i * COL_EACH_ROW + col_204]); + if (col_232 >= 0) + strcpy_s(ppResults[i]->SXYK, ppTable[i * COL_EACH_ROW + col_232]); + if (col_230 >= 0) + strcpy_s(ppResults[i]->CKYKBL, ppTable[i * COL_EACH_ROW + col_230]); + if (col_160 >= 0) + strcpy_s(ppResults[i]->DJSL, ppTable[i * COL_EACH_ROW + col_160]); + //if (col_123 >= 0) + strcpy_s(ppResults[i]->GDDM, ppTable[i * COL_EACH_ROW + col_123]); + if (col_100 >= 0) + strcpy_s(ppResults[i]->JYSDM, ppTable[i * COL_EACH_ROW + col_100]); + if (col_101 >= 0) + strcpy_s(ppResults[i]->JYSMC, ppTable[i * COL_EACH_ROW + col_101]); + //if (col_1213 >= 0) + strcpy_s(ppResults[i]->BLXX, ppTable[i * COL_EACH_ROW + col_1213]); + + + ppResults[i]->ZQSL_ = atoi(ppResults[i]->ZQSL); + ppResults[i]->KMSL_ = atoi(ppResults[i]->KMSL); + ppResults[i]->TBCBJ_ = atof(ppResults[i]->TBCBJ); + ppResults[i]->DQJ_ = atof(ppResults[i]->DQJ); + ppResults[i]->ZXSZ_ = atof(ppResults[i]->ZXSZ); + ppResults[i]->DJSL_ = atof(ppResults[i]->DJSL); + } +} + +void CharTable2ZJYE(FieldInfo_STRUCT** ppFieldInfos, char** ppTable, ZJYE_STRUCT*** pppResults) +{ + *pppResults = nullptr; + if (ppTable == nullptr) + return; + + int count = GetRowCountTableBody(ppTable); + if (count <= 0) + return; + + ZJYE_STRUCT** ppResults = new ZJYE_STRUCT*[count + 1](); + ppResults[count] = nullptr; + *pppResults = ppResults; + + int col_132 = GetIndexByFieldID(ppFieldInfos, FIELD_BZ); + int col_300 = GetIndexByFieldID(ppFieldInfos, FIELD_ZJYE); + int col_301 = GetIndexByFieldID(ppFieldInfos, FIELD_KYZJ); + int col_310 = GetIndexByFieldID(ppFieldInfos, FIELD_ZZC_310); + int col_302 = GetIndexByFieldID(ppFieldInfos, FIELD_KQZJ); + int col_121 = GetIndexByFieldID(ppFieldInfos, FIELD_ZJZH); + int col_205 = GetIndexByFieldID(ppFieldInfos, FIELD_ZXSZ); + + for (int i = 0; i < count; ++i) + { + ppResults[i] = new ZJYE_STRUCT(); + + //if (col_132 >= 0) + strcpy_s(ppResults[i]->BZ, ppTable[i * COL_EACH_ROW + col_132]); + //if (col_300 >= 0) + strcpy_s(ppResults[i]->ZJYE, ppTable[i * COL_EACH_ROW + col_300]); + //if (col_301 >= 0) + strcpy_s(ppResults[i]->KYZJ, ppTable[i * COL_EACH_ROW + col_301]); + //if (col_310 >= 0) + strcpy_s(ppResults[i]->ZZC, ppTable[i * COL_EACH_ROW + col_310]); + if (col_302 >= 0) + strcpy_s(ppResults[i]->KQZJ, ppTable[i * COL_EACH_ROW + col_302]); + if (col_121 >= 0) + strcpy_s(ppResults[i]->ZJZH, ppTable[i * COL_EACH_ROW + col_121]); + if (col_205 >= 0) + strcpy_s(ppResults[i]->ZXSZ, ppTable[i * COL_EACH_ROW + col_205]); + + + ppResults[i]->ZJYE_ = atof(ppResults[i]->ZJYE); + ppResults[i]->KYZJ_ = atof(ppResults[i]->KYZJ); + ppResults[i]->ZZC_ = atof(ppResults[i]->ZZC); + ppResults[i]->KQZJ_ = atof(ppResults[i]->KQZJ); + ppResults[i]->ZXSZ_ = atof(ppResults[i]->ZXSZ); + } +} + +void CharTable2HQ(FieldInfo_STRUCT** ppFieldInfos, char** ppTable, HQ_STRUCT*** pppResults) +{ + *pppResults = nullptr; + if (ppTable == nullptr) + return; + + int count = GetRowCountTableBody(ppTable); + if (count <= 0) + return; + + HQ_STRUCT** ppResults = new HQ_STRUCT*[count + 1](); + ppResults[count] = nullptr; + *pppResults = ppResults; + + int col_140 = GetIndexByFieldID(ppFieldInfos, FIELD_ZQDM); + int col_141 = GetIndexByFieldID(ppFieldInfos, FIELD_ZQMC); + int col_946 = GetIndexByFieldID(ppFieldInfos, FIELD_ZSJ); + int col_945 = GetIndexByFieldID(ppFieldInfos, FIELD_JKJ); + int col_948 = GetIndexByFieldID(ppFieldInfos, FIELD_GZLX); + int col_949 = GetIndexByFieldID(ppFieldInfos, FIELD_DQJ); + int col_910 = GetIndexByFieldID(ppFieldInfos, FIELD_BID_PRICE_1); + int col_911 = GetIndexByFieldID(ppFieldInfos, FIELD_BID_PRICE_2); + int col_912 = GetIndexByFieldID(ppFieldInfos, FIELD_BID_PRICE_3); + int col_913 = GetIndexByFieldID(ppFieldInfos, FIELD_BID_PRICE_4); + int col_914 = GetIndexByFieldID(ppFieldInfos, FIELD_BID_PRICE_5); + int col_900 = GetIndexByFieldID(ppFieldInfos, FIELD_BID_SIZE_1); + int col_901 = GetIndexByFieldID(ppFieldInfos, FIELD_BID_SIZE_2); + int col_902 = GetIndexByFieldID(ppFieldInfos, FIELD_BID_SIZE_3); + int col_903 = GetIndexByFieldID(ppFieldInfos, FIELD_BID_SIZE_4); + int col_904 = GetIndexByFieldID(ppFieldInfos, FIELD_BID_SIZE_5); + int col_930 = GetIndexByFieldID(ppFieldInfos, FIELD_ASK_PRICE_1); + int col_931 = GetIndexByFieldID(ppFieldInfos, FIELD_ASK_PRICE_2); + int col_932 = GetIndexByFieldID(ppFieldInfos, FIELD_ASK_PRICE_3); + int col_933 = GetIndexByFieldID(ppFieldInfos, FIELD_ASK_PRICE_4); + int col_934 = GetIndexByFieldID(ppFieldInfos, FIELD_ASK_PRICE_5); + int col_920 = GetIndexByFieldID(ppFieldInfos, FIELD_ASK_SIZE_1); + int col_921 = GetIndexByFieldID(ppFieldInfos, FIELD_ASK_SIZE_2); + int col_922 = GetIndexByFieldID(ppFieldInfos, FIELD_ASK_SIZE_3); + int col_923 = GetIndexByFieldID(ppFieldInfos, FIELD_ASK_SIZE_4); + int col_924 = GetIndexByFieldID(ppFieldInfos, FIELD_ASK_SIZE_5); + int col_100 = GetIndexByFieldID(ppFieldInfos, FIELD_JYSDM); + int col_187 = GetIndexByFieldID(ppFieldInfos, FIELD_ZXJYGS); + int col_226 = GetIndexByFieldID(ppFieldInfos, FIELD_ZXMRBDJW); + int col_227 = GetIndexByFieldID(ppFieldInfos, FIELD_ZXMCBDJW); + int col_125 = GetIndexByFieldID(ppFieldInfos, FIELD_ZHLB); + int col_132 = GetIndexByFieldID(ppFieldInfos, FIELD_BZ); + int col_958 = GetIndexByFieldID(ppFieldInfos, FIELD_GZBS); + int col_940 = GetIndexByFieldID(ppFieldInfos, FIELD_ZTJG); + int col_941 = GetIndexByFieldID(ppFieldInfos, FIELD_DTJG); + int col_1213 = GetIndexByFieldID(ppFieldInfos, FIELD_BLXX); + + for (int i = 0; i < count; ++i) + { + ppResults[i] = new HQ_STRUCT(); + + //if (col_140 >= 0) + strcpy_s(ppResults[i]->ZQDM, ppTable[i * COL_EACH_ROW + col_140]); + if (col_141 >= 0) + strcpy_s(ppResults[i]->ZQMC, ppTable[i * COL_EACH_ROW + col_141]); + if (col_946 >= 0) + strcpy_s(ppResults[i]->ZSJ, ppTable[i * COL_EACH_ROW + col_946]); + if (col_945 >= 0) + strcpy_s(ppResults[i]->JKJ, ppTable[i * COL_EACH_ROW + col_945]); + if (col_948 >= 0) + strcpy_s(ppResults[i]->GZLX, ppTable[i * COL_EACH_ROW + col_948]); + //if (col_949 >= 0) + strcpy_s(ppResults[i]->DQJ, ppTable[i * COL_EACH_ROW + col_949]); + //if (col_910 >= 0) + strcpy_s(ppResults[i]->BidPrice1, ppTable[i * COL_EACH_ROW + col_910]); + //if (col_911 >= 0) + strcpy_s(ppResults[i]->BidPrice2, ppTable[i * COL_EACH_ROW + col_911]); + //if (col_912 >= 0) + strcpy_s(ppResults[i]->BidPrice3, ppTable[i * COL_EACH_ROW + col_912]); + //if (col_913 >= 0) + strcpy_s(ppResults[i]->BidPrice4, ppTable[i * COL_EACH_ROW + col_913]); + //if (col_914 >= 0) + strcpy_s(ppResults[i]->BidPrice5, ppTable[i * COL_EACH_ROW + col_914]); + //if (col_900 >= 0) + strcpy_s(ppResults[i]->BidSize1, ppTable[i * COL_EACH_ROW + col_900]); + //if (col_901 >= 0) + strcpy_s(ppResults[i]->BidSize2, ppTable[i * COL_EACH_ROW + col_901]); + //if (col_902 >= 0) + strcpy_s(ppResults[i]->BidSize3, ppTable[i * COL_EACH_ROW + col_902]); + //if (col_903 >= 0) + strcpy_s(ppResults[i]->BidSize4, ppTable[i * COL_EACH_ROW + col_903]); + //if (col_904 >= 0) + strcpy_s(ppResults[i]->BidSize5, ppTable[i * COL_EACH_ROW + col_904]); + //if (col_930 >= 0) + strcpy_s(ppResults[i]->AskPrice1, ppTable[i * COL_EACH_ROW + col_930]); + //if (col_931 >= 0) + strcpy_s(ppResults[i]->AskPrice2, ppTable[i * COL_EACH_ROW + col_931]); + //if (col_932 >= 0) + strcpy_s(ppResults[i]->AskPrice3, ppTable[i * COL_EACH_ROW + col_932]); + //if (col_933 >= 0) + strcpy_s(ppResults[i]->AskPrice4, ppTable[i * COL_EACH_ROW + col_933]); + //if (col_934 >= 0) + strcpy_s(ppResults[i]->AskPrice5, ppTable[i * COL_EACH_ROW + col_934]); + //if (col_920 >= 0) + strcpy_s(ppResults[i]->AskSize1, ppTable[i * COL_EACH_ROW + col_920]); + //if (col_921 >= 0) + strcpy_s(ppResults[i]->AskSize2, ppTable[i * COL_EACH_ROW + col_921]); + //if (col_922 >= 0) + strcpy_s(ppResults[i]->AskSize3, ppTable[i * COL_EACH_ROW + col_922]); + //if (col_923 >= 0) + strcpy_s(ppResults[i]->AskSize4, ppTable[i * COL_EACH_ROW + col_923]); + //if (col_924 >= 0) + strcpy_s(ppResults[i]->AskSize5, ppTable[i * COL_EACH_ROW + col_924]); + //if (col_100 >= 0) + strcpy_s(ppResults[i]->JYSDM, ppTable[i * COL_EACH_ROW + col_100]); + //if (col_187 >= 0) + strcpy_s(ppResults[i]->ZXJYGS, ppTable[i * COL_EACH_ROW + col_187]); + //if (col_226 >= 0) + strcpy_s(ppResults[i]->ZXMRBDJW, ppTable[i * COL_EACH_ROW + col_226]); + //if (col_227 >= 0) + strcpy_s(ppResults[i]->ZXMCBDJW, ppTable[i * COL_EACH_ROW + col_227]); + //if (col_125 >= 0) + strcpy_s(ppResults[i]->ZHLB, ppTable[i * COL_EACH_ROW + col_125]); + //if (col_132 >= 0) + strcpy_s(ppResults[i]->BZ, ppTable[i * COL_EACH_ROW + col_132]); + //if (col_958 >= 0) + strcpy_s(ppResults[i]->GZBS, ppTable[i * COL_EACH_ROW + col_958]); + if (col_940 >= 0) + strcpy_s(ppResults[i]->ZTJG, ppTable[i * COL_EACH_ROW + col_940]); + if (col_941 >= 0) + strcpy_s(ppResults[i]->DTJG, ppTable[i * COL_EACH_ROW + col_941]); + if (col_1213 >= 0) + strcpy_s(ppResults[i]->BLXX, ppTable[i * COL_EACH_ROW + col_1213]); + + + ppResults[i]->ZSJ_ = atof(ppResults[i]->ZSJ); + ppResults[i]->JKJ_ = atof(ppResults[i]->JKJ); + ppResults[i]->GZLX_ = atof(ppResults[i]->GZLX); + ppResults[i]->DQJ_ = atof(ppResults[i]->DQJ); + ppResults[i]->BidPrice1_ = atof(ppResults[i]->BidPrice1); + ppResults[i]->BidPrice2_ = atof(ppResults[i]->BidPrice2); + ppResults[i]->BidPrice3_ = atof(ppResults[i]->BidPrice3); + ppResults[i]->BidPrice4_ = atof(ppResults[i]->BidPrice4); + ppResults[i]->BidPrice5_ = atof(ppResults[i]->BidPrice5); + ppResults[i]->AskPrice1_ = atof(ppResults[i]->AskPrice1); + ppResults[i]->AskPrice2_ = atof(ppResults[i]->AskPrice2); + ppResults[i]->AskPrice3_ = atof(ppResults[i]->AskPrice3); + ppResults[i]->AskPrice4_ = atof(ppResults[i]->AskPrice4); + ppResults[i]->AskPrice5_ = atof(ppResults[i]->AskPrice5); + ppResults[i]->BidSize1_ = atoi(ppResults[i]->BidSize1); + ppResults[i]->BidSize2_ = atoi(ppResults[i]->BidSize2); + ppResults[i]->BidSize3_ = atoi(ppResults[i]->BidSize3); + ppResults[i]->BidSize4_ = atoi(ppResults[i]->BidSize4); + ppResults[i]->BidSize5_ = atoi(ppResults[i]->BidSize5); + ppResults[i]->AskSize1_ = atoi(ppResults[i]->AskSize1); + ppResults[i]->AskSize2_ = atoi(ppResults[i]->AskSize2); + ppResults[i]->AskSize3_ = atoi(ppResults[i]->AskSize3); + ppResults[i]->AskSize4_ = atoi(ppResults[i]->AskSize4); + ppResults[i]->AskSize5_ = atoi(ppResults[i]->AskSize5); + + ppResults[i]->ZXJYGS_ = atoi(ppResults[i]->ZXJYGS); + ppResults[i]->ZXMRBDJW_ = atof(ppResults[i]->ZXMRBDJW); + ppResults[i]->ZXMCBDJW_ = atof(ppResults[i]->ZXMCBDJW); + ppResults[i]->ZTJG_ = atof(ppResults[i]->ZTJG); + ppResults[i]->DTJG_ = atof(ppResults[i]->DTJG); + } +} + + +void DeleteStructs(void*** pppStructs) +{ + if (*pppStructs == nullptr) + return; + + void** ppStructs = *pppStructs; + + int i = 0; + while (ppStructs[i] != 0) + { + delete[] ppStructs[i]; + ppStructs[i] = nullptr; + + ++i; + } + + delete[] ppStructs; + *pppStructs = nullptr; +} + + +/* +6 +A74168961|WK |05000000100801|1| 0| | +013086113|WK |05000000100801|0| 0| | + +7 +A12121217|ZHT|1| 40690000|28356| 0|主股东| +015597938|ZHT|0| 40690000|394232|0|主股东| + +5 +A341083000|LK|1| |主股东| +0189181400|LK|0| |主股东| + +8 +E015976151|HT|1|88500918| 12982|1| |主股东| +0601605823|HT|0|88500918| 354000|1| |主股东| +*/ +void String2GDLB(char* szString, GDLB_STRUCT*** pppResults) +{ + *pppResults = nullptr; + if (szString == nullptr) + return; + + char* pBuf = new char[strlen(szString) + 1]; + strcpy(pBuf, szString); + + vector vct; + + // 分好多少列 + char* token = strtok(pBuf, "\r\n"); + int i = 0; + while (token) + { + if (i>0) + { + vct.push_back(token); + } + token = strtok(nullptr, "\r\n"); + ++i; + } + + int count = vct.size(); + + GDLB_STRUCT** ppResults = new GDLB_STRUCT*[count + 1](); + ppResults[count] = nullptr; + *pppResults = ppResults; + + for (int i = 0; i < count;++i) + { + ppResults[i] = new GDLB_STRUCT(); + + vector v1; + vector v2; + vector v3; + char* t = strtok(vct[i], "|"); + int j = 0; + while (t) + { + int len = strlen(t); + if (len == 1) + { + v2.push_back(t); + } + else if (len>0) + { + if (t[0]>127||t[0]<0) + { + v3.push_back(t); + } + else + { + v1.push_back(t); + } + } + t = strtok(nullptr, "|"); + } + + strcpy_s(ppResults[i]->GDDM, v1[0]); + if (v1.size() > 1) + strcpy_s(ppResults[i]->ZJZH, v1[1]); + if (v1.size() > 2) + strcpy_s(ppResults[i]->XWDM, v1[2]); + + strcpy_s(ppResults[i]->ZHLB, v2[0]); + if (v2.size() > 1) + strcpy_s(ppResults[i]->RZRQBS, v2[1]); + + if (v3.size()>0) + strcpy_s(ppResults[i]->GDMC, v3[0]); + if (v3.size()>1) + strcpy_s(ppResults[i]->BLXX, v3[1]); + + ppResults[i]->ZHLB_ = atoi(ppResults[i]->ZHLB); + ppResults[i]->RZRQBS_ = atoi(ppResults[i]->RZRQBS); + } + + delete[] pBuf; +} + +void CharTable2Login(char** ppTable, GDLB_STRUCT*** pppResults) +{ + *pppResults = nullptr; + if (ppTable == nullptr) + return; + + // 如果有数据,第一列就不为空 + int i = 0; + int j = 0; + char* p = ppTable[i * COL_EACH_ROW + j]; + while (p != nullptr) + { + int requstid = atoi(p); + if (requstid == REQUEST_GDLB + 1) + { + String2GDLB(ppTable[i * COL_EACH_ROW + 2], pppResults); + } + + ++i; + p = ppTable[i * COL_EACH_ROW + j]; + } + + return; +} + +int GetCountStructs(void** ppResults) +{ + if (ppResults == nullptr) + return -1; + + int i = 0; + void* pRow = ppResults[i]; + while (pRow != 0) + { + ++i; + pRow = ppResults[i]; + } + return i; +} + +#else +#endif \ No newline at end of file diff --git a/include/Tdx/tdx_function.h b/include/Tdx/tdx_function.h new file mode 100644 index 0000000..1f96d2f --- /dev/null +++ b/include/Tdx/tdx_function.h @@ -0,0 +1,89 @@ +#pragma once + +#include + +#include "tdx_struct.h" + +#ifdef TDXAPI_EXPORTS +#define TDXAPI_API __declspec(dllexport) + +// 由于接口实例中做了一次表头的缓存,直接删除后,下次再取将返回无效值,所以这功能只由接口来调用 +TDXAPI_API void DeleteTableHeader(FieldInfo_STRUCT** ppHeader); +// 复制表头,注意要两个都需要清理 +TDXAPI_API FieldInfo_STRUCT** CopyTableHeader(FieldInfo_STRUCT** ppHeader); + +#else +#define TDXAPI_API __declspec(dllimport) +#endif + + +// 得到时间 +//TDXAPI_API void GetUpdateTime_HH_mm_ss(char* UpdateTime, int* _HH, int* _mm, int* _ss); + +////////////////////////////////////////////////////////////////////////// +// 表头处理 + +// 打印表头信息,实际是一个指针数组,指针指向字段信息,数组最后一个指针为null +TDXAPI_API void PrintTableHeader(FieldInfo_STRUCT** ppHeader); +TDXAPI_API void OutputCSVTableHeader(FILE* pFile, FieldInfo_STRUCT** ppHeader); + +// 根据字段名得到列索引 +TDXAPI_API int GetIndexByFieldName(FieldInfo_STRUCT** ppHeader,char* FieldName); +// 根据字段ID得到列索引 +TDXAPI_API int GetIndexByFieldID(FieldInfo_STRUCT** ppHeader, int FieldID); +// 得到表头列数 +TDXAPI_API int GetCountTableHeader(FieldInfo_STRUCT** ppHeader); + +////////////////////////////////////////////////////////////////////////// +// 表体处理 + +// 打印表体信息,实际是一个指针数组,指针指向字段信息,用一维数组表示二维数组,目前约定每行64列,每列中第1个元素不能为空 +TDXAPI_API void PrintTableBody(char** ppTable); +TDXAPI_API void PrintTableBody(char** ppTable, int count); + +TDXAPI_API void OutputCSVTableBody(FILE* pFile, char** ppTable); +TDXAPI_API void OutputCSVTableBody(FILE* pFile, char** ppTable, int count); + +// 取出的数据看情况是否要删除 +TDXAPI_API void DeleteTableBody(char** ppTable); +TDXAPI_API void DeleteTableBody(char** ppTable, int count); +// 得到某一行某一列,没有数据将返回null +TDXAPI_API char* GetAtTableBody(char** ppTable, int row, int col); +// 只有非空的行才需要数,而中间出现空的只表示你已经知道表行数了,没有必要数 +TDXAPI_API int GetRowCountTableBody(char** ppTable); + +////////////////////////////////////////////////////////////////////////// +// 错误处理 +TDXAPI_API void PrintError(Error_STRUCT* pErr); +TDXAPI_API void PrintErrors(Error_STRUCT** pErrs); +TDXAPI_API void PrintErrors(Error_STRUCT** pErrs, int count); + +TDXAPI_API void OutputCSVError(FILE* pFile, Error_STRUCT* pErr); +TDXAPI_API void OutputCSVErrors(FILE* pFile, Error_STRUCT** pErrs); +TDXAPI_API void OutputCSVErrors(FILE* pFile, Error_STRUCT** pErrs, int count); + +TDXAPI_API void DeleteError(Error_STRUCT* pErr); +TDXAPI_API void DeleteErrors(Error_STRUCT** pErrs); +TDXAPI_API void DeleteErrors(Error_STRUCT** pErrs, int count); +// 得到错误数 +TDXAPI_API int GetCountErrors(Error_STRUCT** pErrs); + +////////////////////////////////////////////////////////////////////////// +// 将字符串表转成特定对 +TDXAPI_API void CharTable2GDLB(FieldInfo_STRUCT** ppFieldInfos, char** ppTable, GDLB_STRUCT*** pppResults); + +TDXAPI_API void CharTable2WTLB(FieldInfo_STRUCT** ppFieldInfos, char** ppTable, WTLB_STRUCT*** pppResults); + +TDXAPI_API void CharTable2CJLB(FieldInfo_STRUCT** ppFieldInfos, char** ppTable, CJLB_STRUCT*** pppResults); + +TDXAPI_API void CharTable2GFLB(FieldInfo_STRUCT** ppFieldInfos, char** ppTable, GFLB_STRUCT*** pppResults); + +TDXAPI_API void CharTable2ZJYE(FieldInfo_STRUCT** ppFieldInfos, char** ppTable, ZJYE_STRUCT*** pppResults); + +TDXAPI_API void CharTable2HQ(FieldInfo_STRUCT** ppFieldInfos, char** ppTable, HQ_STRUCT*** pppResults); + +TDXAPI_API void CharTable2Login(char** ppTable, GDLB_STRUCT*** pppResults); + +TDXAPI_API int GetCountStructs(void** ppResults); + +TDXAPI_API void DeleteStructs(void*** pppStructs); \ No newline at end of file diff --git a/include/Tdx/tdx_request.h b/include/Tdx/tdx_request.h new file mode 100644 index 0000000..270205d --- /dev/null +++ b/include/Tdx/tdx_request.h @@ -0,0 +1,957 @@ +#pragma once + +#ifndef _TDX_REQUEST_H_ +#define _TDX_REQUEST_H_ + +////////////////////////////////////////////////////////////////////////// +// 股票部分 + +/* +120_客户号|134_交易密码|121_资金帐号|125_帐号类别|123_股东代码|110_委托方式|100_ +交易所代码|140_证券代码|510_合约代码|113_操作标志|1217_备注|5250_客户群组|5251_ +客户营业部|5252_硬盘序列号|5253_CPUID|5254_信用交易标识|5255_会话号|5256_客户代 +码| +=============== +140_证券代码|141_证券名称|946_昨收价|945_今开价|948_国债利息|949_当前价|910_买一 +价|911_买二价|912_买三价|913_买四价|914_买五价|900_买一量|901_买二量|902_买三量| +903_买四量|904_买五量|930_卖一价|931_卖二价|932_卖三价|933_卖四价|934_卖五价|920 +_卖一量|921_卖二量|922_卖三量|923_卖四量|924_卖五量|100_交易所代码|187_最小交易 +股数|226_最小买入变动价位|227_最小卖出变动价位|125_帐号类别|132_币种|958_国债标 +识|1213_保留信息| +*/ +#define REQUEST_HQ 102 +/* +120_客户号|134_交易密码|121_资金帐号|125_帐号类别|123_股东代码|110_委托方式|132_ +币种|113_操作标志|1228_模式|1299_功能版本|101_交易所名称|5250_客户群组|5251_客户 +营业部|5252_硬盘序列号|5253_CPUID|5254_信用交易标识|5255_会话号|5256_客户代码| +=============== +132_币种|300_资金余额|301_可用资金|310_总资产|302_可取资金|121_资金帐号|1213_保 +留信息| +*/ +#define REQUEST_ZJYE 104 // 资金余额 +/* +120_客户号|134_交易密码|121_资金帐号|125_帐号类别|123_股东代码|110_委托方式|140_ +证券代码|130_买卖标志|949_当前价|301_可用资金|166_委托方式|510_合约代码|513_开平 +标志|514_投保标志|173_席位代码|242_对方席位代码|243_对方资金帐号|244_对方股东代 +码|245_对方帐号类别|113_操作标志|299_对方分支代码|298_对方客户代码|158_对方密码| +705_买入价|706_卖出价|1223_检查风险标志|146_委托编号|1299_功能版本|142_委托日期| +397_产品标志|1227_参数|5250_客户群组|5251_客户营业部|5252_硬盘序列号|5253_CPUID| +5254_信用交易标识|5255_会话号|5256_客户代码| +=============== +201_可卖数量|301_可用资金|1163_融资负债|1150_融资利息|1159_融资管理费|251_提示信 +息1|1213_保留信息| +*/ +#define REQUEST_110 110 + +/* +120_客户号|134_交易密码|121_资金帐号|125_帐号类别|123_股东代码|110_委托方式|100_ +交易所代码|140_证券代码|113_操作标志|146_委托编号|510_合约代码|162_撤单数量|173_ +席位代码|718_系统中心号|142_委托日期|130_买卖标志|514_投保标志|513_开平标志|144_ +委托数量|145_委托价格|377_合同编号|135_资金密码|143_委托时间|151_成交时间|1227_ +参数|516_成交属性|397_产品标志|101_交易所名称|5250_客户群组|5251_客户营业部|5252 +_硬盘序列号|5253_CPUID|5254_信用交易标识|5255_会话号|5256_客户代码| +=============== +1213_保留信息| +*/ +#define REQUEST_CD 200 // 撤单 +/* +120_客户号|134_交易密码|121_资金帐号|125_帐号类别|123_股东代码|110_委托方式|130_ +买卖标志|138_通讯密码|100_交易所代码|140_证券代码|145_委托价格|133_交易单位|144_ +委托数量|166_委托方式|132_币种|148_委托金额|142_委托日期|143_委托时间|146_委托编 +号|606_批次号|173_席位代码|510_合约代码|513_开平标志|514_投保标志|1223_检查风险 +标志|326_分仓基量|135_资金密码|241_约定序号|242_对方席位代码|243_对方资金帐号|24 +4_对方股东代码|245_对方帐号类别|516_成交属性|538_触发价格|299_对方分支代码|298_ +对方客户代码|158_对方密码|485_推荐人代码|1264_令牌|106_联系人姓名|107_联系方式|3 +97_产品标志|101_交易所名称|5250_客户群组|5251_客户营业部|5252_硬盘序列号|5253_CP +UID|5254_信用交易标识|5255_会话号|5256_客户代码| +=============== +146_委托编号|1223_检查风险标志|149_返回信息|1213_保留信息| +*/ +#define REQUEST_WT 202 // 委托 +/* +120_客户号|134_交易密码|121_资金帐号|125_帐号类别|123_股东代码|110_委托方式|1207 +_起始序号|126_开始日期|127_终止日期|1227_参数|101_交易所名称|5250_客户群组|5251_ +客户营业部|5252_硬盘序列号|5253_CPUID|5254_信用交易标识|5255_会话号|5256_客户代 +码| +=============== +143_委托时间|123_股东代码|140_证券代码|141_证券名称|130_买卖标志|131_买卖标志|10 +0_交易所代码|145_委托价格|144_委托数量|153_成交价格|152_成交数量|162_撤单数量|14 +6_委托编号|194_报价方式|147_状态说明|161_冻结资金|1213_保留信息| +*/ +#define REQUEST_KCLB 1100 // 可撤列表 +/* +120_客户号|134_交易密码|121_资金帐号|125_帐号类别|123_股东代码|110_委托方式|1207 +_起始序号|1227_参数|101_交易所名称|5250_客户群组|5251_客户营业部|5252_硬盘序列号 +|5253_CPUID|5254_信用交易标识|5255_会话号|5256_客户代码| +=============== +143_委托时间|123_股东代码|140_证券代码|141_证券名称|130_买卖标志|131_买卖标志|10 +0_交易所代码|145_委托价格|144_委托数量|153_成交价格|152_成交数量|162_撤单数量|14 +6_委托编号|194_报价方式|147_状态说明|161_冻结资金|1213_保留信息| +*/ +#define REQUEST_DRWT 1102 // 当日委托 +/* +120_客户号|134_交易密码|121_资金帐号|125_帐号类别|123_股东代码|110_委托方式|126_ +开始日期|127_终止日期|1207_起始序号|140_证券代码|1227_参数|5250_客户群组|5251_客 +户营业部|5252_硬盘序列号|5253_CPUID|5254_信用交易标识|5255_会话号|5256_客户代码| + +=============== +142_委托日期|123_股东代码|140_证券代码|141_证券名称|130_买卖标志|131_买卖标志|10 +0_交易所代码|145_委托价格|144_委托数量|153_成交价格|152_成交数量|162_撤单数量|14 +6_委托编号|194_报价方式|161_冻结资金|1213_保留信息| +*/ +#define REQUEST_LSWT 1104 // 历史委托 +/* +120_客户号|134_交易密码|121_资金帐号|125_帐号类别|123_股东代码|110_委托方式|1207 +_起始序号|155_成交编号|101_交易所名称|5250_客户群组|5251_客户营业部|5252_硬盘序 +列号|5253_CPUID|5254_信用交易标识|5255_会话号|5256_客户代码| +=============== +151_成交时间|123_股东代码|140_证券代码|141_证券名称|130_买卖标志|131_买卖标志|15 +3_成交价格|152_成交数量|303_发生金额|155_成交编号|167_撤单标志|146_委托编号|1213 +_保留信息| +*/ +#define REQUEST_DRCJ 1108 // 当日成交 +/* +120_客户号|134_交易密码|121_资金帐号|125_帐号类别|123_股东代码|110_委托方式|126_ +开始日期|127_终止日期|1207_起始序号|140_证券代码|101_交易所名称|5250_客户群组|52 +51_客户营业部|5252_硬盘序列号|5253_CPUID|5254_信用交易标识|5255_会话号|5256_客户 +代码| +=============== +150_成交日期|151_成交时间|123_股东代码|140_证券代码|141_证券名称|130_买卖标志|13 +1_买卖标志|153_成交价格|152_成交数量|303_发生金额|304_剩余金额|206_佣金|210_印花 +税|207_过户费|208_成交费|155_成交编号|146_委托编号|1213_保留信息| +*/ +#define REQUEST_LSCJ 1110 // 历史成交 +/* +120_客户号|134_交易密码|121_资金帐号|125_帐号类别|123_股东代码|110_委托方式|1207 +_起始序号|140_证券代码|113_操作标志|1228_模式|1299_功能版本|101_交易所名称|130_ +买卖标志|5250_客户群组|5251_客户营业部|5252_硬盘序列号|5253_CPUID|5254_信用交易 +标识|5255_会话号|5256_客户代码| +=============== +140_证券代码|141_证券名称|200_证券数量|201_可卖数量|202_摊簿成本价|949_当前价|20 +5_最新市值|204_摊簿浮动盈亏|232_实现盈亏|230_参考盈亏比例(%)|160_冻结数量|123_股 +东代码|100_交易所代码|101_交易所名称|1213_保留信息| +*/ +#define REQUEST_GFLB 1114 // 股份列表 +/* +120_客户号|134_交易密码|121_资金帐号|125_帐号类别|123_股东代码|110_委托方式|113_ +操作标志|299_对方分支代码|298_对方客户代码|243_对方资金帐号|158_对方密码|361_升 +级版本标识|5250_客户群组|5251_客户营业部|5252_硬盘序列号|5253_CPUID|5254_信用交 +易标识|5255_会话号|5256_客户代码| +=============== +123_股东代码|124_股东名称|121_资金帐号|125_帐号类别|281_融资融券标识|1213_保留信 +息| +*/ +#define REQUEST_GDLB 1122 // 股东列表 +/* +120_客户号|134_交易密码|121_资金帐号|125_帐号类别|123_股东代码|110_委托方式|130_ +买卖标志|140_证券代码|510_合约代码|959_证券信息有效标志|1223_检查风险标志|1299_ +功能版本|397_产品标志|241_约定序号|166_委托方式|101_交易所名称|5250_客户群组|525 +1_客户营业部|5252_硬盘序列号|5253_CPUID|5254_信用交易标识|5255_会话号|5256_客户 +代码| +=============== +141_证券名称|960_证券类别|301_可用资金|211_最大可买|166_委托方式|149_返回信息|37 +0_融券数量|1166_可用信用额度|1173_可用保证金|127_终止日期|1227_参数|1223_检查风 +险标志|251_提示信息1|252_提示信息2|397_产品标志|291_字段代码|125_帐号类别|145_委 +托价格|241_约定序号|201_可卖数量|144_委托数量|1213_保留信息| +*/ +#define REQUEST_1124 1124 // +////////////////////////////////////////////////////////////////////////// +// 期权部分 +/* + +*/ +#define REQUEST_BDQSD_QQ 1294 // 备兑券锁定/解锁/撤单 +/* +120_客户号|134_交易密码|121_资金帐号|125_帐号类别|123_股东代码|110_委托方式|100_ +交易所代码|294_附加账号|234_类型|140_证券代码|391_产品代码|510_合约代码|1207_起 +始序号|1227_参数|5250_客户群组|5251_客户营业部|5252_硬盘序列号|5253_CPUID|5254_ +信用交易标识|5255_会话号|5256_客户代码| +=============== +510_合约代码|391_产品代码|511_合约名称|140_证券代码|141_证券名称|333_方案类型|56 +83_期权类型|5672_行权价格|541_保证金|5741_首个交易日|5808_到期日期|5743_最后交易 +日期|540_交割月份|1231_显示颜色|100_交易所代码|1213_保留信息| +*/ +#define REQUEST_QQDMCX_QQ 1296 // 期权代码查询 +/* + +*/ +#define REQUEST_KSDS_QQ 1300 // 可锁定数 125=37好像是期权? +/* +120_客户号|134_交易密码|121_资金帐号|125_帐号类别|123_股东代码|110_委托方式|100_ +交易所代码|294_附加账号|132_币种|1217_备注|5250_客户群组|5251_客户营业部|5252_硬 +盘序列号|5253_CPUID|5254_信用交易标识|5255_会话号|5256_客户代码| +=============== +121_资金帐号|132_币种|541_保证金|700_风险度|300_资金余额|301_可用资金|205_最新市 +值|350_总资产|302_可取资金|1213_保留信息| +*/ +#define REQUEST_ZJCX_QQ 1302 // 资金查询 +/* +120_客户号|134_交易密码|121_资金帐号|125_帐号类别|123_股东代码|110_委托方式|100_ +交易所代码|294_附加账号|140_证券代码|391_产品代码|510_合约代码|146_委托编号|759_ +合约编号|1217_备注|1207_起始序号|5250_客户群组|5251_客户营业部|5252_硬盘序列号|5 +253_CPUID|5254_信用交易标识|5255_会话号|5256_客户代码| +=============== +140_证券代码|141_证券名称|200_证券数量|5689_合约冻结数量|201_可卖数量|521_持仓量 +|5706_累计盈亏|5734_红利金额|5735_配股金额|1213_保留信息| +*/ +#define REQUEST_KSDQCX_QQ 1304 // 可锁定券查询 备兑券锁定 +/* +120_客户号|134_交易密码|121_资金帐号|125_帐号类别|123_股东代码|110_委托方式|100_ +交易所代码|294_附加账号|140_证券代码|391_产品代码|510_合约代码|146_委托编号|759_ +合约编号|1217_备注|1207_起始序号|5250_客户群组|5251_客户营业部|5252_硬盘序列号|5 +253_CPUID|5254_信用交易标识|5255_会话号|5256_客户代码| +=============== +140_证券代码|141_证券名称|200_证券数量|521_持仓量|1213_保留信息| +*/ +#define REQUEST_KJSQCX_QQ 1306 // 可解锁券查询 备兑券解锁 +/* +120_客户号|134_交易密码|121_资金帐号|125_帐号类别|123_股东代码|110_委托方式|100_ +交易所代码|294_附加账号|140_证券代码|391_产品代码|510_合约代码|146_委托编号|759_ +合约编号|606_批次号|113_操作标志|1217_备注|1207_起始序号|5250_客户群组|5251_客户 +营业部|5252_硬盘序列号|5253_CPUID|5254_信用交易标识|5255_会话号|5256_客户代码| +=============== +142_委托日期|143_委托时间|146_委托编号|140_证券代码|141_证券名称|510_合约代码|51 +1_合约名称|333_方案类型|5683_期权类型|100_交易所代码|131_买卖标志|719_开平标志|5 +685_备兑标记|5705_订单类型|5740_申报结果|145_委托价格|144_委托数量|541_保证金|15 +2_成交数量|154_成交金额|162_撤单数量|123_股东代码|1227_参数|1213_保留信息| +*/ +#define REQUEST_DRWTCX_QQ 1308 // 当日委托查询 +/* +120_客户号|134_交易密码|121_资金帐号|125_帐号类别|123_股东代码|110_委托方式|100_ +交易所代码|294_附加账号|140_证券代码|391_产品代码|510_合约代码|146_委托编号|759_ +合约编号|606_批次号|113_操作标志|1217_备注|1207_起始序号|5250_客户群组|5251_客户 +营业部|5252_硬盘序列号|5253_CPUID|5254_信用交易标识|5255_会话号|5256_客户代码| +=============== +142_委托日期|143_委托时间|146_委托编号|510_合约代码|511_合约名称|140_证券代码|14 +1_证券名称|333_方案类型|5683_期权类型|131_买卖标志|719_开平标志|5685_备兑标记|16 +6_委托方式|145_委托价格|144_委托数量|541_保证金|606_批次号|162_撤单数量|123_股东 +代码|1227_参数|1213_保留信息| +*/ +#define REQUEST_KCLBCX_QQ 1310 // 可撤列表查询 +/* +120_客户号|134_交易密码|121_资金帐号|125_帐号类别|123_股东代码|110_委托方式|100_ +交易所代码|294_附加账号|140_证券代码|391_产品代码|510_合约代码|146_委托编号|759_ +合约编号|606_批次号|113_操作标志|1217_备注|1207_起始序号|5250_客户群组|5251_客户 +营业部|5252_硬盘序列号|5253_CPUID|5254_信用交易标识|5255_会话号|5256_客户代码| +=============== +155_成交编号|146_委托编号|120_客户号|122_客户名称|123_股东代码|510_合约代码|511_ +合约名称|1231_显示颜色|5683_期权类型|131_买卖标志|719_开平标志|5685_备兑标记|100 +_交易所代码|151_成交时间|152_成交数量|153_成交价格|154_成交金额|206_佣金|541_保 +证金|1213_保留信息| +*/ +#define REQUEST_DRCJCX_QQ 1312 // 当日成交查询 +/* +120_客户号|134_交易密码|121_资金帐号|125_帐号类别|123_股东代码|110_委托方式|100_ +交易所代码|294_附加账号|140_证券代码|391_产品代码|510_合约代码|146_委托编号|759_ +合约编号|606_批次号|113_操作标志|126_开始日期|127_终止日期|1217_备注|1207_起始序 +号|5250_客户群组|5251_客户营业部|5252_硬盘序列号|5253_CPUID|5254_信用交易标识|52 +55_会话号|5256_客户代码| +=============== +5700_交易日期|146_委托编号|120_客户号|122_客户名称|142_委托日期|143_委托时间|140 +_证券代码|141_证券名称|510_合约代码|511_合约名称|1231_显示颜色|5683_期权类型|100 +_交易所代码|131_买卖标志|719_开平标志|5685_备兑标记|5705_订单类型|5740_申报结果| +145_委托价格|144_委托数量|541_保证金|152_成交数量|154_成交金额|162_撤单数量|1213 +_保留信息| +*/ +#define REQUEST_LSWTCX_QQ 1314 // 历史委托查询 +/* +120_客户号|134_交易密码|121_资金帐号|125_帐号类别|123_股东代码|110_委托方式|100_ +交易所代码|294_附加账号|140_证券代码|391_产品代码|510_合约代码|146_委托编号|759_ +合约编号|606_批次号|113_操作标志|126_开始日期|127_终止日期|1217_备注|1207_起始序 +号|5250_客户群组|5251_客户营业部|5252_硬盘序列号|5253_CPUID|5254_信用交易标识|52 +55_会话号|5256_客户代码| +=============== +146_委托编号|155_成交编号|120_客户号|122_客户名称|123_股东代码|510_合约代码|511_ +合约名称|1231_显示颜色|5683_期权类型|131_买卖标志|719_开平标志|5685_备兑标记|101 +_交易所名称|150_成交日期|151_成交时间|152_成交数量|153_成交价格|154_成交金额|206 +_佣金|5745_实收金额|1213_保留信息| +*/ +#define REQUEST_LSCJCX_QQ 1316 // 历史成交查询 +/* +120_客户号|134_交易密码|121_资金帐号|125_帐号类别|123_股东代码|110_委托方式|100_ +交易所代码|294_附加账号|140_证券代码|391_产品代码|510_合约代码|146_委托编号|759_ +合约编号|606_批次号|173_席位代码|113_操作标志|126_开始日期|127_终止日期|130_买卖 +标志|1217_备注|1207_起始序号|5250_客户群组|5251_客户营业部|5252_硬盘序列号|5253_ +CPUID|5254_信用交易标识|5255_会话号|5256_客户代码| +=============== +510_合约代码|511_合约名称|391_产品代码|333_方案类型|5683_期权类型|660_报价方式|5 +684_持仓方向|662_使用库存标记|5685_备兑标记|5666_当日平仓成交数量|5667_当日开仓 +成交金额|5668_当日平仓成交金额|5669_当日开仓成交数量|5670_当日平仓委托数量|5671_ +当日开仓委托数量|5698_合约市值|541_保证金|522_开仓日期|5808_到期日期|5769_剩余天 +数|756_历史开可用|5689_合约冻结数量|521_持仓量|200_证券数量|5707_平仓数量|5708_ +开仓数量|528_持仓均价|330_摊薄浮动盈亏|328_摊薄成本价|329_摊薄保本价|5709_平仓金 +额|5710_开仓金额|205_最新市值|203_最新价|123_股东代码|100_交易所代码|1213_保留信 +息| +*/ +#define REQUEST_CYXYCX_QQ 1320 // 可用合约查询 + +////////////////////////////////////////////////////////////////////////// +// 登录部分 + +/* +120_客户号|134_交易密码|121_资金帐号|125_帐号类别|123_股东代码|110_委托方式|100_ +交易所代码|294_附加账号|1217_备注|5250_客户群组|5251_客户营业部|5252_硬盘序列号| +5253_CPUID|5254_信用交易标识|5255_会话号|5256_客户代码| +=============== +120_客户号|122_客户名称|123_股东代码|100_交易所代码|5673_子账户编号| +5674_结算机构|5675_结算账号|132_币种|238_帐户状态| +5676_登记日期|173_席位代码|1213_保留信息| +*/ +#define REQUEST_1318 1318 +/* +120_客户号|134_交易密码|121_资金帐号|125_帐号类别|123_股东代码|110_委托方式|234_ +类型|113_操作标志|736_信息类型|1217_备注|1227_参数|5250_客户群组|5251_客户营业部 +|5252_硬盘序列号|5253_CPUID|5254_信用交易标识|5255_会话号|5256_客户代码| +=============== +1223_检查风险标志|181_风险标志|182_风险说明|450_开户类别|474_指定标志|122_客户名 +称|1227_参数|149_返回信息|142_委托日期|157_合法标志|250_提示信息0|123_股东代码|1 +25_帐号类别|251_提示信息1|252_提示信息2|253_提示信息3|254_提示信息4|255_交易征费 +|256_交易费|257_交易系统使用费|258_股份交收费|259_汇率|1213_保留信息| +*/ +#define REQUEST_140 140 +/* +120_客户号|134_交易密码|121_资金帐号|125_帐号类别|123_股东代码|110_委托方式|1207 +_起始序号|736_信息类型|1227_参数|234_类型|1217_备注|5250_客户群组|5251_客户营业 +部|5252_硬盘序列号|5253_CPUID|5254_信用交易标识|5255_会话号|5256_客户代码| +=============== +149_返回信息|1213_保留信息| +*/ +#define REQUEST_322 322 + +////////////////////////////////////////////////////////////////////////// +// 登录时查询时推出来的请求ID,直接就返回过来了, +/* +120_客户号|134_交易密码|121_资金帐号|125_帐号类别|123_股东代码|1206_客户类别|121 +0_认证方式|1211_认证信息|122_客户名称|454_证件号码|455_移动电话|128_用户联系方式 +|129_用户EMAIL|188_上海股东|189_深圳股东|138_通讯密码|1117_银行代码|1118_银行营 +业部|1119_银行股东代码登录市场|1234_柜台类别|1214_断线重联标志|1230_查询模式|121 +6_VIP标志|1235_机器信息|1243_受限模式|1248_SESSION信息|1257_重定向标志|1258_重定 +向信息|1292_手机机器信息|1297_登录输入参数|1244_机器特征码|1300_客户端内部版本|1 +301_版本字符串| +=============== +120_客户号|122_客户名称|125_帐号类别|411_开放式基金标识|110_委托方式|1212_营业部 +ID|1218_客户权限|149_返回信息|220_客户权限代码|221_客户权限名称|1223_检查风险标 +志|450_开户类别|1224_非交易帐号标志|281_融资融券标识|1291_登录返回参数|251_提示 +信息1|1210_认证方式|1204_MAC地址|1229_描述|1248_SESSION信息|295_信用交易提示信息 +|275_个股期权交易标志|276_OTC交易标志|273_港股通交易标志|250_提示信息0|252_提示 +信息2|1217_备注|1213_保留信息| +*/ +#define RESPONSE_101 101 +#define REQUEST_100 100 +/* +120_客户号|134_交易密码|121_资金帐号|125_帐号类别|123_股东代码|110_委托方式|1117 +_银行代码|1118_银行营业部|1119_银行股东代码登录市场|1234_柜台类别|138_通讯密码|1 +230_查询模式|102_营业部代码|1235_机器信息|1244_机器特征码|1292_手机机器信息| +=============== +5250_客户群组|5251_客户营业部|5252_硬盘序列号|5253_CPUID|5254_信用交易标识|5255_ +会话号|5256_客户代码|1213_保留信息| +*/ +#define RESPONSE_113 113 +#define REQUEST_112 112 +/* +120_客户号|134_交易密码|121_资金帐号|125_帐号类别|123_股东代码|110_委托方式|5250 +_客户群组|5251_客户营业部|5252_硬盘序列号|5253_CPUID|5254_信用交易标识|5255_会话 +号|5256_客户代码| +=============== +120_客户号|281_融资融券标识|411_开放式基金标识|110_委托方式|1213_保留信息| +*/ +#define RESPONSE_149 149 +#define REQUEST_148 148 +/* + +*/ +#define REQUEST_1122 REQUEST_GDLB //(1123-1) +#endif + +/* +全部请求号,与对应的字段数,最大是50,所以约定每行为64 + +100,33 +101,28 +102,18 +103,34 +104,18 +105,7 +106,19 +107,2 +108,16 +109,1 +110,38 +111,7 +112,16 +113,8 +118,17 +119,3 +122,19 +123,3 +132,20 +133,2 +134,21 +135,3 +136,20 +137,6 +138,18 +139,14 +140,18 +141,23 +148,13 +149,5 +150,25 +151,9 +152,15 +153,7 +156,22 +157,3 +158,18 +159,13 +160,17 +161,8 +162,17 +163,12 +164,17 +165,8 +166,13 +167,3 +168,16 +169,1 +170,23 +171,4 +172,9 +173,6 +174,10 +175,6 +200,35 +201,1 +202,50 +203,4 +204,17 +205,2 +250,15 +251,7 +252,14 +253,16 +254,14 +255,18 +256,16 +257,12 +302,16 +303,9 +304,17 +305,5 +316,9 +317,13 +322,18 +323,2 +324,18 +325,18 +326,17 +327,2 +328,22 +329,3 +330,18 +331,9 +332,20 +333,11 +344,15 +345,8 +368,16 +369,9 +500,30 +501,50 +502,17 +503,15 +504,17 +505,7 +506,17 +507,17 +508,17 +509,16 +510,17 +511,11 +512,20 +513,1 +514,19 +515,1 +516,19 +517,1 +518,19 +519,1 +520,20 +521,1 +522,19 +523,15 +524,20 +525,18 +530,17 +531,1 +532,17 +533,1 +534,19 +535,1 +536,17 +537,1 +538,19 +539,1 +540,17 +541,1 +542,17 +543,1 +544,17 +545,1 +546,17 +547,1 +548,19 +549,1 +550,19 +551,1 +580,15 +581,7 +900,40 +901,2 +902,21 +903,11 +904,21 +905,2 +908,13 +909,3 +922,20 +923,10 +944,16 +945,11 +1100,18 +1101,17 +1102,16 +1103,17 +1104,18 +1105,16 +1108,16 +1109,13 +1110,18 +1111,18 +1114,20 +1115,15 +1116,16 +1117,7 +1118,17 +1119,9 +1120,17 +1121,18 +1122,19 +1123,6 +1124,23 +1125,22 +1126,18 +1127,6 +1128,20 +1129,1 +1130,38 +1131,14 +1132,17 +1133,14 +1136,18 +1137,5 +1138,14 +1139,11 +1142,15 +1143,2 +1154,15 +1155,3 +1156,16 +1157,11 +1160,16 +1161,14 +1162,16 +1163,2 +1164,21 +1165,2 +1166,21 +1167,2 +1170,19 +1171,2 +1172,15 +1173,1 +1174,14 +1175,1 +1176,15 +1177,11 +1182,13 +1183,6 +1184,16 +1185,1 +1192,17 +1193,13 +1196,15 +1197,12 +1198,15 +1199,12 +1200,15 +1201,16 +1202,17 +1203,15 +1204,15 +1205,12 +1206,17 +1207,17 +1208,15 +1209,15 +1214,14 +1215,19 +1216,14 +1217,19 +1222,19 +1223,6 +1224,14 +1225,13 +1226,16 +1227,11 +1234,17 +1235,9 +1240,14 +1241,6 +1294,44 +1295,5 +1296,21 +1297,16 +1300,39 +1301,31 +1302,17 +1303,10 +1304,22 +1305,10 +1306,22 +1307,5 +1308,24 +1309,24 +1310,24 +1311,21 +1312,24 +1313,20 +1314,26 +1315,25 +1316,26 +1317,21 +1318,16 +1319,12 +1320,28 +1321,37 +1322,23 +1323,10 +1330,28 +1331,1 +1332,20 +1333,15 +1334,21 +1335,31 +1336,23 +1337,11 +1340,15 +1341,7 +1346,20 +1347,12 +1350,20 +1351,8 +1448,16 +1449,5 +1450,33 +1451,3 +1452,30 +1453,18 +1454,22 +1455,1 +1456,22 +1457,7 +1458,23 +1459,18 +1460,24 +1461,17 +1462,26 +1463,19 +1464,26 +1465,16 +1466,26 +1467,20 +1468,26 +1469,21 +1470,21 +1471,10 +1472,20 +1473,1 +1474,20 +1475,1 +1476,20 +1477,21 +1478,19 +1479,1 +1480,17 +1481,1 +1482,17 +1483,10 +1484,18 +1485,8 +1486,20 +1487,16 +1488,19 +1489,16 +1490,20 +1491,18 +1492,19 +1493,18 +1494,18 +1495,1 +1496,18 +1497,1 +1498,19 +1499,10 +1508,15 +1509,8 +1516,6 +1517,4 +1800,31 +1801,2 +1802,17 +1803,14 +1804,20 +1805,23 +1806,17 +1807,8 +1808,17 +1809,16 +1812,15 +1813,7 +1816,17 +1817,24 +1818,20 +1819,8 +1820,21 +1821,17 +1822,16 +1823,8 +1826,27 +1827,6 +2002,30 +2003,2 +2004,16 +2005,14 +2006,16 +2007,14 +2008,15 +2009,7 +2010,18 +2011,11 +2012,15 +2013,14 +2014,16 +2015,16 +2016,14 +2017,12 +2018,17 +2019,15 +2020,16 +2021,17 +2022,16 +2023,12 +2024,15 +2025,15 +2028,15 +2029,15 +2030,15 +2031,13 +2032,17 +2033,12 +2034,16 +2035,12 +2040,18 +2041,13 +2042,14 +2043,9 +2046,14 +2047,12 +2050,18 +2051,8 +2052,15 +2053,15 +2100,37 +2101,4 +2102,25 +2103,2 +2104,24 +2105,4 +2106,18 +2107,14 +2108,20 +2109,13 +2110,21 +2111,19 +2112,20 +2113,7 +2114,21 +2115,2 +2116,18 +2117,20 +2118,50 +2119,24 +2122,30 +2123,10 +2124,19 +2125,3 +2126,18 +2127,7 +2128,20 +2129,14 +2130,35 +2131,4 +2132,29 +2133,1 +2134,17 +2135,17 +2136,17 +2137,14 +2138,16 +2139,3 +2144,19 +2145,3 +2156,22 +2157,2 +2158,18 +2159,7 +2160,20 +2161,14 +2200,19 +2201,11 +2202,21 +2203,11 +2204,20 +2205,7 +2206,22 +2207,11 +2208,20 +2209,19 +2210,19 +2211,7 +2216,18 +2217,13 +2218,20 +2219,15 +2220,21 +2221,3 +2222,20 +2223,3 +2224,18 +2225,3 +2226,18 +2227,9 +2230,27 +2231,4 +2232,19 +2233,3 +2236,20 +2237,2 +2238,17 +2239,9 +2242,21 +2243,7 +2248,20 +2249,8 +2256,18 +2257,9 +2258,18 +2259,7 +2260,20 +2261,11 +2262,18 +2263,5 +2264,20 +2265,11 +2320,18 +2321,5 +3000,22 +3001,2 +3002,21 +3003,6 +3004,15 +3005,10 +3006,20 +3007,1 +3028,15 +3029,10 +3200,17 +3201,9 +3202,17 +3203,8 +3204,19 +3205,30 +3206,19 +3207,30 +3208,17 +3209,6 +3210,15 +3211,30 +3212,15 +3213,7 +3214,14 +3215,26 +3216,17 +3217,10 +3218,14 +3219,20 +3220,18 +3221,6 +3222,14 +3223,17 +3224,14 +3225,18 +3226,17 +3227,5 +3228,18 +3229,1 +3230,18 +3231,1 +3232,19 +3233,7 +3234,14 +3235,16 +3236,14 +3237,1 +3238,14 +3239,16 +3240,18 +3241,7 +3242,17 +3243,9 +3244,17 +3245,1 +3246,15 +3247,16 +3248,14 +3249,17 +3250,14 +3251,1 +3252,14 +3253,1 +3254,14 +3255,1 +3256,14 +3257,1 +3258,14 +3259,1 +3260,16 +3261,1 +3264,16 +3265,12 +3272,16 +3273,9 +3274,17 +3275,16 +3276,18 +3277,15 +3286,16 +3287,14 +3288,14 +3289,30 +3292,23 +3293,11 +3294,16 +3295,5 +5010,11 +5011,8 +*/ \ No newline at end of file diff --git a/include/Tdx/tdx_struct.h b/include/Tdx/tdx_struct.h new file mode 100644 index 0000000..b556680 --- /dev/null +++ b/include/Tdx/tdx_struct.h @@ -0,0 +1,267 @@ +#pragma once + +#ifndef _TDX_STRUCT_H_ +#define _TDX_STRUCT_H_ + + +// 字段信息,通达信内部定义的,非自定义 +struct FieldInfo_STRUCT +{ + short FieldID; // 字段ID + char a; // 只有a和1两种情况 + char b; // 怎么一直都是2? + char Len; // 好像目前看到最大的是32 + char d; + char e; + char FieldName[25]; // 字段名字 +}; + +// 错误 +struct Error_STRUCT +{ + int ErrType; + int ErrCode; + char ErrInfo[256]; +}; + +// 委托 +struct Order_STRUCT +{ + char ZJZH[32]; // 121_资金帐号 + char GDDM[32]; // 123_股东代码 + char ZQDM[32]; // 140_证券代码 + int ZHLB; // 125_帐号类别 + int RZRQBS; // 281_融资融券标识 + double Price; // 145_委托价格 + long Qty; // 144_委托数量 + long MMBZ; // 130_买卖标志 + long WTFS; // 166_委托方式 + + char ZHLB_[2]; // 125_帐号类别 + // 下完单后用来回填 + char WTBH[32]; // 146_委托编号 +}; + +// 股东列表 +struct GDLB_STRUCT +{ + char GDDM[32]; // 123_股东代码 + char GDMC[32]; // 124_股东名称 + char ZHLB[32]; // 125_帐号类别 + char ZJZH[32]; // 121_资金帐号 + char XWDM[32]; // 173_席位代码 + char RZRQBS[32]; // 281_融资融券标识 + char YMTZH[32]; // 5925_一码通账号 + char BLXX[32]; // 1213_保留信息 + + int ZHLB_; // 125_帐号类别 + int RZRQBS_; // 281_融资融券标识 +}; + +// 当日委托/历史委托=委托列表 +struct WTLB_STRUCT +{ + char WTRQ[32]; // 142_委托日期 + char WTSJ[32]; // 143_委托时间 + char GDDM[32]; // 123_股东代码 + char ZQDM[32]; // 140_证券代码 + char ZQMC[32]; // 141_证券名称 + char MMBZ[32]; // 130_买卖标志 + char WTLB[32]; // 131_委托类别 + char JYSDM[32]; // 100_交易所代码 + char WTJG[32]; // 145_委托价格 + char WTSL[32]; // 144_委托数量 + char CJJG[32]; // 153_成交价格 + char CJSL[32]; // 152_成交数量 + char CDSL[32]; // 162_撤单数量 + char WTBH[32]; // 146_委托编号 + char BJFS[32]; // 194_报价方式 + char ZTSM[32]; // 147_状态说明 + char DJZJ[32]; // 161_冻结资金 + char BLXX[32]; // 1213_保留信息 + + int WTRQ_; + int WTSJ_; + char MMBZ_; + char JYSDM_; + double WTJG_; + int WTSL_; + double CJJG_; + int CJSL_; + int CDSL_; + double DJZJ_; + int ZTSM_; + int BJFS_; +}; + +// 成交列表 +struct CJLB_STRUCT +{ + char CJRQ[32]; // 150_成交日期 + char CJSJ[32]; // 151_成交时间 + char GDDM[32]; // 123_股东代码 + char ZQDM[32]; // 140_证券代码 + char ZQMC[32]; // 141_证券名称 + char MMBZ[32]; // 130_买卖标志 + char WTLB[32]; // 131_委托类别 + char CJJG[32]; // 153_成交价格 + char CJSL[32]; // 152_成交数量 + char FSJE[32]; // 303_发生金额 + char SYJE[32]; // 304_剩余金额 + char YJ[32]; // 206_佣金 + char YHS[32]; // 210_印花税 + char GHF[32]; // 207_过户费 + char CJF[32]; // 208_成交费 + char CJBH[32]; // 155_成交编号 + char CDBZ[32]; // 167_撤单标志 + char WTBH[32]; // 146_委托编号 + + int CJRQ_; + int CJSJ_; + char MMBZ_; + char WTLB_; + double CJJG_; + int CJSL_; + double FSJE_; + double SYJE_; + double YJ_; + double YHS_; + double GHF_; + double CJF_; + char CDBZ_; +}; + + +// 股份列表 +struct GFLB_STRUCT +{ + char ZQDM[32]; // 140_证券代码 + char ZQMC[32]; // 141_证券名称 + char ZQSL[32]; // 200_证券数量 + char KMSL[32]; // 201_可卖数量 + char TBCBJ[32]; // 202_摊簿成本价 + char DQJ[32]; // 949_当前价 + char ZXSZ[32]; // 205_最新市值 + char TBFDYK[32]; // 204_摊簿浮动盈亏 + char SXYK[32]; // 232_实现盈亏 + char CKYKBL[32]; // 230_参考盈亏比例(%) + char DJSL[32]; // 160_冻结数量 + char GDDM[32]; // 123_股东代码 + char JYSDM[32]; // 100_交易所代码 + char JYSMC[32]; // 101_交易所名称 + char BLXX[32]; // 1213_保留信息 + + int ZQSL_; + int KMSL_; + double TBCBJ_; + double DQJ_; + double ZXSZ_; + double DJSL_; +}; + +// 资金余额 +struct ZJYE_STRUCT +{ + char BZ[32]; // 132_币种 + char ZJYE[32]; // 300_资金余额 + char KYZJ[32]; // 301_可用资金 + char ZZC[32]; // 310_总资产 + char KQZJ[32]; // 302_可取资金 + char ZJZH[32]; // 121_资金帐号 + char ZXSZ[32]; // 205_最新市值 + + double ZJYE_; + double KYZJ_; + double ZZC_; + double KQZJ_; + double ZXSZ_; +}; + +struct HQ_STRUCT +{ + char ZQDM[32]; // 140_证券代码 + char ZQMC[32]; // 141_证券名称 + char ZSJ[32]; // 946_昨收价 + char JKJ[32]; // 945_今开价 + char GZLX[32]; // 948_国债利息 + char DQJ[32]; // 949_当前价 + char BidPrice1[32]; // 910_买一价 + char BidPrice2[32]; // 911_买二价 + char BidPrice3[32]; // 912_买三价 + char BidPrice4[32]; // 913_买四价 + char BidPrice5[32]; // 914_买五价 + char BidSize1[32]; // 900_买一量 + char BidSize2[32]; // 901_买二量 + char BidSize3[32]; // 902_买三量 + char BidSize4[32]; // 903_买四量 + char BidSize5[32]; // 904_买五量 + char AskPrice1[32]; // 930_卖一价 + char AskPrice2[32]; // 931_卖二价 + char AskPrice3[32]; // 932_卖三价 + char AskPrice4[32]; // 933_卖四价 + char AskPrice5[32]; // 934_卖五价 + char AskSize1[32]; // 920_卖一量 + char AskSize2[32]; // 921_卖二量 + char AskSize3[32]; // 922_卖三量 + char AskSize4[32]; // 923_卖四量 + char AskSize5[32]; // 924_卖五量 + char JYSDM[32]; // 100_交易所代码 + char ZXJYGS[32]; // 187_最小交易股数 + char ZXMRBDJW[32]; // 226_最小买入变动价位 + char ZXMCBDJW[32]; // 227_最小卖出变动价位 + char ZHLB[32]; // 125_帐号类别 + char BZ[32]; // 132_币种 + char GZBS[32]; // 958_国债标识 + char BLXX[32]; // 1213_保留信息 + char ZTJG[32]; // 940_涨停价格 + char DTJG[32]; // 941_跌停价格 + + double ZSJ_; // 946_昨收价 + double JKJ_; // 945_今开价 + double GZLX_; // 948_国债利息 + double DQJ_; // 949_当前价 + double BidPrice1_; // 910_买一价 + double BidPrice2_; // 911_买二价 + double BidPrice3_; // 912_买三价 + double BidPrice4_; // 913_买四价 + double BidPrice5_; // 914_买五价 + int BidSize1_; // 900_买一量 + int BidSize2_; // 901_买二量 + int BidSize3_; // 902_买三量 + int BidSize4_; // 903_买四量 + int BidSize5_; // 904_买五量 + double AskPrice1_; // 930_卖一价 + double AskPrice2_; // 931_卖二价 + double AskPrice3_; // 932_卖三价 + double AskPrice4_; // 933_卖四价 + double AskPrice5_; // 934_卖五价 + int AskSize1_; // 920_卖一量 + int AskSize2_; // 921_卖二量 + int AskSize3_; // 922_卖三量 + int AskSize4_; // 923_卖四量 + int AskSize5_; // 924_卖五量 + + int ZXJYGS_; // 187_最小交易股数 + double ZXMRBDJW_; // 226_最小买入变动价位 + double ZXMCBDJW_; // 227_最小卖出变动价位 + double ZTJG_; // 940_涨停价格 + double DTJG_; // 941_跌停价格 +}; + +// +//////////////////////////////////////////////////////////////////////////// +//// 以下的在整理完后要删除 +// + + +// 登录结果 +struct DLJG_STRUCT +{ + char COL1[128]; + char COL2[128]; + char COL3[128]; +}; + +#endif + + diff --git a/include/Tdx/win32/EasyHook32.dll b/include/Tdx/win32/EasyHook32.dll new file mode 100644 index 0000000..24b6852 Binary files /dev/null and b/include/Tdx/win32/EasyHook32.dll differ diff --git a/include/Tdx/win32/TdxApi.dll b/include/Tdx/win32/TdxApi.dll new file mode 100644 index 0000000..3fba89b Binary files /dev/null and b/include/Tdx/win32/TdxApi.dll differ diff --git a/include/Tdx/win32/TdxApi.lib b/include/Tdx/win32/TdxApi.lib new file mode 100644 index 0000000..890b265 Binary files /dev/null and b/include/Tdx/win32/TdxApi.lib differ diff --git a/include/Tdx/win32/TdxApiDemo.exe b/include/Tdx/win32/TdxApiDemo.exe new file mode 100644 index 0000000..de0f3d0 Binary files /dev/null and b/include/Tdx/win32/TdxApiDemo.exe differ diff --git a/include/Tdx/win32/TdxInjector.exe b/include/Tdx/win32/TdxInjector.exe new file mode 100644 index 0000000..866142b Binary files /dev/null and b/include/Tdx/win32/TdxInjector.exe differ diff --git a/include/Tdx/win32/login.ini b/include/Tdx/win32/login.ini new file mode 100644 index 0000000..d14350c --- /dev/null +++ b/include/Tdx/win32/login.ini @@ -0,0 +1,6 @@ +[INIT] +TdxPath=D:\new_hbzq_qq\ +LuaFile=D:\new_hbzq_qq\Login.lua +[LOGIN] +Account=05000000000 +Password=123456 \ No newline at end of file diff --git a/include/Tdx/win32/lua53.dll b/include/Tdx/win32/lua53.dll new file mode 100644 index 0000000..af5169b Binary files /dev/null and b/include/Tdx/win32/lua53.dll differ