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