1- #include " stdafx.h"
1+ #include " stdafx.h"
22#include " MdUserApi.h"
33#include " ../include/QueueEnum.h"
44
55#include " ../include/ApiHeader.h"
66#include " ../include/ApiStruct.h"
77
88#include " ../include/toolkit.h"
9+ #include " ../QuantBox_CTP_Trade/TypeConvert.h"
910
1011#include " ../QuantBox_Queue/MsgQueue.h"
1112#ifdef _REMOTE
@@ -21,7 +22,7 @@ using namespace std;
2122
2223void * __stdcall Query (char type, void * pApi1, void * pApi2, double double1, double double2, void * ptr1, int size1, void * ptr2, int size2, void * ptr3, int size3)
2324{
24- // 由内部调用,不用检查是否为空
25+ // 由内部调用,不用检查是否为空
2526 CMdUserApi* pApi = (CMdUserApi*)pApi2;
2627 pApi->QueryInThread (type, pApi1, pApi2, double1, double2, ptr1, size1, ptr2, size2, ptr3, size3);
2728 return nullptr ;
@@ -33,7 +34,7 @@ CMdUserApi::CMdUserApi(void)
3334 m_lRequestID = 0 ;
3435 m_nSleep = 1 ;
3536
36- // 自己维护两个消息队列
37+ // 自己维护两个消息队列
3738 m_msgQueue = new CMsgQueue ();
3839 m_msgQueue_Query = new CMsgQueue ();
3940
@@ -67,13 +68,13 @@ void CMdUserApi::QueryInThread(char type, void* pApi1, void* pApi2, double doubl
6768
6869 if (0 == iRet)
6970 {
70- // 返回成功,填加到已发送池
71+ // 返回成功,填加到已发送池
7172 m_nSleep = 1 ;
7273 }
7374 else
7475 {
7576 m_msgQueue_Query->Input_Copy (type, pApi1, pApi2, double1, double2, ptr1, size1, ptr2, size2, ptr3, size3);
76- // 失败,按4的幂进行延时,但不超过1s
77+ // 失败,按4的幂进行延时,但不超过1s
7778 m_nSleep *= 4 ;
7879 m_nSleep %= 1023 ;
7980 }
@@ -140,7 +141,7 @@ void CMdUserApi::Connect(const string& szPath,
140141 nullptr , 0 , nullptr , 0 , nullptr , 0 );
141142
142143#ifdef _REMOTE
143- // 将收到的行情通过ZeroMQ发送出去
144+ // 将收到的行情通过ZeroMQ发送出去
144145 if (strlen (m_ServerInfo.ExtendInformation ) > 0 )
145146 {
146147 m_remoteQueue = new CRemoteQueue (m_ServerInfo.ExtendInformation );
@@ -165,7 +166,7 @@ int CMdUserApi::_Init()
165166 {
166167 m_pApi->RegisterSpi (this );
167168
168- // 添加地址
169+ // 添加地址
169170 size_t len = strlen (m_ServerInfo.Address ) + 1 ;
170171 char * buf = new char [len];
171172 strncpy (buf, m_ServerInfo.Address , len);
@@ -181,7 +182,7 @@ int CMdUserApi::_Init()
181182 }
182183 delete[] buf;
183184
184- // 初始化连接
185+ // 初始化连接
185186 m_pApi->Init ();
186187 m_msgQueue->Input_NoCopy (ResponeType::OnConnectionStatus, m_msgQueue, m_pClass, ConnectionStatus::Connecting, 0 , nullptr , 0 , nullptr , 0 , nullptr , 0 );
187188 }
@@ -209,7 +210,7 @@ int CMdUserApi::_ReqUserLogin(char type, void* pApi1, void* pApi2, double double
209210
210211void CMdUserApi::Disconnect ()
211212{
212- // 清理查询队列
213+ // 清理查询队列
213214 if (m_msgQueue_Query)
214215 {
215216 m_msgQueue_Query->StopThread ();
@@ -225,14 +226,14 @@ void CMdUserApi::Disconnect()
225226 m_pApi->Release ();
226227 m_pApi = NULL ;
227228
228- // 全清理,只留最后一个
229+ // 全清理,只留最后一个
229230 m_msgQueue->Clear ();
230231 m_msgQueue->Input_NoCopy (ResponeType::OnConnectionStatus, m_msgQueue, m_pClass, ConnectionStatus::Disconnected, 0 , nullptr , 0 , nullptr , 0 , nullptr , 0 );
231- // 主动触发
232+ // 主动触发
232233 m_msgQueue->Process ();
233234 }
234235
235- // 清理响应队列
236+ // 清理响应队列
236237 if (m_msgQueue)
237238 {
238239 m_msgQueue->StopThread ();
@@ -242,7 +243,7 @@ void CMdUserApi::Disconnect()
242243 m_msgQueue = nullptr ;
243244 }
244245
245- // 清理队列
246+ // 清理队列
246247 if (m_remoteQueue)
247248 {
248249 m_remoteQueue->StopThread ();
@@ -267,14 +268,14 @@ void CMdUserApi::Subscribe(const string& szInstrumentIDs, const string& szExchag
267268
268269 if (vct.size ()>0 )
269270 {
270- // 转成字符串数组
271+ // 转成字符串数组
271272 char ** pArray = new char *[vct.size ()];
272273 for (size_t j = 0 ; j<vct.size (); ++j)
273274 {
274275 pArray[j] = vct[j];
275276 }
276277
277- // 订阅
278+ // 订阅
278279 m_pApi->SubscribeMarketData (pArray,(int )vct.size ());
279280
280281 delete[] pArray;
@@ -313,14 +314,14 @@ void CMdUserApi::Unsubscribe(const string& szInstrumentIDs, const string& szExch
313314
314315 if (vct.size ()>0 )
315316 {
316- // 转成字符串数组
317+ // 转成字符串数组
317318 char ** pArray = new char *[vct.size ()];
318319 for (size_t j = 0 ; j<vct.size (); ++j)
319320 {
320321 pArray[j] = vct[j];
321322 }
322323
323- // 订阅
324+ // 订阅
324325 m_pApi->UnSubscribeMarketData (pArray,(int )vct.size ());
325326
326327 delete[] pArray;
@@ -341,14 +342,14 @@ void CMdUserApi::SubscribeQuote(const string& szInstrumentIDs, const string& szE
341342
342343 if (vct.size ()>0 )
343344 {
344- // 转成字符串数组
345+ // 转成字符串数组
345346 char ** pArray = new char *[vct.size ()];
346347 for (size_t j = 0 ; j<vct.size (); ++j)
347348 {
348349 pArray[j] = vct[j];
349350 }
350351
351- // 订阅
352+ // 订阅
352353 m_pApi->SubscribeForQuoteRsp (pArray, (int )vct.size ());
353354
354355 delete[] pArray;
@@ -387,14 +388,14 @@ void CMdUserApi::UnsubscribeQuote(const string& szInstrumentIDs, const string& s
387388
388389 if (vct.size ()>0 )
389390 {
390- // 转成字符串数组
391+ // 转成字符串数组
391392 char ** pArray = new char *[vct.size ()];
392393 for (size_t j = 0 ; j<vct.size (); ++j)
393394 {
394395 pArray[j] = vct[j];
395396 }
396397
397- // 订阅
398+ // 订阅
398399 m_pApi->UnSubscribeForQuoteRsp (pArray, (int )vct.size ());
399400
400401 delete[] pArray;
@@ -406,14 +407,14 @@ void CMdUserApi::OnFrontConnected()
406407{
407408 m_msgQueue->Input_NoCopy (ResponeType::OnConnectionStatus, m_msgQueue, m_pClass, ConnectionStatus::Connected, 0 , nullptr , 0 , nullptr , 0 , nullptr , 0 );
408409
409- // 连接成功后自动请求登录
410+ // 连接成功后自动请求登录
410411 ReqUserLogin ();
411412}
412413
413414void CMdUserApi::OnFrontDisconnected (int nReason)
414415{
415416 RspUserLoginField* pField = (RspUserLoginField*)m_msgQueue->new_block (sizeof (RspUserLoginField));
416- // 连接失败返回的信息是拼接而成,主要是为了统一输出
417+ // 连接失败返回的信息是拼接而成,主要是为了统一输出
417418 pField->ErrorID = nReason;
418419 GetOnFrontDisconnectedMsg (nReason, pField->ErrorMsg );
419420
@@ -429,20 +430,21 @@ void CMdUserApi::OnRspUserLogin(CThostFtdcRspUserLoginField *pRspUserLogin, CTho
429430 {
430431 pField->TradingDay = GetDate (pRspUserLogin->TradingDay );
431432 pField->LoginTime = GetTime (pRspUserLogin->LoginTime );
433+ m_TradingDay = pField->TradingDay ;
432434
433435 sprintf (pField->SessionID , " %d:%d" , pRspUserLogin->FrontID , pRspUserLogin->SessionID );
434436
435437 m_msgQueue->Input_NoCopy (ResponeType::OnConnectionStatus, m_msgQueue, m_pClass, ConnectionStatus::Logined, 0 , pField, sizeof (RspUserLoginField), nullptr , 0 , nullptr , 0 );
436438 m_msgQueue->Input_NoCopy (ResponeType::OnConnectionStatus, m_msgQueue, m_pClass, ConnectionStatus::Done, 0 , nullptr , 0 , nullptr , 0 , nullptr , 0 );
437439
438- // 有可能断线了,本处是断线重连后重新订阅
439- set<string> mapOld = m_setInstrumentIDs;// 记下上次订阅的合约
440- // Unsubscribe(mapOld);//由于已经断线了,没有必要再取消订阅
441- Subscribe (mapOld," " );// 订阅
440+ // 有可能断线了,本处是断线重连后重新订阅
441+ set<string> mapOld = m_setInstrumentIDs;// 记下上次订阅的合约
442+ // Unsubscribe(mapOld);//由于已经断线了,没有必要再取消订阅
443+ Subscribe (mapOld," " );// 订阅
442444
443- // 有可能断线了,本处是断线重连后重新订阅
444- mapOld = m_setQuoteInstrumentIDs;// 记下上次订阅的合约
445- SubscribeQuote (mapOld, " " );// 订阅
445+ // 有可能断线了,本处是断线重连后重新订阅
446+ mapOld = m_setQuoteInstrumentIDs;// 记下上次订阅的合约
447+ SubscribeQuote (mapOld, " " );// 订阅
446448 }
447449 else
448450 {
@@ -460,7 +462,7 @@ void CMdUserApi::OnRspError(CThostFtdcRspInfoField *pRspInfo, int nRequestID, bo
460462
461463void CMdUserApi::OnRspSubMarketData (CThostFtdcSpecificInstrumentField *pSpecificInstrument, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
462464{
463- // 在模拟平台可能这个函数不会触发,所以要自己维护一张已经订阅的合约列表
465+ // 在模拟平台可能这个函数不会触发,所以要自己维护一张已经订阅的合约列表
464466 if (!IsErrorRspInfo (pRspInfo,nRequestID,bIsLast)
465467 &&pSpecificInstrument)
466468 {
@@ -472,7 +474,7 @@ void CMdUserApi::OnRspSubMarketData(CThostFtdcSpecificInstrumentField *pSpecific
472474
473475void CMdUserApi::OnRspUnSubMarketData (CThostFtdcSpecificInstrumentField *pSpecificInstrument, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
474476{
475- // 模拟平台可能这个函数不会触发
477+ // 模拟平台可能这个函数不会触发
476478 if (!IsErrorRspInfo (pRspInfo,nRequestID,bIsLast)
477479 &&pSpecificInstrument)
478480 {
@@ -482,24 +484,37 @@ void CMdUserApi::OnRspUnSubMarketData(CThostFtdcSpecificInstrumentField *pSpecif
482484 }
483485}
484486
485- // 行情回调,得保证此函数尽快返回
487+ // 行情回调,得保证此函数尽快返回
486488void CMdUserApi::OnRtnDepthMarketData (CThostFtdcDepthMarketDataField *pDepthMarketData)
487489{
488490 // for (int i = 0; i < 50; ++i)
489491 // {
490- // // 测试平台穿越速度,用完后需要注释掉
492+ // // 测试平台穿越速度,用完后需要注释掉
491493 // WriteLog("CTP:OnRtnDepthMarketData:%s %f %s.%03d", pDepthMarketData->InstrumentID, pDepthMarketData->LastPrice, pDepthMarketData->UpdateTime, pDepthMarketData->UpdateMillisec);
492494
493495 DepthMarketDataField* pField = (DepthMarketDataField*)m_msgQueue->new_block (sizeof (DepthMarketDataField));
494496
495497 strcpy (pField->InstrumentID , pDepthMarketData->InstrumentID );
496- strcpy ( pField->ExchangeID , pDepthMarketData->ExchangeID );
498+ pField->Exchange = TThostFtdcExchangeIDType_2_ExchangeType ( pDepthMarketData->ExchangeID );
497499
498- sprintf (pField->Symbol , " %s.%s" , pField->InstrumentID , pField ->ExchangeID );
500+ sprintf (pField->Symbol , " %s.%s" , pField->InstrumentID , pDepthMarketData ->ExchangeID );
499501
500- // TODO:CTP大连没有ActionDay,所以API中是将TradingDay填到了这里,所以这里这种用法可能会出错,要测
501- GetExchangeTime (pDepthMarketData->TradingDay , pDepthMarketData->ActionDay , pDepthMarketData->UpdateTime
502- , &pField->TradingDay , &pField->ActionDay , &pField->UpdateTime , &pField->UpdateMillisec );
502+ // m_TradingDay
503+ switch (pField->Exchange )
504+ {
505+ case ExchangeType::DCE:
506+ GetExchangeTime_DCE (pDepthMarketData->TradingDay , pDepthMarketData->ActionDay , pDepthMarketData->UpdateTime
507+ , &pField->TradingDay , &pField->ActionDay , &pField->UpdateTime , &pField->UpdateMillisec );
508+ break ;
509+ case ExchangeType::CZCE:
510+ GetExchangeTime_CZCE (m_TradingDay, pDepthMarketData->TradingDay , pDepthMarketData->ActionDay , pDepthMarketData->UpdateTime
511+ , &pField->TradingDay , &pField->ActionDay , &pField->UpdateTime , &pField->UpdateMillisec );
512+ break ;
513+ default :
514+ GetExchangeTime (pDepthMarketData->TradingDay , pDepthMarketData->ActionDay , pDepthMarketData->UpdateTime
515+ , &pField->TradingDay , &pField->ActionDay , &pField->UpdateTime , &pField->UpdateMillisec );
516+ break ;
517+ }
503518
504519 pField->UpdateMillisec = pDepthMarketData->UpdateMillisec ;
505520
@@ -585,8 +600,8 @@ void CMdUserApi::OnRtnDepthMarketData(CThostFtdcDepthMarketDataField *pDepthMark
585600 pField->AskVolume5 = pDepthMarketData->AskVolume5 ;
586601 } while (false );
587602
588- // 这两个队列先头循序不要搞混,有删除功能的语句要放在后面
589- // 如果放前面,会导致远程收到乱码
603+ // 这两个队列先头循序不要搞混,有删除功能的语句要放在后面
604+ // 如果放前面,会导致远程收到乱码
590605#ifdef _REMOTE
591606 if (m_remoteQueue)
592607 {
@@ -595,7 +610,7 @@ void CMdUserApi::OnRtnDepthMarketData(CThostFtdcDepthMarketDataField *pDepthMark
595610#endif
596611
597612 m_msgQueue->Input_NoCopy (ResponeType::OnRtnDepthMarketData, m_msgQueue, m_pClass, 0 , 0 , pField, sizeof (DepthMarketDataField), nullptr , 0 , nullptr , 0 );
598- // 要关注一下其内的
613+ // 要关注一下其内的
599614 // }
600615}
601616
@@ -623,7 +638,7 @@ void CMdUserApi::OnRspUnSubForQuoteRsp(CThostFtdcSpecificInstrumentField *pSpeci
623638
624639void CMdUserApi::OnRtnForQuoteRsp (CThostFtdcForQuoteRspField *pForQuoteRsp)
625640{
626- // 上期技术的人说,上海中金走的交易接口,大商,郑商走行情,所以这个地方后期可能要改
641+ // 上期技术的人说,上海中金走的交易接口,大商,郑商走行情,所以这个地方后期可能要改
627642 QuoteRequestField* pField = (QuoteRequestField*)m_msgQueue->new_block (sizeof (QuoteRequestField));
628643
629644 pField->TradingDay = GetDate (pForQuoteRsp->TradingDay );
0 commit comments