1
- #include " stdafx.h"
1
+ #include " stdafx.h"
2
2
#include " MdUserApi.h"
3
3
#include " ../include/QueueEnum.h"
4
4
5
5
#include " ../include/ApiHeader.h"
6
6
#include " ../include/ApiStruct.h"
7
7
8
8
#include " ../include/toolkit.h"
9
+ #include " ../QuantBox_CTP_Trade/TypeConvert.h"
9
10
10
11
#include " ../QuantBox_Queue/MsgQueue.h"
11
12
#ifdef _REMOTE
@@ -21,7 +22,7 @@ using namespace std;
21
22
22
23
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)
23
24
{
24
- // 由内部调用,不用检查是否为空
25
+ // 由内部调用,不用检查是否为空
25
26
CMdUserApi* pApi = (CMdUserApi*)pApi2;
26
27
pApi->QueryInThread (type, pApi1, pApi2, double1, double2, ptr1, size1, ptr2, size2, ptr3, size3);
27
28
return nullptr ;
@@ -33,7 +34,7 @@ CMdUserApi::CMdUserApi(void)
33
34
m_lRequestID = 0 ;
34
35
m_nSleep = 1 ;
35
36
36
- // 自己维护两个消息队列
37
+ // 自己维护两个消息队列
37
38
m_msgQueue = new CMsgQueue ();
38
39
m_msgQueue_Query = new CMsgQueue ();
39
40
@@ -67,13 +68,13 @@ void CMdUserApi::QueryInThread(char type, void* pApi1, void* pApi2, double doubl
67
68
68
69
if (0 == iRet)
69
70
{
70
- // 返回成功,填加到已发送池
71
+ // 返回成功,填加到已发送池
71
72
m_nSleep = 1 ;
72
73
}
73
74
else
74
75
{
75
76
m_msgQueue_Query->Input_Copy (type, pApi1, pApi2, double1, double2, ptr1, size1, ptr2, size2, ptr3, size3);
76
- // 失败,按4的幂进行延时,但不超过1s
77
+ // 失败,按4的幂进行延时,但不超过1s
77
78
m_nSleep *= 4 ;
78
79
m_nSleep %= 1023 ;
79
80
}
@@ -140,7 +141,7 @@ void CMdUserApi::Connect(const string& szPath,
140
141
nullptr , 0 , nullptr , 0 , nullptr , 0 );
141
142
142
143
#ifdef _REMOTE
143
- // 将收到的行情通过ZeroMQ发送出去
144
+ // 将收到的行情通过ZeroMQ发送出去
144
145
if (strlen (m_ServerInfo.ExtendInformation ) > 0 )
145
146
{
146
147
m_remoteQueue = new CRemoteQueue (m_ServerInfo.ExtendInformation );
@@ -165,7 +166,7 @@ int CMdUserApi::_Init()
165
166
{
166
167
m_pApi->RegisterSpi (this );
167
168
168
- // 添加地址
169
+ // 添加地址
169
170
size_t len = strlen (m_ServerInfo.Address ) + 1 ;
170
171
char * buf = new char [len];
171
172
strncpy (buf, m_ServerInfo.Address , len);
@@ -181,7 +182,7 @@ int CMdUserApi::_Init()
181
182
}
182
183
delete[] buf;
183
184
184
- // 初始化连接
185
+ // 初始化连接
185
186
m_pApi->Init ();
186
187
m_msgQueue->Input_NoCopy (ResponeType::OnConnectionStatus, m_msgQueue, m_pClass, ConnectionStatus::Connecting, 0 , nullptr , 0 , nullptr , 0 , nullptr , 0 );
187
188
}
@@ -209,7 +210,7 @@ int CMdUserApi::_ReqUserLogin(char type, void* pApi1, void* pApi2, double double
209
210
210
211
void CMdUserApi::Disconnect ()
211
212
{
212
- // 清理查询队列
213
+ // 清理查询队列
213
214
if (m_msgQueue_Query)
214
215
{
215
216
m_msgQueue_Query->StopThread ();
@@ -225,14 +226,14 @@ void CMdUserApi::Disconnect()
225
226
m_pApi->Release ();
226
227
m_pApi = NULL ;
227
228
228
- // 全清理,只留最后一个
229
+ // 全清理,只留最后一个
229
230
m_msgQueue->Clear ();
230
231
m_msgQueue->Input_NoCopy (ResponeType::OnConnectionStatus, m_msgQueue, m_pClass, ConnectionStatus::Disconnected, 0 , nullptr , 0 , nullptr , 0 , nullptr , 0 );
231
- // 主动触发
232
+ // 主动触发
232
233
m_msgQueue->Process ();
233
234
}
234
235
235
- // 清理响应队列
236
+ // 清理响应队列
236
237
if (m_msgQueue)
237
238
{
238
239
m_msgQueue->StopThread ();
@@ -242,7 +243,7 @@ void CMdUserApi::Disconnect()
242
243
m_msgQueue = nullptr ;
243
244
}
244
245
245
- // 清理队列
246
+ // 清理队列
246
247
if (m_remoteQueue)
247
248
{
248
249
m_remoteQueue->StopThread ();
@@ -267,14 +268,14 @@ void CMdUserApi::Subscribe(const string& szInstrumentIDs, const string& szExchag
267
268
268
269
if (vct.size ()>0 )
269
270
{
270
- // 转成字符串数组
271
+ // 转成字符串数组
271
272
char ** pArray = new char *[vct.size ()];
272
273
for (size_t j = 0 ; j<vct.size (); ++j)
273
274
{
274
275
pArray[j] = vct[j];
275
276
}
276
277
277
- // 订阅
278
+ // 订阅
278
279
m_pApi->SubscribeMarketData (pArray,(int )vct.size ());
279
280
280
281
delete[] pArray;
@@ -313,14 +314,14 @@ void CMdUserApi::Unsubscribe(const string& szInstrumentIDs, const string& szExch
313
314
314
315
if (vct.size ()>0 )
315
316
{
316
- // 转成字符串数组
317
+ // 转成字符串数组
317
318
char ** pArray = new char *[vct.size ()];
318
319
for (size_t j = 0 ; j<vct.size (); ++j)
319
320
{
320
321
pArray[j] = vct[j];
321
322
}
322
323
323
- // 订阅
324
+ // 订阅
324
325
m_pApi->UnSubscribeMarketData (pArray,(int )vct.size ());
325
326
326
327
delete[] pArray;
@@ -341,14 +342,14 @@ void CMdUserApi::SubscribeQuote(const string& szInstrumentIDs, const string& szE
341
342
342
343
if (vct.size ()>0 )
343
344
{
344
- // 转成字符串数组
345
+ // 转成字符串数组
345
346
char ** pArray = new char *[vct.size ()];
346
347
for (size_t j = 0 ; j<vct.size (); ++j)
347
348
{
348
349
pArray[j] = vct[j];
349
350
}
350
351
351
- // 订阅
352
+ // 订阅
352
353
m_pApi->SubscribeForQuoteRsp (pArray, (int )vct.size ());
353
354
354
355
delete[] pArray;
@@ -387,14 +388,14 @@ void CMdUserApi::UnsubscribeQuote(const string& szInstrumentIDs, const string& s
387
388
388
389
if (vct.size ()>0 )
389
390
{
390
- // 转成字符串数组
391
+ // 转成字符串数组
391
392
char ** pArray = new char *[vct.size ()];
392
393
for (size_t j = 0 ; j<vct.size (); ++j)
393
394
{
394
395
pArray[j] = vct[j];
395
396
}
396
397
397
- // 订阅
398
+ // 订阅
398
399
m_pApi->UnSubscribeForQuoteRsp (pArray, (int )vct.size ());
399
400
400
401
delete[] pArray;
@@ -406,14 +407,14 @@ void CMdUserApi::OnFrontConnected()
406
407
{
407
408
m_msgQueue->Input_NoCopy (ResponeType::OnConnectionStatus, m_msgQueue, m_pClass, ConnectionStatus::Connected, 0 , nullptr , 0 , nullptr , 0 , nullptr , 0 );
408
409
409
- // 连接成功后自动请求登录
410
+ // 连接成功后自动请求登录
410
411
ReqUserLogin ();
411
412
}
412
413
413
414
void CMdUserApi::OnFrontDisconnected (int nReason)
414
415
{
415
416
RspUserLoginField* pField = (RspUserLoginField*)m_msgQueue->new_block (sizeof (RspUserLoginField));
416
- // 连接失败返回的信息是拼接而成,主要是为了统一输出
417
+ // 连接失败返回的信息是拼接而成,主要是为了统一输出
417
418
pField->ErrorID = nReason;
418
419
GetOnFrontDisconnectedMsg (nReason, pField->ErrorMsg );
419
420
@@ -429,20 +430,21 @@ void CMdUserApi::OnRspUserLogin(CThostFtdcRspUserLoginField *pRspUserLogin, CTho
429
430
{
430
431
pField->TradingDay = GetDate (pRspUserLogin->TradingDay );
431
432
pField->LoginTime = GetTime (pRspUserLogin->LoginTime );
433
+ m_TradingDay = pField->TradingDay ;
432
434
433
435
sprintf (pField->SessionID , " %d:%d" , pRspUserLogin->FrontID , pRspUserLogin->SessionID );
434
436
435
437
m_msgQueue->Input_NoCopy (ResponeType::OnConnectionStatus, m_msgQueue, m_pClass, ConnectionStatus::Logined, 0 , pField, sizeof (RspUserLoginField), nullptr , 0 , nullptr , 0 );
436
438
m_msgQueue->Input_NoCopy (ResponeType::OnConnectionStatus, m_msgQueue, m_pClass, ConnectionStatus::Done, 0 , nullptr , 0 , nullptr , 0 , nullptr , 0 );
437
439
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," " );// 订阅
442
444
443
- // 有可能断线了,本处是断线重连后重新订阅
444
- mapOld = m_setQuoteInstrumentIDs;// 记下上次订阅的合约
445
- SubscribeQuote (mapOld, " " );// 订阅
445
+ // 有可能断线了,本处是断线重连后重新订阅
446
+ mapOld = m_setQuoteInstrumentIDs;// 记下上次订阅的合约
447
+ SubscribeQuote (mapOld, " " );// 订阅
446
448
}
447
449
else
448
450
{
@@ -460,7 +462,7 @@ void CMdUserApi::OnRspError(CThostFtdcRspInfoField *pRspInfo, int nRequestID, bo
460
462
461
463
void CMdUserApi::OnRspSubMarketData (CThostFtdcSpecificInstrumentField *pSpecificInstrument, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
462
464
{
463
- // 在模拟平台可能这个函数不会触发,所以要自己维护一张已经订阅的合约列表
465
+ // 在模拟平台可能这个函数不会触发,所以要自己维护一张已经订阅的合约列表
464
466
if (!IsErrorRspInfo (pRspInfo,nRequestID,bIsLast)
465
467
&&pSpecificInstrument)
466
468
{
@@ -472,7 +474,7 @@ void CMdUserApi::OnRspSubMarketData(CThostFtdcSpecificInstrumentField *pSpecific
472
474
473
475
void CMdUserApi::OnRspUnSubMarketData (CThostFtdcSpecificInstrumentField *pSpecificInstrument, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
474
476
{
475
- // 模拟平台可能这个函数不会触发
477
+ // 模拟平台可能这个函数不会触发
476
478
if (!IsErrorRspInfo (pRspInfo,nRequestID,bIsLast)
477
479
&&pSpecificInstrument)
478
480
{
@@ -482,24 +484,37 @@ void CMdUserApi::OnRspUnSubMarketData(CThostFtdcSpecificInstrumentField *pSpecif
482
484
}
483
485
}
484
486
485
- // 行情回调,得保证此函数尽快返回
487
+ // 行情回调,得保证此函数尽快返回
486
488
void CMdUserApi::OnRtnDepthMarketData (CThostFtdcDepthMarketDataField *pDepthMarketData)
487
489
{
488
490
// for (int i = 0; i < 50; ++i)
489
491
// {
490
- // // 测试平台穿越速度,用完后需要注释掉
492
+ // // 测试平台穿越速度,用完后需要注释掉
491
493
// WriteLog("CTP:OnRtnDepthMarketData:%s %f %s.%03d", pDepthMarketData->InstrumentID, pDepthMarketData->LastPrice, pDepthMarketData->UpdateTime, pDepthMarketData->UpdateMillisec);
492
494
493
495
DepthMarketDataField* pField = (DepthMarketDataField*)m_msgQueue->new_block (sizeof (DepthMarketDataField));
494
496
495
497
strcpy (pField->InstrumentID , pDepthMarketData->InstrumentID );
496
- strcpy ( pField->ExchangeID , pDepthMarketData->ExchangeID );
498
+ pField->Exchange = TThostFtdcExchangeIDType_2_ExchangeType ( pDepthMarketData->ExchangeID );
497
499
498
- sprintf (pField->Symbol , " %s.%s" , pField->InstrumentID , pField ->ExchangeID );
500
+ sprintf (pField->Symbol , " %s.%s" , pField->InstrumentID , pDepthMarketData ->ExchangeID );
499
501
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
+ }
503
518
504
519
pField->UpdateMillisec = pDepthMarketData->UpdateMillisec ;
505
520
@@ -585,8 +600,8 @@ void CMdUserApi::OnRtnDepthMarketData(CThostFtdcDepthMarketDataField *pDepthMark
585
600
pField->AskVolume5 = pDepthMarketData->AskVolume5 ;
586
601
} while (false );
587
602
588
- // 这两个队列先头循序不要搞混,有删除功能的语句要放在后面
589
- // 如果放前面,会导致远程收到乱码
603
+ // 这两个队列先头循序不要搞混,有删除功能的语句要放在后面
604
+ // 如果放前面,会导致远程收到乱码
590
605
#ifdef _REMOTE
591
606
if (m_remoteQueue)
592
607
{
@@ -595,7 +610,7 @@ void CMdUserApi::OnRtnDepthMarketData(CThostFtdcDepthMarketDataField *pDepthMark
595
610
#endif
596
611
597
612
m_msgQueue->Input_NoCopy (ResponeType::OnRtnDepthMarketData, m_msgQueue, m_pClass, 0 , 0 , pField, sizeof (DepthMarketDataField), nullptr , 0 , nullptr , 0 );
598
- // 要关注一下其内的
613
+ // 要关注一下其内的
599
614
// }
600
615
}
601
616
@@ -623,7 +638,7 @@ void CMdUserApi::OnRspUnSubForQuoteRsp(CThostFtdcSpecificInstrumentField *pSpeci
623
638
624
639
void CMdUserApi::OnRtnForQuoteRsp (CThostFtdcForQuoteRspField *pForQuoteRsp)
625
640
{
626
- // 上期技术的人说,上海中金走的交易接口,大商,郑商走行情,所以这个地方后期可能要改
641
+ // 上期技术的人说,上海中金走的交易接口,大商,郑商走行情,所以这个地方后期可能要改
627
642
QuoteRequestField* pField = (QuoteRequestField*)m_msgQueue->new_block (sizeof (QuoteRequestField));
628
643
629
644
pField->TradingDay = GetDate (pForQuoteRsp->TradingDay );
0 commit comments