TW.cpp
上传用户:nameszq
上传日期:2014-08-12
资源大小:336k
文件大小:26k
源码类别:

金融证券系统

开发平台:

Visual C++

  1. // TW.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "TW.h"
  5. #include "SPTime.h"
  6. #include "TSCache.h"
  7. #include <math.h>
  8. #ifdef _DEBUG
  9. #define new DEBUG_NEW
  10. #undef THIS_FILE
  11. static char THIS_FILE[] = __FILE__;
  12. #endif
  13. /////////////////////////////////////////////////////////////////////////////
  14. // TW Interface
  15. static BYTE g_serial = 0x00;
  16. static CTWStockArray g_serial_stocks[0x80];
  17. static int g_serial_count[0x80];
  18. BYTE GetNextSerial( TW_STOCK & stock, int count = 0 )
  19. {
  20. g_serial ++;
  21. if( g_serial > 0x7f ) g_serial = 0x01;
  22. if( g_serial >= 1 && g_serial <= 0x7f )
  23. {
  24. g_serial_stocks[g_serial].RemoveAll();
  25. g_serial_stocks[g_serial].Add(stock);
  26. g_serial_count[g_serial] = count;
  27. }
  28. return g_serial;
  29. }
  30. BYTE GetNextSerial( CTWStockArray & stocks, int count = 0 )
  31. {
  32. g_serial ++;
  33. if( g_serial > 0x7f ) g_serial = 0x01;
  34. if( g_serial >= 1 && g_serial <= 0x7f )
  35. {
  36. g_serial_stocks[g_serial].RemoveAll();
  37. g_serial_stocks[g_serial].Copy(stocks);
  38. g_serial_count[g_serial] = count;
  39. }
  40. return g_serial;
  41. }
  42. BOOL GetSerialStock( BYTE serial, TW_STOCK & stock, int * pcount = NULL )
  43. {
  44. if( serial >= 1 && serial <= 0x7f )
  45. {
  46. memset( &stock, 0, sizeof(stock) );
  47. if( g_serial_stocks[serial].GetSize() > 0 )
  48. memcpy( &stock, &(g_serial_stocks[serial].ElementAt(0)), sizeof(stock) );
  49. if( pcount )
  50. *pcount = g_serial_count[serial];
  51. return TRUE;
  52. }
  53. return FALSE;
  54. }
  55. BOOL GetSerialStock( BYTE serial, CTWStockArray & stocks, int * pcount = NULL )
  56. {
  57. if( serial >= 1 && serial <= 0x7f )
  58. {
  59. stocks.RemoveAll();
  60. if( g_serial_stocks[serial].GetSize() > 0 )
  61. stocks.Copy( g_serial_stocks[serial] );
  62. if( pcount )
  63. *pcount = g_serial_count[serial];
  64. return TRUE;
  65. }
  66. return FALSE;
  67. }
  68. int ConstructLength( TW_HEADER & header, int len )
  69. {
  70. CString string = itoa(len,header.m_length,16);
  71. int nZeros = TW_LENGTH_LEN-string.GetLength();
  72. int i;
  73. for( i=0; i<nZeros; i++ )
  74. for( i=0; i<TW_LENGTH_LEN; i++ )
  75. {
  76. if( i< nZeros )
  77. header.m_length[i] = '0';
  78. else
  79. header.m_length[i] = string[i-nZeros];
  80. }
  81. return len;
  82. }
  83. int ConstructLoginBuffer( BYTE * buffer, size_t maxlen, LPCTSTR lpszUser, LPCTSTR lpszPasswd )
  84. {
  85. int nLen = 0;
  86. int nLenUser = strlen(lpszUser);
  87. int nLenPasswd = strlen(lpszPasswd);
  88. TW_LOGIN packet;
  89. memset(&packet,0,sizeof(packet));
  90. packet.m_header.m_magic = TW_MAGIC;
  91. if( maxlen < (int)(5 + sizeof(TW_HEADER) + nLenUser + nLenPasswd) )
  92. {
  93. nLen = 5 + sizeof(TW_HEADER);
  94. return -1;
  95. }
  96. packet.m_name_len = (WORD)nLenUser;
  97. memcpy( packet.m_data, lpszUser, nLenUser );
  98. *(WORD*)(packet.m_data + nLenUser) = (WORD)nLenPasswd;
  99. memcpy( packet.m_data + nLenUser + sizeof(WORD), lpszPasswd, nLenPasswd );
  100. nLen = 5 + sizeof(TW_HEADER) + nLenUser + nLenPasswd;
  101. ConstructLength( packet.m_header, nLen - sizeof(packet.m_header) );
  102. if( buffer )
  103. memcpy( buffer, &packet, nLen );
  104. return nLen;
  105. }
  106. int ConstructAskInitBuffer( TW_ASK & ask )
  107. {
  108. memset( &ask, 0, sizeof(ask) );
  109. ask.m_header.m_magic = TW_MAGIC;
  110. const char * str_tag = "E013.45D013.04D022.03D043.20xcs1.00.is2.00";
  111. ask.m_tag1 = 0x01;
  112. ask.m_tag2 = 0x01;
  113. ask.m_serial = 0x00;
  114. ask.m_size = 0x0007;
  115. CSPTime sptime = CTSCache::GetInstance().GetLocalLatest();
  116. DWORD date = sptime.ToStockTimeDay();
  117. memcpy( &(ask.m_stocks[0].m_type), &date, sizeof(date) );
  118. // ask.m_stocks[0].m_type = 0xdc;
  119. // ask.m_stocks[0].m_code[0] = (char)0xcc;
  120. // ask.m_stocks[0].m_code[1] = 0x31;
  121. // ask.m_stocks[0].m_code[2] = (char)0x01; //0xdc cc 31 01 = 20040924
  122. ask.m_stocks[0].m_code[3] = 0x00;
  123. ask.m_stocks[0].m_code[4] = 0x00;
  124. ask.m_stocks[0].m_code[5] = 0x00;
  125. memcpy( &(ask.m_stocks[1]), str_tag, strlen(str_tag) );
  126. int ret = (6 + sizeof(ask.m_header) + sizeof(TW_STOCK) + strlen(str_tag));
  127. ConstructLength( ask.m_header, ret - sizeof(ask.m_header) );
  128. return ret;
  129. }
  130. int ConstructAskReportBuffer( TW_ASK & ask, TW_STOCK * pStocks, size_t size )
  131. {
  132. memset( &ask, 0, sizeof(ask) );
  133. ask.m_header.m_magic = TW_MAGIC;
  134. SHORT shortSize = (SHORT)size;
  135. if( shortSize > sizeof(ask.m_stocks)/sizeof(TW_STOCK) )
  136. shortSize = sizeof(ask.m_stocks)/sizeof(TW_STOCK);
  137. if( shortSize <= 0 )
  138. return -1;
  139. ask.m_tag1 = 0x00;
  140. ask.m_tag2 = 0x03;
  141. CTWStockArray astocks;
  142. astocks.SetSize( 0, size+1 );
  143. for( size_t i=0; i<size; i++ ) astocks.Add( pStocks[i] );
  144. ask.m_serial = GetNextSerial(astocks);
  145. ask.m_size = shortSize;
  146. if( size > sizeof(ask.m_stocks)/sizeof(TW_STOCK) )
  147. return -1;
  148. if( pStocks && shortSize > 0 )
  149. memcpy( ask.m_stocks, pStocks, shortSize*sizeof(TW_STOCK) );
  150. int ret = (6 + sizeof(ask.m_header) + shortSize * sizeof(TW_STOCK));
  151. ConstructLength( ask.m_header, ret - sizeof(ask.m_header) );
  152. return ret;
  153. }
  154. int ConstructAskMinuteBuffer( TW_ASK & ask, TW_STOCK * pStock )
  155. {
  156. memset( &ask, 0, sizeof(ask) );
  157. ask.m_header.m_magic = TW_MAGIC;
  158. ask.m_tag1 = 0x01;
  159. ask.m_tag2 = 0x04;
  160. ask.m_size = 0x0001;
  161. memcpy( &(ask.m_stocks[0]), pStock, sizeof(TW_STOCK) );
  162. ask.m_serial = GetNextSerial(ask.m_stocks[0]);
  163. int ret = (6 + sizeof(ask.m_header) + sizeof(TW_STOCK));
  164. ConstructLength( ask.m_header, ret - sizeof(ask.m_header) );
  165. return ret;
  166. }
  167. int ConstructAskHistoryBuffer(TW_ASK & ask, TW_STOCK * pStock, int nKType, int nDataCount,
  168.   BOOL bChangeStock, BOOL bFirstRequest )
  169. {
  170. memset( &ask, 0, sizeof(ask) );
  171. ask.m_header.m_magic = TW_MAGIC;
  172. SHORT shortSize = (SHORT)nDataCount;
  173. ask.m_tag1 = 0x00;
  174. ask.m_tag2 = 0x09;
  175. ask.m_size = - shortSize;
  176. memcpy( &(ask.m_stocks[0]), pStock, sizeof(TW_STOCK) );
  177. ask.m_serial = GetNextSerial(ask.m_stocks[0],nDataCount);
  178. if( ktypeMin5 == nKType )
  179. ask.m_tag1 |= 0x30;
  180. else if( ktypeMin15 == nKType )
  181. ask.m_tag1 |= 0x40;
  182. else if( ktypeMin30 == nKType )
  183. ask.m_tag1 |= 0x50;
  184. else if( ktypeMin60 == nKType )
  185. ask.m_tag1 |= 0x60;
  186. else if( ktypeDay == nKType )
  187. ask.m_tag1 |= 0x10;
  188. else if( ktypeWeek == nKType )
  189. ask.m_tag1 |= 0x80;
  190. else if( ktypeMonth == nKType )
  191. ask.m_tag1 |= 0x90;
  192. if( bChangeStock )
  193. ask.m_tag1 |= 0x03;
  194. else if( bFirstRequest )
  195. ask.m_tag1 |= 0x01;
  196. else
  197. ask.m_tag1 |= 0x02;
  198. if( ktypeDay == nKType && bChangeStock )
  199. ask.m_tag1 = 0x20;
  200. int ret = (6 + sizeof(ask.m_header) + sizeof(TW_STOCK));
  201. ConstructLength( ask.m_header, ret - sizeof(ask.m_header) );
  202. return ret;
  203. }
  204. int ConstructAskMultisortBuffer( TW_ASK & ask, TW_STOCK * pStock )
  205. {
  206. memset( &ask, 0, sizeof(ask) );
  207. ask.m_header.m_magic = TW_MAGIC;
  208. BYTE type = typeshA;
  209. if( pStock )
  210. type = pStock->m_type;
  211. TW_STOCK stock;
  212. memset( &stock, 0, sizeof(stock) );
  213. SHORT shortSize = 9;
  214. ask.m_tag1 = 0x0a;
  215. ask.m_tag2 = 0x08;
  216. ask.m_size = - shortSize;
  217. ask.m_stocks[0].m_type = type;
  218. ask.m_stocks[0].m_code[0] = 0x06;
  219. ask.m_stocks[0].m_code[1] = 0x00;
  220. ask.m_stocks[0].m_code[2] = (char)0xff;
  221. ask.m_stocks[0].m_code[3] = 0x01;
  222. ask.m_stocks[0].m_code[4] = 0x00;
  223. ask.m_stocks[0].m_code[5] = 0x00;
  224. ask.m_serial = GetNextSerial(stock);
  225. int ret = (6 + sizeof(ask.m_header) + sizeof(TW_STOCK));
  226. ConstructLength( ask.m_header, ret - sizeof(ask.m_header) );
  227. return ret;
  228. }
  229. int ConstructAskDetailBuffer( TW_ASK & ask, TW_STOCK * pStock )
  230. {
  231. memset( &ask, 0, sizeof(ask) );
  232. ask.m_header.m_magic = TW_MAGIC;
  233. ask.m_tag1 = 0x01;
  234. ask.m_tag2 = 0x02;
  235. ask.m_size = 0x0001;
  236. memcpy( &(ask.m_stocks[0]), pStock, sizeof(TW_STOCK) );
  237. ask.m_serial = GetNextSerial(ask.m_stocks[0]);
  238. int ret = (6 + sizeof(ask.m_header) + sizeof(TW_STOCK));
  239. ConstructLength( ask.m_header, ret - sizeof(ask.m_header) );
  240. return ret;
  241. }
  242. int ConstructAskBaseBuffer( TW_ASK & ask, TW_STOCK * pStock )
  243. {
  244. memset( &ask, 0, sizeof(ask) );
  245. ask.m_header.m_magic = TW_MAGIC;
  246. ask.m_tag1 = 0x05;
  247. ask.m_tag2 = 0x0b;
  248. ask.m_size = 0x0005;
  249. memcpy( &(ask.m_stocks[0]), pStock, sizeof(TW_STOCK) );
  250. ask.m_serial = GetNextSerial(ask.m_stocks[0]);
  251. int ret = (6 + sizeof(ask.m_header) + 5*sizeof(TW_STOCK));
  252. ConstructLength( ask.m_header, ret - sizeof(ask.m_header) );
  253. return ret;
  254. }
  255. size_t TryGetLength( TW_HEADER & header )
  256. {
  257. if( TW_MAGIC != header.m_magic || 0 != header.m_end )
  258. return 0;
  259. int len = (int)strtol(header.m_length,NULL,16);
  260. if( len < 0 )
  261. return 0;
  262. return (size_t)len;
  263. }
  264. size_t TryGetLength( BYTE * buffer, size_t len )
  265. {
  266. if( len < sizeof(TW_HEADER) )
  267. return 0;
  268. TW_HEADER * pheader = (TW_HEADER*)buffer;
  269. return TryGetLength( *pheader );
  270. }
  271. BOOL IsLoginOK( BYTE * buffer, size_t len )
  272. {
  273. if( len < sizeof(TW_ANS) )
  274. return FALSE;
  275. TW_ANS * pans = (TW_ANS *)buffer;
  276. if( TW_MAGIC != pans->m_header.m_magic )
  277. return FALSE;
  278. if( 0x00 != pans->m_tag1 || 0x00 != pans->m_tag2 )
  279. return FALSE;
  280. return TRUE;
  281. }
  282. int TryGetInit( BYTE * buffer, size_t len, PRCV_DATA pRCV_DATA )
  283. {
  284. if( len < sizeof(TW_ANS) )
  285. return 0;
  286. TW_ANS * pans = (TW_ANS*)buffer;
  287. if( TW_MAGIC != pans->m_header.m_magic )
  288. return 0;
  289. if( 0x02 != pans->m_tag1 || 0x01 != pans->m_tag2 )
  290. return 0;
  291. // get it, fill pRCV_DATA
  292. size_t dataoffset = 469;
  293. int datalen = len - dataoffset;
  294. CSPTime tLatest( CSPTime::GetLatestTradeTime(time(NULL)) );
  295. if( len > 128 )
  296. {
  297. DWORD date = (*(DWORD*)(buffer+45));
  298. CSPTime sptime;
  299. if( sptime.FromStockTimeDay( date ) )
  300. tLatest = CSPTime(sptime.GetYear(),sptime.GetMonth(),sptime.GetDay(),9,15,0).GetTime();
  301. }
  302. if( pRCV_DATA && datalen >= (int)sizeof(TW_ANS_INIT) )
  303. {
  304. // 每组28个字节, 共XXXX组,最后以0xfdfdfdfd为结尾
  305. TW_ANS_INIT * pinit = (TW_ANS_INIT*)(buffer+dataoffset);
  306. int packetsize = datalen/(int)sizeof(TW_ANS_INIT);
  307. memset( pRCV_DATA, 0, sizeof(RCV_DATA) );
  308. pRCV_DATA->m_wDataType = RCV_REPORT; // no use
  309. pRCV_DATA->m_nPacketNum = packetsize;
  310. pRCV_DATA->m_bDISK = FALSE;
  311. pRCV_DATA->m_pReport = new RCV_REPORT_STRUCTEx[packetsize];
  312. memset( pRCV_DATA->m_pReport, 0, sizeof(RCV_REPORT_STRUCTEx)*packetsize );
  313. for( int i=0;i <packetsize; i++ )
  314. {
  315. if( pinit[i].m_tag != TW_MAGIC_BYTE )
  316. continue;
  317. pRCV_DATA->m_pReport[i].m_cbSize = sizeof(RCV_REPORT_STRUCTEx);
  318. pRCV_DATA->m_pReport[i].m_time = tLatest.GetTime();
  319. pRCV_DATA->m_pReport[i].m_wMarket = (pinit[i].m_type & 0x20) ? SZ_MARKET_EX : SH_MARKET_EX;
  320. pRCV_DATA->m_pReport[i].m_fLastClose = (float)(pinit[i].m_lastclose * 0.001);
  321. strncpy(pRCV_DATA->m_pReport[i].m_szLabel, pinit[i].m_code,
  322. min(sizeof(pRCV_DATA->m_pReport[i].m_szLabel),sizeof(pinit[i].m_code)));
  323. strncpy(pRCV_DATA->m_pReport[i].m_szName, pinit[i].m_name,
  324. min(sizeof(pRCV_DATA->m_pReport[i].m_szName),sizeof(pinit[i].m_name)));
  325. strncpy(pRCV_DATA->m_pReport[i].m_szName+sizeof(pinit[i].m_name)+2, pinit[i].m_shortname,
  326. min(sizeof(pRCV_DATA->m_pReport[i].m_szName)-sizeof(pinit[i].m_name)-2,sizeof(pinit[i].m_shortname)));
  327. }
  328. return len;
  329. }
  330. return 0;
  331. }
  332. int TryGetReport( BYTE * buffer, size_t len, PRCV_DATA pRCV_DATA )
  333. {
  334. if( len < sizeof(TW_ANS) )
  335. return 0;
  336. TW_ANS * pans = (TW_ANS*)buffer;
  337. if( TW_MAGIC != pans->m_header.m_magic )
  338. return 0;
  339. if( 0x00 != pans->m_tag1 || 0x03 != pans->m_tag2 )
  340. return 0;
  341. CTWStockArray astocks;
  342. BOOL bStockOK = GetSerialStock( pans->m_serial, astocks );
  343. // get it, fill pRCV_DATA
  344. size_t dataoffset = 43;
  345. int datalen = len - dataoffset;
  346. if( pRCV_DATA && bStockOK && astocks.GetSize() > 0 && datalen >= (int)sizeof(TW_ANS_REPORT) )
  347. {
  348. TW_ANS_REPORT * preport = (TW_ANS_REPORT*)(buffer+dataoffset);
  349. memset( pRCV_DATA, 0, sizeof(RCV_DATA) );
  350. pRCV_DATA->m_wDataType = RCV_REPORT; // no use
  351. pRCV_DATA->m_nPacketNum = astocks.GetSize();
  352. pRCV_DATA->m_bDISK = FALSE;
  353. pRCV_DATA->m_pReport = new RCV_REPORT_STRUCTEx[astocks.GetSize()];
  354. memset( pRCV_DATA->m_pReport, 0, sizeof(RCV_REPORT_STRUCTEx)*astocks.GetSize() );
  355. CSPTime tLatest = CTSCache::GetInstance().GetLocalLatest( );
  356. for( int i=0; i<astocks.GetSize() && i<datalen/(int)sizeof(TW_ANS_REPORT); i++ )
  357. {
  358. pRCV_DATA->m_pReport[i].m_cbSize = sizeof(RCV_REPORT_STRUCTEx);
  359. pRCV_DATA->m_pReport[i].m_time = tLatest.GetTime();
  360. pRCV_DATA->m_pReport[i].m_wMarket = (astocks[i].m_type & 0x20) ? SZ_MARKET_EX : SH_MARKET_EX;
  361. strncpy(pRCV_DATA->m_pReport[i].m_szLabel, astocks[i].m_code,
  362. min(sizeof(pRCV_DATA->m_pReport[i].m_szLabel),sizeof(astocks[i].m_code)));
  363. // unknown pRCV_DATA->m_pReport[i].m_fLastClose = (float)(0.001*preport->m_open);
  364. pRCV_DATA->m_pReport[i].m_fOpen = (float)(0.001*preport[i].m_open);
  365. pRCV_DATA->m_pReport[i].m_fHigh = (float)(0.001*preport[i].m_high);
  366. pRCV_DATA->m_pReport[i].m_fLow = (float)(0.001*preport[i].m_low);
  367. pRCV_DATA->m_pReport[i].m_fNewPrice = (float)(0.001*preport[i].m_new);
  368. pRCV_DATA->m_pReport[i].m_fVolume = (float)(0.01*preport[i].m_volume);
  369. pRCV_DATA->m_pReport[i].m_fAmount = (float)(0.01*preport[i].m_amount);
  370. pRCV_DATA->m_pReport[i].m_fBuyPrice[0]= (float)(0.001*preport[i].m_buy1);
  371. pRCV_DATA->m_pReport[i].m_fBuyPrice[1]= (float)(0.001*preport[i].m_buy2);
  372. pRCV_DATA->m_pReport[i].m_fBuyPrice[2]= (float)(0.001*preport[i].m_buy3);
  373. pRCV_DATA->m_pReport[i].m_fBuyVolume[0]= (float)(0.01*preport[i].m_buy1vol);
  374. pRCV_DATA->m_pReport[i].m_fBuyVolume[1]= (float)(0.01*preport[i].m_buy2vol);
  375. pRCV_DATA->m_pReport[i].m_fBuyVolume[2]= (float)(0.01*preport[i].m_buy3vol);
  376. pRCV_DATA->m_pReport[i].m_fSellPrice[0]= (float)(0.001*preport[i].m_sell1);
  377. pRCV_DATA->m_pReport[i].m_fSellPrice[1]= (float)(0.001*preport[i].m_sell2);
  378. pRCV_DATA->m_pReport[i].m_fSellPrice[2]= (float)(0.001*preport[i].m_sell3);
  379. pRCV_DATA->m_pReport[i].m_fSellVolume[0]= (float)(0.01*preport[i].m_sell1vol);
  380. pRCV_DATA->m_pReport[i].m_fSellVolume[1]= (float)(0.01*preport[i].m_sell2vol);
  381. pRCV_DATA->m_pReport[i].m_fSellVolume[2]= (float)(0.01*preport[i].m_sell3vol);
  382. }
  383. return len;
  384. }
  385. return 0;
  386. }
  387. int TryGetMinute( BYTE * buffer, size_t len, PRCV_DATA pRCV_MINUTE, PRCV_DATA pRCV_REPORT )
  388. {
  389. if( len < sizeof(TW_ANS) )
  390. return 0;
  391. TW_ANS * pans = (TW_ANS*)buffer;
  392. if( TW_MAGIC != pans->m_header.m_magic )
  393. return 0;
  394. if( 0x01 != pans->m_tag1 || 0x04 != pans->m_tag2 )
  395. return 0;
  396. TW_STOCK stock;
  397. memset( &stock, 0, sizeof(stock) );
  398. BOOL bStockOK = GetSerialStock( pans->m_serial, stock );
  399. // get it, fill pRCV_DATA
  400. size_t dataoffset = 43;
  401. int datalen = len - dataoffset;
  402. if( pRCV_MINUTE && pRCV_REPORT && bStockOK && datalen >= (int)(sizeof(TW_ANS_MINUTE)-240*sizeof(TW_MINUTE)) )
  403. {
  404. TW_ANS_MINUTE * pminute = (TW_ANS_MINUTE*)(buffer+dataoffset);
  405. CSPTime tLatest = CTSCache::GetInstance().GetLocalLatest( );
  406. int nCount = min(241,pminute->m_offset+1);
  407. int count1 = 0, count2 = 0;
  408. for( int k=0; k<nCount; k++ )
  409. {
  410. if( pminute->m_minutes[k].m_data1 <= pminute->m_high && pminute->m_minutes[k].m_data1 >= pminute->m_low )
  411. count1 ++;
  412. if( pminute->m_minutes[k].m_data2 <= pminute->m_high && pminute->m_minutes[k].m_data2 >= pminute->m_low )
  413. count2 ++;
  414. }
  415. int mode = ( count1 > count2 ? 1 : 2 );
  416. // minute
  417. memset( pRCV_MINUTE, 0, sizeof(RCV_DATA) );
  418. pRCV_MINUTE->m_wDataType = FILE_MINUTE_EX;
  419. pRCV_MINUTE->m_nPacketNum = 1+nCount;
  420. pRCV_MINUTE->m_bDISK = FALSE;
  421. pRCV_MINUTE->m_pMinute = new RCV_MINUTE_STRUCTEx[1+nCount];
  422. memset( pRCV_MINUTE->m_pMinute, 0, sizeof(RCV_MINUTE_STRUCTEx)*(1+nCount) );
  423. pRCV_MINUTE->m_pMinute[0].m_head.m_dwHeadTag = EKE_HEAD_TAG;
  424. pRCV_MINUTE->m_pMinute[0].m_head.m_wMarket = (stock.m_type & 0x20) ? SZ_MARKET_EX : SH_MARKET_EX;
  425. strncpy(pRCV_MINUTE->m_pMinute[0].m_head.m_szLabel, stock.m_code,
  426. min(sizeof(pRCV_MINUTE->m_pMinute[0].m_head.m_szLabel),sizeof(stock.m_code)));
  427. for( int i=0; i<nCount; i++ )
  428. {
  429. pRCV_MINUTE->m_pMinute[i+1].m_time = CSPTime::GetTradeOffsetToTime(i,tLatest.GetTime());
  430. if( 1 == mode )
  431. {
  432. pRCV_MINUTE->m_pMinute[i+1].m_fPrice = (float)(0.001 * pminute->m_minutes[i].m_data1);
  433. pRCV_MINUTE->m_pMinute[i+1].m_fVolume = (float)(0.01 * pminute->m_minutes[i].m_data2);
  434. }
  435. else
  436. {
  437. pRCV_MINUTE->m_pMinute[i+1].m_fPrice = (float)(0.001 * pminute->m_minutes[i].m_data2);
  438. pRCV_MINUTE->m_pMinute[i+1].m_fVolume = (float)(0.01 * pminute->m_minutes[i].m_data1);
  439. }
  440. pRCV_MINUTE->m_pMinute[i+1].m_fAmount = (float)(100. * pRCV_MINUTE->m_pMinute[i+1].m_fVolume * pRCV_MINUTE->m_pMinute[i+1].m_fPrice);
  441. }
  442. // report
  443. memset( pRCV_REPORT, 0, sizeof(RCV_DATA) );
  444. pRCV_REPORT->m_wDataType = RCV_REPORT; // no use
  445. pRCV_REPORT->m_nPacketNum = 11;
  446. pRCV_REPORT->m_bDISK = FALSE;
  447. pRCV_REPORT->m_pReport = new RCV_REPORT_STRUCTEx[11];
  448. memset( pRCV_REPORT->m_pReport, 0, sizeof(RCV_REPORT_STRUCTEx)*11 );
  449. for( i=0;i <11; i++ )
  450. {
  451. pRCV_REPORT->m_pReport[i].m_cbSize = sizeof(RCV_REPORT_STRUCTEx);
  452. pRCV_REPORT->m_pReport[i].m_time = CSPTime::GetTradeOffsetToTime(pminute->m_details[i].m_offset,tLatest.GetTime());
  453. pRCV_REPORT->m_pReport[i].m_wMarket = (stock.m_type & 0x20) ? SZ_MARKET_EX : SH_MARKET_EX;
  454. strncpy(pRCV_REPORT->m_pReport[i].m_szLabel, stock.m_code,
  455. min(sizeof(pRCV_REPORT->m_pReport[i].m_szLabel),sizeof(stock.m_code)));
  456. // unknown pRCV_REPORT->m_pReport[i].m_fLastClose = (float)(0.001*pminute->m_open);
  457. pRCV_REPORT->m_pReport[i].m_fOpen = (float)(0.001*pminute->m_open);
  458. pRCV_REPORT->m_pReport[i].m_fHigh = (float)(0.001*pminute->m_high);
  459. pRCV_REPORT->m_pReport[i].m_fLow = (float)(0.001*pminute->m_low);
  460. pRCV_REPORT->m_pReport[i].m_fNewPrice = (float)(0.001*pminute->m_details[i].m_price);
  461. pRCV_REPORT->m_pReport[i].m_fVolume = (float)(0.01*pminute->m_details[i].m_volume);
  462. pRCV_REPORT->m_pReport[i].m_fAmount = (float)(100.*pRCV_REPORT->m_pReport[i].m_fVolume*pRCV_REPORT->m_pReport[i].m_fNewPrice);
  463. pRCV_REPORT->m_pReport[i].m_fBuyPrice[0]= (float)(0.001*pminute->m_details[i].m_buy);
  464. if(10==i) pRCV_REPORT->m_pReport[i].m_fBuyPrice[1]= (float)(0.001*pminute->m_buy2);
  465. if(10==i) pRCV_REPORT->m_pReport[i].m_fBuyPrice[2]= (float)(0.001*pminute->m_buy3);
  466. if(10==i) pRCV_REPORT->m_pReport[i].m_fBuyVolume[0]= (float)(0.01*pminute->m_buy1vol);
  467. if(10==i) pRCV_REPORT->m_pReport[i].m_fBuyVolume[1]= (float)(0.01*pminute->m_buy2vol);
  468. if(10==i) pRCV_REPORT->m_pReport[i].m_fBuyVolume[2]= (float)(0.01*pminute->m_buy3vol);
  469. pRCV_REPORT->m_pReport[i].m_fSellPrice[0]= (float)(0.001*pminute->m_details[i].m_sell);
  470. if(10==i) pRCV_REPORT->m_pReport[i].m_fSellPrice[1]= (float)(0.001*pminute->m_sell2);
  471. if(10==i) pRCV_REPORT->m_pReport[i].m_fSellPrice[2]= (float)(0.001*pminute->m_sell3);
  472. if(10==i) pRCV_REPORT->m_pReport[i].m_fSellVolume[0]= (float)(0.01*pminute->m_sell1vol);
  473. if(10==i) pRCV_REPORT->m_pReport[i].m_fSellVolume[1]= (float)(0.01*pminute->m_sell2vol);
  474. if(10==i) pRCV_REPORT->m_pReport[i].m_fSellVolume[2]= (float)(0.01*pminute->m_sell3vol);
  475. }
  476. return len;
  477. }
  478. return 0;
  479. }
  480. int TryGetHistory( BYTE * buffer, size_t len, PRCV_DATA pRCV_DATA )
  481. {
  482. if( len < sizeof(TW_ANS) )
  483. return 0;
  484. TW_ANS * pans = (TW_ANS*)buffer;
  485. if( TW_MAGIC != pans->m_header.m_magic )
  486. return 0;
  487. if( 0x09 != pans->m_tag2 )
  488. return 0;
  489. TW_STOCK stock;
  490. memset( &stock, 0, sizeof(stock) );
  491. int nCount = 0;
  492. BOOL bStockOK = GetSerialStock( pans->m_serial, stock, &nCount );
  493. if( 1 == nCount ) nCount = 2;
  494. int ktype = ktypeDay;
  495. if( 0x20 == pans->m_tag1 )
  496. ktype = ktypeDay;
  497. else if( 0x30 == (0xf0 & pans->m_tag1) )
  498. ktype = ktypeMin5;
  499. else if( 0x40 == (0xf0 & pans->m_tag1) )
  500. ktype = ktypeMin15;
  501. else if( 0x50 == (0xf0 & pans->m_tag1) )
  502. ktype = ktypeMin30;
  503. else if( 0x60 == (0xf0 & pans->m_tag1) )
  504. ktype = ktypeMin60;
  505. else if( 0x10 == (0xf0 & pans->m_tag1) )
  506. ktype = ktypeDay;
  507. else if( 0x80 == (0xf0 & pans->m_tag1) )
  508. ktype = ktypeWeek;
  509. else if( 0x90 == (0xf0 & pans->m_tag1) )
  510. ktype = ktypeMonth;
  511. // get it, fill pRCV_DATA
  512. size_t dataoffset = 43;
  513. int datalen = len - dataoffset;
  514. if( pRCV_DATA && bStockOK && nCount > 0 && datalen >= nCount*(int)(sizeof(TW_ANS_HISTORY)+sizeof(DWORD)) )
  515. {
  516. int dataprefix = datalen - nCount*(int)(sizeof(TW_ANS_HISTORY)+sizeof(DWORD));
  517. if( 2 == nCount && datalen >= nCount*(int)(sizeof(TW_ANS_HISTORY)+sizeof(DWORD))+36 )
  518. {
  519. dataprefix = datalen - nCount*(int)(sizeof(TW_ANS_HISTORY)+sizeof(DWORD)) - 36;
  520. }
  521. TW_ANS_HISTORY * phistory = (TW_ANS_HISTORY*)(buffer+dataoffset+dataprefix);
  522. CSPTime tLatest = CTSCache::GetInstance().GetLocalLatest( );
  523. // minute
  524. memset( pRCV_DATA, 0, sizeof(RCV_DATA) );
  525. pRCV_DATA->m_wDataType = FILE_HISTORY_EX;
  526. pRCV_DATA->m_nPacketNum = 1 + nCount;
  527. pRCV_DATA->m_bDISK = FALSE;
  528. pRCV_DATA->m_pDay = new RCV_HISTORY_STRUCTEx[pRCV_DATA->m_nPacketNum+1];
  529. memset( pRCV_DATA->m_pDay, 0, sizeof(RCV_HISTORY_STRUCTEx)*(pRCV_DATA->m_nPacketNum+1) );
  530. pRCV_DATA->m_pDay[0].m_head.m_dwHeadTag = EKE_HEAD_TAG;
  531. pRCV_DATA->m_pDay[0].m_head.m_wMarket = (stock.m_type & 0x20) ? SZ_MARKET_EX : SH_MARKET_EX;
  532. strncpy(pRCV_DATA->m_pDay[0].m_head.m_szLabel, stock.m_code,
  533. min(sizeof(pRCV_DATA->m_pDay[0].m_head.m_szLabel),sizeof(stock.m_code)));
  534. for( int i=0; i<nCount; i++ )
  535. {
  536. CSPTime sptime;
  537. if( sptime.FromStockTime( phistory[i].m_date, ktype, tLatest.GetYear() ) )
  538. pRCV_DATA->m_pDay[i+1].m_time = sptime.GetTime();
  539. else
  540. return 0;
  541. pRCV_DATA->m_pDay[i+1].m_fOpen = (float)(0.001 * phistory[i].m_open);
  542. pRCV_DATA->m_pDay[i+1].m_fHigh = (float)(0.001 * phistory[i].m_high);
  543. pRCV_DATA->m_pDay[i+1].m_fLow = (float)(0.001 * phistory[i].m_low);
  544. pRCV_DATA->m_pDay[i+1].m_fClose = (float)(0.001 * phistory[i].m_close);
  545. pRCV_DATA->m_pDay[i+1].m_fVolume = (float)(phistory[i].m_volume);
  546. pRCV_DATA->m_pDay[i+1].m_fAmount = (float)(1000. * ((DWORD*)&(phistory[nCount]))[i] );
  547. }
  548. return len;
  549. }
  550. return 0;
  551. }
  552. int TryGetMultisort( BYTE * buffer, size_t len, PRCV_DATA pRCV_DATA )
  553. {
  554. if( len < sizeof(TW_ANS) )
  555. return 0;
  556. TW_ANS * pans = (TW_ANS*)buffer;
  557. if( TW_MAGIC != pans->m_header.m_magic )
  558. return 0;
  559. if( 0x0a != pans->m_tag1 || 0x08 != pans->m_tag2 )
  560. return 0;
  561. // get it, fill pRCV_DATA
  562. size_t dataoffset = 41;
  563. int datalen = len - dataoffset;
  564. if( pRCV_DATA && datalen >= (int)sizeof(TW_ANS_MULTISORT) )
  565. {
  566. TW_ANS_MULTISORT * pmultisort = (TW_ANS_MULTISORT*)(buffer+dataoffset);
  567. if( 0x0006 == pmultisort->m_tag1 || datalen == sizeof(TW_ANS_MULTISORT) )
  568. {
  569. memset( pRCV_DATA, 0, sizeof(RCV_DATA) );
  570. pRCV_DATA->m_wDataType = FILE_MULTISORT_EX; // no use
  571. pRCV_DATA->m_nPacketNum = 1;
  572. pRCV_DATA->m_bDISK = FALSE;
  573. pRCV_DATA->m_pMultisort = new RCV_MULTISORT_STRUCTEx[1];
  574. memset( pRCV_DATA->m_pMultisort, 0, sizeof(RCV_MULTISORT_STRUCTEx)*1 );
  575. memcpy( pRCV_DATA->m_pMultisort, pmultisort, sizeof(TW_ANS_MULTISORT) );
  576. return len;
  577. }
  578. }
  579. return 0;
  580. }
  581. int TryGetDetail( BYTE * buffer, size_t len, PRCV_DATA pRCV_DATA )
  582. {
  583. if( len < sizeof(TW_ANS) )
  584. return 0;
  585. TW_ANS * pans = (TW_ANS*)buffer;
  586. if( TW_MAGIC != pans->m_header.m_magic )
  587. return 0;
  588. if( 0x01 != pans->m_tag1 || 0x02 != pans->m_tag2 )
  589. return 0;
  590. TW_STOCK stock;
  591. memset( &stock, 0, sizeof(stock) );
  592. BOOL bStockOK = GetSerialStock( pans->m_serial, stock );
  593. // get it, fill pRCV_DATA
  594. size_t dataoffset = 43;
  595. int datalen = len - dataoffset;
  596. if( pRCV_DATA && bStockOK && datalen >= (int)sizeof(TW_ANS_DETAIL) )
  597. {
  598. TW_ANS_DETAIL * pdetail = (TW_ANS_DETAIL*)(buffer+dataoffset);
  599. int packetsize = datalen/(int)sizeof(TW_ANS_DETAIL);
  600. memset( pRCV_DATA, 0, sizeof(RCV_DATA) );
  601. pRCV_DATA->m_wDataType = RCV_REPORT; // no use
  602. pRCV_DATA->m_nPacketNum = packetsize;
  603. pRCV_DATA->m_bDISK = FALSE;
  604. pRCV_DATA->m_pReport = new RCV_REPORT_STRUCTEx[packetsize];
  605. memset( pRCV_DATA->m_pReport, 0, sizeof(RCV_REPORT_STRUCTEx)*packetsize );
  606. CSPTime tLatest = CTSCache::GetInstance().GetLocalLatest( );
  607. for( int i=0;i <packetsize; i++ )
  608. {
  609. pRCV_DATA->m_pReport[i].m_cbSize = sizeof(RCV_REPORT_STRUCTEx);
  610. pRCV_DATA->m_pReport[i].m_time = CSPTime::GetTradeOffsetToTime( pdetail[i].m_offset, tLatest.GetTime() );
  611. pRCV_DATA->m_pReport[i].m_wMarket = (stock.m_type & 0x20) ? SZ_MARKET_EX : SH_MARKET_EX;
  612. strncpy(pRCV_DATA->m_pReport[i].m_szLabel, stock.m_code,
  613. min(sizeof(pRCV_DATA->m_pReport[i].m_szLabel),sizeof(stock.m_code)));
  614. pRCV_DATA->m_pReport[i].m_fNewPrice = (float)(0.001*pdetail[i].m_price);
  615. pRCV_DATA->m_pReport[i].m_fVolume = (float)(0.01*pdetail[i].m_volume);
  616. pRCV_DATA->m_pReport[i].m_fAmount = (float)(100.*pRCV_DATA->m_pReport[i].m_fVolume*pRCV_DATA->m_pReport[i].m_fNewPrice);
  617. pRCV_DATA->m_pReport[i].m_fBuyPrice[0]= (float)(0.001*pdetail[i].m_buy1);
  618. pRCV_DATA->m_pReport[i].m_fSellPrice[0]= (float)(0.001*pdetail[i].m_sell1);
  619. }
  620. return len;
  621. }
  622. return 0;
  623. }
  624. int TryGetBase( BYTE * buffer, size_t len, PRCV_DATA pRCV_DATA )
  625. {
  626. if( len < sizeof(TW_ANS) )
  627. return 0;
  628. TW_ANS * pans = (TW_ANS*)buffer;
  629. if( TW_MAGIC != pans->m_header.m_magic )
  630. return 0;
  631. if( 0x05 != pans->m_tag1 || 0x0b != pans->m_tag2 )
  632. return 0;
  633. TW_STOCK stock;
  634. memset( &stock, 0, sizeof(stock) );
  635. BOOL bStockOK = GetSerialStock( pans->m_serial, stock );
  636. // get it, fill pRCV_DATA
  637. size_t dataoffset = 45;
  638. int datalen = len - dataoffset;
  639. if( pRCV_DATA && bStockOK && datalen > 0 )
  640. {
  641. memset( pRCV_DATA, 0, sizeof(RCV_DATA) );
  642. pRCV_DATA->m_wDataType = FILE_BASE_EX;
  643. pRCV_DATA->m_nPacketNum = 1;
  644. pRCV_DATA->m_bDISK = FALSE;
  645. pRCV_DATA->m_File.m_dwLen = datalen;
  646. strncpy( pRCV_DATA->m_File.m_szFileName, stock.m_code, min(sizeof(stock.m_code),sizeof(pRCV_DATA->m_File.m_szFileName)-1) );
  647. if( strlen(pRCV_DATA->m_File.m_szFileName)+5 < sizeof(pRCV_DATA->m_File.m_szFileName) )
  648. strcat(pRCV_DATA->m_File.m_szFileName, ".txt");
  649. pRCV_DATA->m_pData = new BYTE[datalen+1];
  650. memcpy( pRCV_DATA->m_pData, buffer + dataoffset, datalen );
  651. ((char*)pRCV_DATA->m_pData)[datalen] = 0;
  652. return len;
  653. }
  654. return 0;
  655. }