diff --git a/.gitignore b/.gitignore index 15d7ed33..5af6d235 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ *.wpr *.wpu .vs +x64 # Temp build diff --git a/vnpy/api/ctp/vnctp/vnctp.h b/vnpy/api/ctp/vnctp/vnctp.h index c1d067ec..23050d51 100644 --- a/vnpy/api/ctp/vnctp/vnctp.h +++ b/vnpy/api/ctp/vnctp/vnctp.h @@ -103,35 +103,35 @@ void getString(const pybind11::dict &d, const char *key, string_literal &v if (d.contains(key)) { object o = d[key]; - std::string s = o.cast(); + string s = o.cast(); const char *buf = s.c_str(); strcpy(value, buf); } }; //将GBK编码的字符串转换为UTF8 -inline std::string toUtf(const std::string &gb2312) +inline string toUtf(const string &gb2312) { #ifdef _MSC_VER - const static std::locale loc("zh-CN"); + const static locale loc("zh-CN"); #else - const static std::locale loc("zh_CN.GB18030"); + const static locale loc("zh_CN.GB18030"); #endif - std::vector wstr(gb2312.size()); + vector wstr(gb2312.size()); wchar_t* wstrEnd = nullptr; const char* gbEnd = nullptr; - std::mbstate_t state = {}; - int res = std::use_facet > + mbstate_t state = {}; + int res = use_facet > (loc).in(state, gb2312.data(), gb2312.data() + gb2312.size(), gbEnd, wstr.data(), wstr.data() + wstr.size(), wstrEnd); - if (std::codecvt_base::ok == res) + if (codecvt_base::ok == res) { - std::wstring_convert> cutf8; - return cutf8.to_bytes(std::wstring(wstr.data(), wstrEnd)); + wstring_convert> cutf8; + return cutf8.to_bytes(wstring(wstr.data(), wstrEnd)); } - return std::string(); + return string(); } diff --git a/vnpy/api/ctp/vnctp/vnctpmd/vnctpmd.cpp b/vnpy/api/ctp/vnctp/vnctpmd/vnctpmd.cpp index 1f461275..d85494b3 100644 --- a/vnpy/api/ctp/vnctp/vnctpmd/vnctpmd.cpp +++ b/vnpy/api/ctp/vnctp/vnctpmd/vnctpmd.cpp @@ -563,7 +563,9 @@ int MdApi::join() int MdApi::exit() { - //该函数在原生API里没有,用于安全退出API用,原生的join似乎不太稳定 + this->active = false; + //this->task_thread.join(); + this->api->RegisterSpi(NULL); this->api->Release(); this->api = NULL; diff --git a/vnpy/api/ctp/vnctp/vnctpmd/vnctpmd.vcxproj b/vnpy/api/ctp/vnctp/vnctpmd/vnctpmd.vcxproj index 5b750883..7a830fb8 100644 --- a/vnpy/api/ctp/vnctp/vnctpmd/vnctpmd.vcxproj +++ b/vnpy/api/ctp/vnctp/vnctpmd/vnctpmd.vcxproj @@ -23,7 +23,7 @@ {F00054FF-282F-4826-848E-D58BFB9E9D9F} Win32Proj vnctpmd - 10.0.17763.0 + 10.0.17134.0 diff --git a/vnpy/api/ctp/vnctp/vnctptd/vnctptd.cpp b/vnpy/api/ctp/vnctp/vnctptd/vnctptd.cpp index d3b106a9..5d0ea59e 100644 --- a/vnpy/api/ctp/vnctp/vnctptd/vnctptd.cpp +++ b/vnpy/api/ctp/vnctp/vnctptd/vnctptd.cpp @@ -7914,7 +7914,9 @@ int TdApi::join() int TdApi::exit() { - //该函数在原生API里没有,用于安全退出API用,原生的join似乎不太稳定 + this->active = false; + //this->task_thread.join(); + this->api->RegisterSpi(NULL); this->api->Release(); this->api = NULL; diff --git a/vnpy/api/ctp/vnctp/vnctptd/vnctptd.vcxproj b/vnpy/api/ctp/vnctp/vnctptd/vnctptd.vcxproj index 027a210f..d0acf4ac 100644 --- a/vnpy/api/ctp/vnctp/vnctptd/vnctptd.vcxproj +++ b/vnpy/api/ctp/vnctp/vnctptd/vnctptd.vcxproj @@ -23,7 +23,7 @@ {016732E6-5789-4F7C-9A1C-C46A249080CF} Win32Proj vnctptd - 10.0.17763.0 + 10.0.17134.0 diff --git a/vnpy/api/ctp/vnctpmd.pyd b/vnpy/api/ctp/vnctpmd.pyd index aa287d78..06804964 100644 Binary files a/vnpy/api/ctp/vnctpmd.pyd and b/vnpy/api/ctp/vnctpmd.pyd differ diff --git a/vnpy/api/ctp/vnctptd.pyd b/vnpy/api/ctp/vnctptd.pyd index 8f945149..41fcc880 100644 Binary files a/vnpy/api/ctp/vnctptd.pyd and b/vnpy/api/ctp/vnctptd.pyd differ diff --git a/vnpy/gateway/ctp/ctp_gateway.py b/vnpy/gateway/ctp/ctp_gateway.py index 1129d897..29e4b2f7 100644 --- a/vnpy/gateway/ctp/ctp_gateway.py +++ b/vnpy/gateway/ctp/ctp_gateway.py @@ -2,7 +2,6 @@ """ """ -from copy import copy from datetime import datetime from vnpy.api.ctp import * @@ -212,11 +211,7 @@ class CtpMdApi(MdApi): self.connect_status = False self.login_status = False self.gateway.write_log(f"琛屾儏杩炴帴鏂紑锛屽師鍥爗reason}") - - def onHeartBeatWarning(self, n: int): - """""" - pass - + def onRspUserLogin(self, data: dict, error: dict, reqid: int, last: bool): """ Callback when user is logged in. @@ -230,10 +225,6 @@ class CtpMdApi(MdApi): else: self.gateway.write_error("琛屾儏鐧诲綍澶辫触", error) - def onRspUserLogout(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - def onRspError(self, error: dict, reqid: int, last: bool): """ Callback when error occured. @@ -246,19 +237,7 @@ class CtpMdApi(MdApi): return self.gateway.write_error("琛屾儏璁㈤槄澶辫触", error) - - def onRspUnSubMarketData(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspSubForQuoteRsp(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspUnSubForQuoteRsp(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - + def onRtnDepthMarketData(self, data: dict): """ Callback of tick data update. @@ -274,7 +253,7 @@ class CtpMdApi(MdApi): symbol=symbol, exchange=exchange, datetime=datetime.strptime(timestamp, "%Y%m%d %H:%M:%S.%f"), - name = symbol_name_map[symbol], + name=symbol_name_map[symbol], volume=data["Volume"], last_price=data["LastPrice"], limit_up=data["UpperLimitPrice"], @@ -289,11 +268,7 @@ class CtpMdApi(MdApi): ask_volume_1=data["AskVolume1"], gateway_name=self.gateway_name ) - self.gateway.on_tick(tick) - - def onRtnForQuoteRsp(self, data: dict): - """""" - pass + self.gateway.on_tick(tick) def connect(self, address: str, userid: str, password: str, brokerid: int): """ @@ -343,9 +318,6 @@ class CtpMdApi(MdApi): self.exit() - - - class CtpTdApi(TdApi): """""" @@ -394,10 +366,6 @@ class CtpTdApi(TdApi): self.login_status = False self.gateway.write_log(f"浜ゆ槗杩炴帴鏂紑锛屽師鍥爗reason}") - def onHeartBeatWarning(self, n: int): - """""" - pass - def onRspAuthenticate(self, data: dict, error: dict, reqid: int, last: bool): """""" if not error['ErrorID']: @@ -427,30 +395,6 @@ class CtpTdApi(TdApi): self.gateway.write_error("浜ゆ槗鐧诲綍澶辫触", error) - def onRspUserLogout(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspUserPasswordUpdate(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspTradingAccountPasswordUpdate(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspUserAuthMethod(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspGenUserCaptcha(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspGenUserText(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - def onRspOrderInsert(self, data: dict, error: dict, reqid: int, last: bool): """""" order_ref = data["OrderRef"] @@ -474,14 +418,6 @@ class CtpTdApi(TdApi): self.gateway.write_error("浜ゆ槗濮旀墭澶辫触", error) - def onRspParkedOrderInsert(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspParkedOrderAction(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - def onRspOrderAction(self, data: dict, error: dict, reqid: int, last: bool): """""" self.gateway.write_error("浜ゆ槗鎾ゅ崟澶辫触", error) @@ -498,58 +434,6 @@ class CtpTdApi(TdApi): self.reqid += 1 self.reqQryInstrument({}, self.reqid) - - def onRspRemoveParkedOrder(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspRemoveParkedOrderAction(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspExecOrderInsert(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspExecOrderAction(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspForQuoteInsert(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspQuoteInsert(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspQuoteAction(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspBatchOrderAction(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspOptionSelfCloseInsert(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspOptionSelfCloseAction(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspCombActionInsert(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspQryOrder(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspQryTrade(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass def onRspQryInvestorPosition(self, data: dict, error: dict, reqid: int, last: bool): """""" @@ -612,39 +496,19 @@ class CtpTdApi(TdApi): self.gateway.on_account(account) - def onRspQryInvestor(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspQryTradingCode(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspQryInstrumentMarginRate(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspQryInstrumentCommissionRate(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspQryExchange(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspQryProduct(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - def onRspQryInstrument(self, data: dict, error: dict, reqid: int, last: bool): """ Callback of instrument query. """ + product = PRODUCT_CTP2VT.get(data["ProductClass"], None) + if not product: + return + contract = ContractData( symbol=data["InstrumentID"], exchange=EXCHANGE_CTP2VT[data["ExchangeID"]], name=data["InstrumentName"], - product=PRODUCT_CTP2VT[data["ProductClass"]], + product=product, size=data["VolumeMultiple"], pricetick=data["PriceTick"], option_underlying=data["UnderlyingInstrID"], @@ -671,142 +535,6 @@ class CtpTdApi(TdApi): self.onRtnTrade(data) self.trade_data.clear() - def onRspQryDepthMarketData(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspQrySettlementInfo(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspQryTransferBank(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspQryInvestorPositionDetail(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspQryNotice(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspQrySettlementInfoConfirm(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspQryInvestorPositionCombineDetail(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspQryCFMMCTradingAccountKey(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspQryEWarrantOffset(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspQryInvestorProductGroupMargin(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspQryExchangeMarginRate(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspQryExchangeMarginRateAdjust(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspQryExchangeRate(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspQrySecAgentACIDMap(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspQryProductExchRate(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspQryProductGroup(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspQryMMInstrumentCommissionRate(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspQryMMOptionInstrCommRate(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspQryInstrumentOrderCommRate(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspQrySecAgentTradingAccount(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspQrySecAgentCheckMode(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspQrySecAgentTradeInfo(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspQryOptionInstrTradeCost(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspQryOptionInstrCommRate(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspQryExecOrder(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspQryForQuote(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspQryQuote(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspQryOptionSelfClose(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspQryInvestUnit(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspQryCombInstrumentGuard(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspQryCombAction(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspQryTransferSerial(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspQryAccountregister(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspError(self, error: dict, reqid: int, last: bool): - """""" - pass - def onRtnOrder(self, data: dict): """ Callback of order status update. @@ -865,206 +593,6 @@ class CtpTdApi(TdApi): ) self.gateway.on_trade(trade) - def onErrRtnOrderInsert(self, data: dict, error: dict): - """""" - pass - - def onErrRtnOrderAction(self, data: dict, error: dict): - """""" - pass - - def onRtnInstrumentStatus(self, data: dict): - """""" - pass - - def onRtnBulletin(self, data: dict): - """""" - pass - - def onRtnTradingNotice(self, data: dict): - """""" - pass - - def onRtnErrorConditionalOrder(self, data: dict): - """""" - pass - - def onRtnExecOrder(self, data: dict): - """""" - pass - - def onErrRtnExecOrderInsert(self, data: dict, error: dict): - """""" - pass - - def onErrRtnExecOrderAction(self, data: dict, error: dict): - """""" - pass - - def onErrRtnForQuoteInsert(self, data: dict, error: dict): - """""" - pass - - def onRtnQuote(self, data: dict): - """""" - pass - - def onErrRtnQuoteInsert(self, data: dict, error: dict): - """""" - pass - - def onErrRtnQuoteAction(self, data: dict, error: dict): - """""" - pass - - def onRtnForQuoteRsp(self, data: dict): - """""" - pass - - def onRtnCFMMCTradingAccountToken(self, data: dict): - """""" - pass - - def onErrRtnBatchOrderAction(self, data: dict, error: dict): - """""" - pass - - def onRtnOptionSelfClose(self, data: dict): - """""" - pass - - def onErrRtnOptionSelfCloseInsert(self, data: dict, error: dict): - """""" - pass - - def onErrRtnOptionSelfCloseAction(self, data: dict, error: dict): - """""" - pass - - def onRtnCombAction(self, data: dict): - """""" - pass - - def onErrRtnCombActionInsert(self, data: dict, error: dict): - """""" - pass - - def onRspQryContractBank(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspQryParkedOrder(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspQryParkedOrderAction(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspQryTradingNotice(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspQryBrokerTradingParams(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspQryBrokerTradingAlgos(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspQueryCFMMCTradingAccountToken(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRtnFromBankToFutureByBank(self, data: dict): - """""" - pass - - def onRtnFromFutureToBankByBank(self, data: dict): - """""" - pass - - def onRtnRepealFromBankToFutureByBank(self, data: dict): - """""" - pass - - def onRtnRepealFromFutureToBankByBank(self, data: dict): - """""" - pass - - def onRtnFromBankToFutureByFuture(self, data: dict): - """""" - pass - - def onRtnFromFutureToBankByFuture(self, data: dict): - """""" - pass - - def onRtnRepealFromBankToFutureByFutureManual(self, data: dict): - """""" - pass - - def onRtnRepealFromFutureToBankByFutureManual(self, data: dict): - """""" - pass - - def onRtnQueryBankBalanceByFuture(self, data: dict): - """""" - pass - - def onErrRtnBankToFutureByFuture(self, data: dict, error: dict): - """""" - pass - - def onErrRtnFutureToBankByFuture(self, data: dict, error: dict): - """""" - pass - - def onErrRtnRepealBankToFutureByFutureManual(self, data: dict, error: dict): - """""" - pass - - def onErrRtnRepealFutureToBankByFutureManual(self, data: dict, error: dict): - """""" - pass - - def onErrRtnQueryBankBalanceByFuture(self, data: dict, error: dict): - """""" - pass - - def onRtnRepealFromBankToFutureByFuture(self, data: dict): - """""" - pass - - def onRtnRepealFromFutureToBankByFuture(self, data: dict): - """""" - pass - - def onRspFromBankToFutureByFuture(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspFromFutureToBankByFuture(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRspQueryBankAccountMoneyByFuture(self, data: dict, error: dict, reqid: int, last: bool): - """""" - pass - - def onRtnOpenAccountByBank(self, data: dict): - """""" - pass - - def onRtnCancelAccountByBank(self, data: dict): - """""" - pass - - def onRtnChangeAccountByBank(self, data: dict): - """""" - pass - def connect(self, address: str, userid: str, password: str, brokerid: int, auth_code: str, product_info: str): """ Start connection to server. @@ -1107,11 +635,11 @@ class CtpTdApi(TdApi): """ if self.login_failed: return - + req = { "UserID": self.userid, "Password": self.password, - "BrokerID": self.brokerid, + "BrokerID": self.brokerid } self.reqid += 1