1- #include " stdafx.h"
1+ #include " stdafx.h"
22#include " MdUserApi.h"
33#include " ../include/QueueEnum.h"
44
@@ -49,24 +49,35 @@ LRESULT CMdUserApi::_OnMsg(WPARAM wParam, LPARAM lParam)
4949
5050 pHeader = (RCV_DATA*)lParam;
5151
52- // 对于处理速度慢的数据类型,最好将 pHeader->m_pData 指向的数据备份, 再作处理
52+ // 对于处理速度慢的数据类型,最好将 pHeader->m_pData 指向的数据备份, 再作处理
5353 switch (wParam)
5454 {
55- case RCV_REPORT: // 股票行情
56- for (i = 0 ; i < pHeader->m_nPacketNum ; i++)
57- {
58- // 数据处理
59- OnRtnDepthMarketData ((RCV_REPORT_STRUCTEx*)&(pHeader->m_pReport [i]), i, pHeader->m_nPacketNum );
60- }
55+ case RCV_REPORT: // 股票行情
56+ // 取第一个和最后一个,如果发现全都是不要的,如三板,直接丢弃
57+ // 这个地方可能有问题,如果元素为0就出事了
58+ {
59+ RCV_REPORT_STRUCTEx* pFirst = &pHeader->m_pReport [0 ];
60+ RCV_REPORT_STRUCTEx* pLast = &pHeader->m_pReport [pHeader->m_nPacketNum - 1 ];
61+
62+ // 前后都不合要求才跳过
63+ if (FilterExchange (pFirst->m_wMarket ) || FilterExchange (pLast->m_wMarket ))
64+ {
65+ for (i = 0 ; i < pHeader->m_nPacketNum ; i++)
66+ {
67+ // 数据处理
68+ OnRtnDepthMarketData (&pHeader->m_pReport [i], i, pHeader->m_nPacketNum );
69+ }
70+ }
71+ }
6172 break ;
6273
63- case RCV_FILEDATA: // 文件
74+ case RCV_FILEDATA: // 文件
6475 switch (pHeader->m_wDataType )
6576 {
66- case FILE_HISTORY_EX: // 补日线数据
77+ case FILE_HISTORY_EX: // 补日线数据
6778 break ;
6879
69- case FILE_MINUTE_EX: // 补分钟线数据
80+ case FILE_MINUTE_EX: // 补分钟线数据
7081 break ;
7182 default :
7283 return 0 ;
@@ -81,7 +92,7 @@ LRESULT CMdUserApi::_OnMsg(WPARAM wParam, LPARAM lParam)
8192
8293void * __stdcall Query (char type, void * pApi1, void * pApi2, double double1, double double2, void * ptr1, int size1, void * ptr2, int size2, void * ptr3, int size3)
8394{
84- // 由内部调用,不用检查是否为空
95+ // 由内部调用,不用检查是否为空
8596 CMdUserApi* pApi = (CMdUserApi*)pApi2;
8697 pApi->QueryInThread (type, pApi1, pApi2, double1, double2, ptr1, size1, ptr2, size2, ptr3, size3);
8798 return nullptr ;
@@ -93,7 +104,7 @@ CMdUserApi::CMdUserApi(void)
93104 m_lRequestID = 0 ;
94105 m_nSleep = 1 ;
95106
96- // 自己维护两个消息队列
107+ // 自己维护两个消息队列
97108 m_msgQueue = new CMsgQueue ();
98109 m_msgQueue_Query = new CMsgQueue ();
99110
@@ -134,13 +145,13 @@ void CMdUserApi::QueryInThread(char type, void* pApi1, void* pApi2, double doubl
134145
135146 if (0 == iRet)
136147 {
137- // 返回成功,填加到已发送池
148+ // 返回成功,填加到已发送池
138149 m_nSleep = 1 ;
139150 }
140151 else
141152 {
142153 m_msgQueue_Query->Input_Copy (type, pApi1, pApi2, double1, double2, ptr1, size1, ptr2, size2, ptr3, size3);
143- // 失败,按4的幂进行延时,但不超过1s
154+ // 失败,按4的幂进行延时,但不超过1s
144155 m_nSleep *= 4 ;
145156 m_nSleep %= 1023 ;
146157 }
@@ -172,28 +183,6 @@ ConfigInfoField* CMdUserApi::Config(ConfigInfoField* pConfigInfo)
172183 return nullptr ;
173184}
174185
175- // bool CMdUserApi::IsErrorRspInfo(CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
176- // {
177- // bool bRet = ((pRspInfo) && (pRspInfo->ErrorID != 0));
178- // if(bRet)
179- // {
180- // ErrorField* pField = (ErrorField*)m_msgQueue->new_block(sizeof(ErrorField));
181- //
182- // pField->ErrorID = pRspInfo->ErrorID;
183- // strcpy(pField->ErrorMsg, pRspInfo->ErrorMsg);
184- //
185- // m_msgQueue->Input_NoCopy(ResponeType::OnRtnError, m_msgQueue, m_pClass, bIsLast, 0, pField, sizeof(ErrorField), nullptr, 0, nullptr, 0);
186- // }
187- // return bRet;
188- // }
189- //
190- // bool CMdUserApi::IsErrorRspInfo(CThostFtdcRspInfoField *pRspInfo)
191- // {
192- // bool bRet = ((pRspInfo) && (pRspInfo->ErrorID != 0));
193- //
194- // return bRet;
195- // }
196-
197186void CMdUserApi::Connect (const string& szPath,
198187 ServerInfoField* pServerInfo,
199188 UserInfoField* pUserInfo,
@@ -218,7 +207,7 @@ void CMdUserApi::Disconnect()
218207{
219208 StopThread ();
220209
221- // 清理查询队列
210+ // 清理查询队列
222211 if (m_msgQueue_Query)
223212 {
224213 m_msgQueue_Query->StopThread ();
@@ -234,18 +223,18 @@ void CMdUserApi::Disconnect()
234223 // m_pApi->Release();
235224 // m_pApi = NULL;
236225
237- // 全清理,只留最后一个
238- // 由于这个dll中设计的线程在连接失败时直接退出,所以这个地方要加一个判断,防出错
226+ // 全清理,只留最后一个
227+ // 由于这个dll中设计的线程在连接失败时直接退出,所以这个地方要加一个判断,防出错
239228 if (m_msgQueue)
240229 {
241230 m_msgQueue->Clear ();
242231 m_msgQueue->Input_NoCopy (ResponeType::OnConnectionStatus, m_msgQueue, m_pClass, ConnectionStatus::Disconnected, 0 , nullptr , 0 , nullptr , 0 , nullptr , 0 );
243- // 主动触发
232+ // 主动触发
244233 m_msgQueue->Process ();
245234 }
246235 // }
247236
248- // 清理响应队列
237+ // 清理响应队列
249238 if (m_msgQueue)
250239 {
251240 m_msgQueue->StopThread ();
@@ -290,17 +279,51 @@ void CMdUserApi::OnRspQryInstrument(DepthMarketDataField* _pField,RCV_REPORT_STR
290279 m_msgQueue->Input_NoCopy (ResponeType::OnRspQryInstrument, m_msgQueue, m_pClass, index >= Count - 1 , 0 , pField, sizeof (InstrumentField), nullptr , 0 , nullptr , 0 );
291280}
292281
293- // 行情回调,得保证此函数尽快返回
282+ bool CMdUserApi::FilterExchange (WORD wMarket)
283+ {
284+ // 只要上海与深圳,不处理三板
285+ return wMarket != SB_MARKET_EX;
286+ }
287+
288+ bool CMdUserApi::FilterInstrument (WORD wMarket, int instrument)
289+ {
290+ // 只处理A股,不处理债券与基金
291+ int prefix1 = instrument / 100000 ;
292+ switch (wMarket)
293+ {
294+ case SH_MARKET_EX:
295+ return (prefix1 == 6 );
296+ case SZ_MARKET_EX:
297+ return (prefix1 == 0 ) || (prefix1 == 3 );
298+ default :
299+ break ;
300+ }
301+ return false ;
302+ }
303+
304+ // 行情回调,得保证此函数尽快返回
294305void CMdUserApi::OnRtnDepthMarketData (RCV_REPORT_STRUCTEx *pDepthMarketData, int index, int Count)
295306{
307+ // 把不想要的过滤了,加快速度
308+ if (
309+ FilterExchange (pDepthMarketData->m_wMarket )
310+ &&FilterInstrument (pDepthMarketData->m_wMarket , atoi (pDepthMarketData->m_szLabel ))
311+ )
312+ {
313+ }
314+ else
315+ {
316+ return ;
317+ }
318+
296319 DepthMarketDataField* pField = (DepthMarketDataField*)m_msgQueue->new_block (sizeof (DepthMarketDataField));
297320
298321 strcpy (pField->InstrumentID , OldSymbol_2_NewSymbol (pDepthMarketData->m_szLabel , pDepthMarketData->m_wMarket ));
299322 strcpy (pField->ExchangeID , Market_2_Exchange (pDepthMarketData->m_wMarket ));
300323
301324 sprintf (pField->Symbol , " %s.%s" , pField->InstrumentID , pField->ExchangeID );
302325
303- // 为合约导入功能所加,做行情处理时还是注释了比较好
326+ // 为合约导入功能所加,如果合约不需要再导入,还是注释了比较好
304327 set<string>::iterator it = m_setInstrumentIDsReceived.find (pField->Symbol );
305328 if (it == m_setInstrumentIDsReceived.end ())
306329 {
@@ -410,14 +433,15 @@ void CMdUserApi::RunInThread()
410433{
411434 m_setInstrumentIDsReceived.clear ();
412435
436+ // 银江要设置成 WS_VISIBLE 不然不调用银江接口
413437 m_hWnd = CreateWindowA (
414438 " static" ,
415- " MsgRecv" ,
416- WS_OVERLAPPEDWINDOW|WS_VISIBLE,
417- CW_USEDEFAULT,
418- CW_USEDEFAULT,
439+ " 请不要关闭我!否则收不到行情" ,
440+ WS_OVERLAPPEDWINDOW | WS_VISIBLE,// | WS_MINIMIZE,
419441 CW_USEDEFAULT,
420442 CW_USEDEFAULT,
443+ 400 ,// CW_USEDEFAULT,
444+ 5 ,// CW_USEDEFAULT,
421445 NULL ,
422446 NULL ,
423447 NULL ,
@@ -463,6 +487,7 @@ void CMdUserApi::RunInThread()
463487 SetWindowLong (m_hWnd, GWL_WNDPROC, (LONG)WndProc);
464488 }
465489 m_pfnStock_Init (m_hWnd, WM_USER_STOCK, RCV_WORK_SENDMSG);
490+ ShowWindow (m_hWnd, SW_HIDE);
466491
467492 MSG msg;
468493 while (m_bRunning)
@@ -487,7 +512,7 @@ void CMdUserApi::RunInThread()
487512 m_hModule = nullptr ;
488513 m_hWnd = nullptr ;
489514
490- // 清理线程
515+ // 清理线程
491516 m_hThread = nullptr ;
492517 m_bRunning = false ;
493518}
0 commit comments