QianLong.cpp
上传用户:zhanglf88
上传日期:2013-11-19
资源大小:6036k
文件大小:32k
源码类别:

金融证券系统

开发平台:

Visual C++

  1. /*
  2. Cross Platform Core Code.
  3. Copyright(R) 2001-2002 Balang Software.
  4. All rights reserved.
  5. Using:
  6. class CQianLong;
  7. */
  8. #include "StdAfx.h"
  9. #include "../Include/Database.h"
  10. #include "../Include/SpString.h"
  11. #include "QianLong.h"
  12. #include <math.h>
  13. #ifdef _DEBUG
  14. #define new DEBUG_NEW
  15. #undef THIS_FILE
  16. static char THIS_FILE[] = __FILE__;
  17. #endif
  18. BOOL convert_QL_Data_5min_to_KDATA( DWORD dwMarket, const char *szCode, struct QL_Data_5min * pqlkd, KDATA *pkd )
  19. {
  20. SP_ASSERT( pqlkd && pkd );
  21. if( NULL == pqlkd || NULL == pkd )
  22. return FALSE;
  23. memset( pkd, 0, sizeof(KDATA) );
  24. pkd->m_dwMarket = dwMarket;
  25. if( szCode )
  26. strncpy( pkd->m_szCode, szCode, min(sizeof(pkd->m_szCode)-1,strlen(szCode)) );
  27. pkd->m_date = pqlkd->min_off;
  28. CSPTime sptime;
  29. if( sptime.FromStockTimeMin( pkd->m_date) )
  30. pkd->m_time = sptime.GetTime();
  31. pkd->m_fOpen = (float)fabs( pqlkd->open_price * 0.001 );
  32. pkd->m_fHigh = (float)fabs( pqlkd->high_price * 0.001 );
  33. pkd->m_fLow = (float)fabs( pqlkd->low_price * 0.001 );
  34. pkd->m_fClose = (float)fabs( pqlkd->close_price * 0.001 );
  35. pkd->m_fVolume = (float)fabs( pqlkd->min_volume * 100. );
  36. pkd->m_fAmount = (float)fabs( pqlkd->min_amount * 100. );
  37. return TRUE;
  38. }
  39. BOOL convert_QL_Data_day_to_KDATA( DWORD dwMarket, const char *szCode, struct QL_Data_day * pqlkd, KDATA *pkd )
  40. {
  41. SP_ASSERT( pqlkd && pkd );
  42. if( NULL == pqlkd || NULL == pkd )
  43. return FALSE;
  44. memset( pkd, 0, sizeof(KDATA) );
  45. pkd->m_dwMarket = dwMarket;
  46. if( szCode )
  47. strncpy( pkd->m_szCode, szCode, min(sizeof(pkd->m_szCode)-1,strlen(szCode)) );
  48. pkd->m_date = pqlkd->day_date;
  49. CSPTime sptime;
  50. if( sptime.FromStockTimeDay(pkd->m_date) )
  51. pkd->m_time = sptime.GetTime();
  52. pkd->m_fOpen = (float)fabs( pqlkd->open_price * 0.001 );
  53. pkd->m_fHigh = (float)fabs( pqlkd->high_price * 0.001 );
  54. pkd->m_fLow = (float)fabs( pqlkd->low_price * 0.001 );
  55. pkd->m_fClose = (float)fabs( pqlkd->close_price * 0.001 );
  56. pkd->m_fVolume = (float)fabs( pqlkd->day_volume * 100. );
  57. pkd->m_fAmount = (float)fabs( pqlkd->day_amount * 1000. );
  58. return TRUE;
  59. }
  60. BOOL convert_KDATA_to_QL_Data_day( KDATA * pkd, struct QL_Data_day * pqlkd )
  61. {
  62. SP_ASSERT( pqlkd && pkd );
  63. if( NULL == pqlkd || NULL == pkd )
  64. return FALSE;
  65. memset( pqlkd, 0, sizeof(struct QL_Data_day) );
  66. pqlkd->day_date = (DWORD)( pkd->m_date );
  67. pqlkd->open_price = (DWORD)( pkd->m_fOpen * 1000 );
  68. pqlkd->high_price = (DWORD)( pkd->m_fHigh * 1000 );
  69. pqlkd->low_price = (DWORD)( pkd->m_fLow * 1000 );
  70. pqlkd->close_price = (DWORD)( pkd->m_fClose * 1000 );
  71. pqlkd->day_volume = (DWORD)( pkd->m_fVolume * 0.01 );
  72. pqlkd->day_amount = (DWORD)( pkd->m_fAmount * 0.001 );
  73. return TRUE;
  74. }
  75. BOOL convert_KDATA_to_QL_Data_5min( KDATA * pkd, struct QL_Data_5min * pqlkd )
  76. {
  77. SP_ASSERT( pqlkd && pkd );
  78. if( NULL == pqlkd || NULL == pkd )
  79. return FALSE;
  80. memset( pqlkd, 0, sizeof(struct QL_Data_day) );
  81. pqlkd->min_off = (DWORD)( pkd->m_date );
  82. pqlkd->open_price = (DWORD)( pkd->m_fOpen * 1000 );
  83. pqlkd->high_price = (DWORD)( pkd->m_fHigh * 1000 );
  84. pqlkd->low_price = (DWORD)( pkd->m_fLow * 1000 );
  85. pqlkd->close_price = (DWORD)( pkd->m_fClose * 1000 );
  86. pqlkd->min_volume = (DWORD)( pkd->m_fVolume * 0.01 );
  87. pqlkd->min_amount = (DWORD)( pkd->m_fAmount * 0.01 );
  88. return TRUE;
  89. }
  90. void ConvertQLStockInfo( DWORD dwMarket, QL_Stock_info_V302 & block, CStockInfo *pInfo )
  91. {
  92. pInfo->Clear();
  93. char code[sizeof(block.stock_code)+2];
  94. memset(code,0,sizeof(code));
  95. strncpy(code,(const char *)block.stock_code,sizeof(block.stock_code));
  96. char name[sizeof(block.stock_name)+2];
  97. memset(name,0,sizeof(name));
  98. strncpy(name,(const char *)block.stock_name,sizeof(block.stock_name));
  99. pInfo->SetStockCode( dwMarket, code );
  100. pInfo->SetStockName( name );
  101. pInfo->SetType( block.stock_type );
  102. /*
  103. pInfo->m_fLast = (float)fabs( block.last_close_price * 0.001 );
  104. pInfo->m_fOpen = (float)fabs( block.open_price * 0.001 );
  105. pInfo->m_fHigh = (float)fabs( block.high_price * 0.001 );
  106. pInfo->m_fLow = (float)fabs( block.low_price * 0.001 );
  107. pInfo->m_fClose = (float)fabs( block.close_price * 0.001 );
  108. pInfo->m_fVolume = (float)fabs( block.total_volume * 100. );
  109. pInfo->m_fAmount = (float)fabs( block.total_value * 1000. );
  110. pInfo->m_fBuyPrice[0] = (float)fabs( block.buy_1_price * 0.001 );
  111. pInfo->m_fBuyVolume[0] = (float)fabs( block.buy_1_volume * 100. );
  112. pInfo->m_fBuyPrice[1] = (float)fabs( block.buy_2_price * 0.001 );
  113. pInfo->m_fBuyVolume[1] = (float)fabs( block.buy_2_volume * 100. );
  114. pInfo->m_fBuyPrice[2] = (float)fabs( block.buy_3_price * 0.001 );
  115. pInfo->m_fBuyVolume[2] = (float)fabs( block.buy_3_volume * 100. );
  116. pInfo->m_fSellPrice[0] = (float)fabs( block.sell_1_price * 0.001 );
  117. pInfo->m_fSellVolume[0] = (float)fabs( block.sell_1_volume * 100. );
  118. pInfo->m_fSellPrice[1] = (float)fabs( block.sell_2_price * 0.001 );
  119. pInfo->m_fSellVolume[1] = (float)fabs( block.sell_2_volume * 100. );
  120. pInfo->m_fSellPrice[2] = (float)fabs( block.sell_3_price * 0.001 );
  121. pInfo->m_fSellVolume[2] = (float)fabs( block.sell_3_volume * 100. );
  122. */
  123. }
  124. void ConvertQLStockInfo( DWORD dwMarket, QL_Stock_info2_V304 & block, CStockInfo *pInfo )
  125. {
  126. pInfo->Clear();
  127. char code[sizeof(block.stock_code)+2];
  128. memset(code,0,sizeof(code));
  129. strncpy(code,(const char *)block.stock_code,sizeof(block.stock_code));
  130. char name[sizeof(block.stock_name)+2];
  131. memset(name,0,sizeof(name));
  132. strncpy(name,(const char *)block.stock_name,sizeof(block.stock_name));
  133. pInfo->SetStockCode( dwMarket, code );
  134. pInfo->SetStockName( name );
  135. pInfo->SetType( block.stock_type );
  136. /*
  137. pInfo->m_fLast = (float)fabs( block.last_close_price * 0.001 );
  138. pInfo->m_fOpen = (float)fabs( block.open_price * 0.001 );
  139. pInfo->m_fHigh = (float)fabs( block.high_price * 0.001 );
  140. pInfo->m_fLow = (float)fabs( block.low_price * 0.001 );
  141. pInfo->m_fClose = (float)fabs( block.close_price * 0.001 );
  142. pInfo->m_fVolume = (float)fabs( block.total_volume * 100. );
  143. pInfo->m_fAmount = (float)fabs( block.total_value * 1000. );
  144. pInfo->m_fBuyPrice[0] = (float)fabs( block.buy_1_price * 0.001 );
  145. pInfo->m_fBuyVolume[0] = (float)fabs( block.buy_1_volume * 100. );
  146. pInfo->m_fBuyPrice[1] = (float)fabs( block.buy_2_price * 0.001 );
  147. pInfo->m_fBuyVolume[1] = (float)fabs( block.buy_2_volume * 100. );
  148. pInfo->m_fBuyPrice[2] = (float)fabs( block.buy_3_price * 0.001 );
  149. pInfo->m_fBuyVolume[2] = (float)fabs( block.buy_3_volume * 100. );
  150. pInfo->m_fSellPrice[0] = (float)fabs( block.sell_1_price * 0.001 );
  151. pInfo->m_fSellVolume[0] = (float)fabs( block.sell_1_volume * 100. );
  152. pInfo->m_fSellPrice[1] = (float)fabs( block.sell_2_price * 0.001 );
  153. pInfo->m_fSellVolume[1] = (float)fabs( block.sell_2_volume * 100. );
  154. pInfo->m_fSellPrice[2] = (float)fabs( block.sell_3_price * 0.001 );
  155. pInfo->m_fSellVolume[2] = (float)fabs( block.sell_3_volume * 100. );
  156. */
  157. }
  158. /////////////////////////////////////////////////////////////////////////////////////
  159. // class CQianlong
  160. /*
  161. struct QL_Info_data datainfo_sha[TYPE_NUM];
  162. struct QL_Info_data datainfo_szn[TYPE_NUM];
  163. unsigned char exepath[80];
  164. unsigned char appdexe[88];
  165. unsigned char ml_sys[80];
  166. unsigned char ml_dat[80];
  167. unsigned char ml_sh_day[80];
  168. unsigned char ml_sz_day[80];
  169. unsigned char ml_sh_min[80];
  170. unsigned char ml_sz_min[80];
  171. unsigned char ml_sh_wek[80];
  172. unsigned char ml_sz_wek[80];
  173. unsigned char ml_sh_mnt[80];
  174. unsigned char ml_sz_mnt[80];
  175. unsigned char sl_sys[80];
  176. unsigned char sl_dat[80];
  177. unsigned char sl_sh_day[80];
  178. unsigned char sl_sz_day[80];
  179. unsigned char sl_sh_min[80];
  180. unsigned char sl_sz_min[80];
  181. unsigned char sl_sh_wek[80];
  182. unsigned char sl_sz_wek[80];
  183. unsigned char sl_sh_mnt[80];
  184. unsigned char sl_sz_mnt[80];
  185. unsigned char hx_sys[80];
  186. unsigned char hx_dat[80];
  187. unsigned char hx_sh_day[80];
  188. unsigned char hx_sz_day[80];
  189. unsigned char hx_sh_min[80];
  190. unsigned char hx_sz_min[80];
  191. unsigned char hx_sh_wek[80];
  192. unsigned char hx_sz_wek[80];
  193. unsigned char hx_sh_mnt[80];
  194. unsigned char hx_sz_mnt[80];
  195. unsigned char dealpath[80];
  196. unsigned char dealdat[80];
  197. unsigned char tmpdir[80];
  198. unsigned char sysdir[80];
  199. unsigned char infdir[80];
  200. unsigned char datdir[80];
  201. unsigned char basdir[80];
  202. unsigned char flag_mlv304;
  203. unsigned long nowdate;
  204. unsigned char datestr[10];
  205. unsigned char flag_dynamic;
  206. unsigned char ml30_flag;
  207. unsigned char slon_flag;
  208. unsigned char hxtw_flag;
  209. */
  210. char ml_dat[] = "dat\";
  211. char ml_sh_info[] = "dat\shinfo.dat";
  212. char ml_sz_info[] = "dat\szinfo.dat";
  213. char ml_sh_now[] = "dat\shnow.dat";
  214. char ml_sz_now[] = "dat\sznow.dat";
  215. char ml_sh_pyjc[] = "dat\shpyjc.dat";
  216. char ml_sz_pyjc[] = "dat\szpyjc.dat";
  217. char ml_sh_trace[] = "dat\shtrace.dat";
  218. char ml_sz_trace[] = "dat\sztrace.dat";
  219. char ml_sh_minute[] = "dat\shminute.dat";
  220. char ml_sz_minute[] = "dat\szminute.dat";
  221. char ml_data[] = "data\";
  222. char ml_sh[] = "data\shase\";
  223. char ml_sz[] = "data\sznse\";
  224. char ml_base[] = "base\";
  225. char ml_month[] = "month\";
  226. char ml_week[] = "week\";
  227. char ml_day[] = "day\";
  228. char ml_min5[] = "min\";
  229. char ml_sh_base[] = "data\shase\base\";
  230. char ml_sz_base[] = "data\sznse\base\";
  231. char ml_sh_month[] = "data\shase\month\";
  232. char ml_sz_month[] = "data\sznse\month\";
  233. char ml_sh_week[] = "data\shase\week\";
  234. char ml_sz_week[] = "data\sznse\week\";
  235. char ml_sh_day[] = "data\shase\day\";
  236. char ml_sz_day[] = "data\sznse\day\";
  237. char ml_sh_min[] = "data\shase\min\";
  238. char ml_sz_min[] = "data\sznse\min\";
  239. char ml_ext_base[] = ".txt";
  240. char ml_ext_month[] = ".mnt";
  241. char ml_ext_week[] = ".wek";
  242. char ml_ext_day[] = ".day";
  243. char ml_ext_min5[] = ".nmn";
  244. CQianlong::CQianlong( const char * rootpath, BOOL bOK )
  245. {
  246. m_bIsOK = FALSE;
  247. memset( m_szRootPath, 0, sizeof(m_szRootPath) );
  248. if( !bOK )
  249. {
  250. if( GetAccurateRoot( rootpath, m_szRootPath, sizeof(m_szRootPath)-1 ) )
  251. m_bIsOK = TRUE;
  252. else
  253. m_bIsOK = FALSE;
  254. }
  255. else
  256. {
  257. strncpy( m_szRootPath, rootpath, sizeof(m_szRootPath)-1 );
  258. m_bIsOK = TRUE;
  259. }
  260. m_nVersion = versionUnknown;
  261. if( bOK )
  262. m_nVersion = DetectVersion( GetRootPath() );
  263. }
  264. CQianlong::~CQianlong( )
  265. {
  266. }
  267. int CQianlong::GetMaxStockNumber( )
  268. {
  269. SP_ASSERT( m_bIsOK );
  270. if( ! m_bIsOK ) return 0;
  271. // load shinfo.dat szinfo.dat
  272. int blocksize = sizeof(struct QL_Stock_info_V302);
  273. if( version304 == m_nVersion )
  274. blocksize = sizeof(struct QL_Stock_info2_V304);
  275. DWORD dwCount = 0;
  276. CSPString sFileName = GetRootPath();
  277. sFileName += ml_sh_now;
  278. CSPFile file;
  279. if( file.Open( sFileName, CSPFile::modeRead | CSPFile::shareDenyNone ) )
  280. {
  281. DWORD dwFileLen = file.GetLength();
  282. dwCount += dwFileLen / blocksize;
  283. file.Close();
  284. }
  285. sFileName = GetRootPath();
  286. sFileName += ml_sz_now;
  287. if( file.Open( sFileName, CSPFile::modeRead | CSPFile::shareDenyNone ) )
  288. {
  289. DWORD dwFileLen = file.GetLength();
  290. dwCount += dwFileLen / blocksize;
  291. file.Close();
  292. }
  293. return dwCount;
  294. }
  295. int CQianlong::LoadCodetable( CStockContainer & container )
  296. {
  297. SP_ASSERT( m_bIsOK );
  298. if( !m_bIsOK ) return 0;
  299. int maxsize = GetMaxStockNumber();
  300. container.SetSize( maxsize );
  301. CStockInfo * pdata = container.GetData();
  302. char szShortName[QL_SHORTNAME_LEN+1];
  303. memset( szShortName, 0, sizeof(szShortName) );
  304. int  nCount = 0;
  305. CSPString sFileName = GetRootPath();
  306. sFileName += ml_sh_now;
  307. CSPFile file;
  308. if( file.Open( sFileName, CSPFile::modeRead | CSPFile::shareDenyNone ) )
  309. {
  310. // pin yin file
  311. CSPString sFileNamePyjc = GetRootPath();
  312. sFileNamePyjc += ml_sh_pyjc;
  313. CSPFile filePyjc;
  314. filePyjc.Open( sFileNamePyjc, CSPFile::modeRead | CSPFile::shareDenyNone );
  315. if( version302 == m_nVersion )
  316. {
  317. struct QL_Stock_info_V302 block;
  318. while( nCount < maxsize 
  319. && sizeof(block) == file.Read( &block, sizeof(block) ) )
  320. {
  321. pdata[nCount].Clear();
  322. ConvertQLStockInfo( CStock::marketSHSE, block, &(pdata[nCount]) );
  323. // read shortname
  324. if( CSPFile::hFileNull != filePyjc.m_hFile && QL_SHORTNAME_LEN == filePyjc.Read( szShortName, QL_SHORTNAME_LEN ) )
  325. pdata[nCount].SetStockShortName( szShortName );
  326. nCount ++;
  327. }
  328. }
  329. else if( version304 == m_nVersion )
  330. {
  331. struct QL_Stock_info2_V304 block;
  332. while( nCount < maxsize 
  333. && sizeof(block) == file.Read( &block, sizeof(block) ) )
  334. {
  335. pdata[nCount].Clear();
  336. ConvertQLStockInfo( CStock::marketSHSE, block, &(pdata[nCount]) );
  337. // read shortname
  338. if( CSPFile::hFileNull != filePyjc.m_hFile && QL_SHORTNAME_LEN == filePyjc.Read( szShortName, QL_SHORTNAME_LEN ) )
  339. pdata[nCount].SetStockShortName( szShortName );
  340. nCount ++;
  341. }
  342. }
  343. if( CSPFile::hFileNull != filePyjc.m_hFile )
  344. filePyjc.Close();
  345. file.Close();
  346. }
  347. sFileName = GetRootPath();
  348. sFileName += ml_sz_now;
  349. if( file.Open( sFileName, CSPFile::modeRead | CSPFile::shareDenyNone ) )
  350. {
  351. // pin yin file
  352. CSPString sFileNamePyjc = GetRootPath();
  353. sFileNamePyjc += ml_sz_pyjc;
  354. CSPFile filePyjc;
  355. filePyjc.Open( sFileNamePyjc, CSPFile::modeRead | CSPFile::shareDenyNone );
  356. if( version302 == m_nVersion )
  357. {
  358. struct QL_Stock_info_V302 block;
  359. while( nCount < maxsize 
  360. && sizeof(block) == file.Read( &block, sizeof(block) ) )
  361. {
  362. pdata[nCount].Clear();
  363. ConvertQLStockInfo( CStock::marketSZSE, block, &(pdata[nCount]) );
  364. // read shortname
  365. if( CSPFile::hFileNull != filePyjc.m_hFile && QL_SHORTNAME_LEN == filePyjc.Read( szShortName, QL_SHORTNAME_LEN ) )
  366. pdata[nCount].SetStockShortName( szShortName );
  367. nCount ++;
  368. }
  369. }
  370. else if( version304 == m_nVersion )
  371. {
  372. struct QL_Stock_info2_V304 block;
  373. while( nCount < maxsize 
  374. && sizeof(block) == file.Read( &block, sizeof(block) ) )
  375. {
  376. pdata[nCount].Clear();
  377. ConvertQLStockInfo( CStock::marketSZSE, block, &(pdata[nCount]) );
  378. // read shortname
  379. if( CSPFile::hFileNull != filePyjc.m_hFile && QL_SHORTNAME_LEN == filePyjc.Read( szShortName, QL_SHORTNAME_LEN ) )
  380. pdata[nCount].SetStockShortName( szShortName );
  381. nCount ++;
  382. }
  383. }
  384. file.Close();
  385. }
  386. container.SetSize( nCount );
  387. return nCount;
  388. }
  389. int CQianlong::StoreCodetable( CStockContainer & container )
  390. {
  391. SP_ASSERT( FALSE );
  392. return 0;
  393. }
  394. int CQianlong::LoadKDataCache( CStockContainer & container, PROGRESS_CALLBACK fnCallback, void *cookie, int nProgStart, int nProgEnd )
  395. {
  396. SP_ASSERT( m_bIsOK );
  397. if( !m_bIsOK ) return 0;
  398. UINT nCacheDays = AfxGetProfile().GetCacheDays();
  399. // 读取行情缓存
  400. SP_ASSERT( nProgStart <= nProgEnd );
  401. int nCount = container.GetSize();
  402. int nCacheCount = 0;
  403. int nProgressSegment = nCount / 25;
  404. double dProgressRatio = ( 0 == nCount ? 1 : (nProgEnd-nProgStart)/nCount );
  405. for( int i=0; i<nCount; i++ )
  406. {
  407. container.Lock();
  408. CStockInfo & info = container.ElementAt(i);
  409. DWORD dwMarket = info.GetMarket();
  410. CSPString sCode = info.GetStockCode();
  411. // Get Data From Day K Line
  412. CSPString sFileName;
  413. GetFileName( sFileName, CStock::dataK, &info, CKData::ktypeDay );
  414. CSPFile file;
  415. if( file.Open( sFileName, CSPFile::modeRead | CSPFile::shareDenyNone ) )
  416. {
  417. DWORD dwFileLen = file.GetLength();
  418. struct QL_Data_day qlkd;
  419. info.m_kdata.SetSize( 0, nCacheDays+3 );
  420. if( dwFileLen > sizeof(qlkd)*(nCacheDays+1) )
  421. file.Seek( dwFileLen-sizeof(qlkd)*(nCacheDays+1), CSPFile::begin );
  422. while( sizeof(qlkd) == file.Read( &qlkd, sizeof(qlkd) ) )
  423. {
  424. KDATA kd;
  425. convert_QL_Data_day_to_KDATA( dwMarket, sCode, &qlkd, &kd );
  426. info.m_kdata.Add( kd );
  427. }
  428. file.Close();
  429. nCacheCount ++;
  430. if( fnCallback && !(nCacheCount % nProgressSegment) )
  431. fnCallback( PROG_PROGRESS, (int)(nProgStart+nCacheCount*dProgressRatio), NULL, cookie );
  432. }
  433. container.UnLock();
  434. }
  435. return nCount;
  436. }
  437. int CQianlong::LoadBasetable( CStockContainer & container )
  438. {
  439. SP_ASSERT( FALSE );
  440. return 0;
  441. }
  442. int CQianlong::StoreBasetable( CStockContainer & container )
  443. {
  444. SP_ASSERT( FALSE );
  445. return 0;
  446. }
  447. int CQianlong::LoadBaseText( CStock *pstock )
  448. {
  449. SP_ASSERT( m_bIsOK && pstock && pstock->GetStockInfo().IsValidStock() );
  450. if( ! m_bIsOK || ! pstock || !pstock->GetStockInfo().IsValidStock() ) return 0;
  451. CSPString sFileName;
  452. GetFileName( sFileName, CStock::dataBasetext, &(pstock->GetStockInfo()) );
  453. int nCount = 0;
  454. CSPFile file;
  455. if( file.Open( sFileName, CSPFile::modeRead | CSPFile::shareDenyNone ) )
  456. {
  457. DWORD dwLen = file.GetLength();
  458. if( pstock->AllocBaseTextMem( dwLen ) )
  459. {
  460. nCount = file.Read( pstock->GetBaseTextPtr(), dwLen );
  461. }
  462. file.Close();
  463. }
  464. return nCount;
  465. }
  466. int CQianlong::LoadKData( CStock *pstock, int nKType )
  467. {
  468. SP_ASSERT( m_bIsOK && pstock && pstock->GetStockInfo().IsValidStock() );
  469. if( ! m_bIsOK || ! pstock || !pstock->GetStockInfo().IsValidStock() ) return 0;
  470. CKData * pkdata = NULL;
  471. DWORD dwMarket = pstock->GetStockInfo().GetMarket();
  472. CSPString sCode = pstock->GetStockCode();
  473. CSPString sFileName;
  474. GetFileName( sFileName, CStock::dataK, &(pstock->GetStockInfo()), nKType );
  475. switch( nKType )
  476. {
  477. case CKData::ktypeMonth:
  478. pkdata = &(pstock->GetKDataMonth());
  479. break;
  480. case CKData::ktypeWeek:
  481. pkdata = &(pstock->GetKDataWeek());
  482. break;
  483. case CKData::ktypeDay:
  484. pkdata = &(pstock->GetKDataDay());
  485. break;
  486. case CKData::ktypeMin60:
  487. return 0;
  488. case CKData::ktypeMin30:
  489. return 0;
  490. case CKData::ktypeMin15:
  491. return 0;
  492. case CKData::ktypeMin5:
  493. pkdata = &(pstock->GetKDataMin5());
  494. break;
  495. default:
  496. return 0;
  497. }
  498. if( CKData::IsDayOrMin(nKType) )
  499. {
  500. CSPFile file;
  501. if( pkdata && file.Open( sFileName, CSPFile::modeRead | CSPFile::shareDenyNone ) )
  502. {
  503. DWORD dwLen = file.GetLength();
  504. struct QL_Data_day qlkd;
  505. int nSize = dwLen/sizeof(qlkd);
  506. int nOldMaindataType = pkdata->GetMaindataType();
  507. pkdata->Clear();
  508. pkdata->SetKType( nKType );
  509. pkdata->SetMaindataType( nOldMaindataType );
  510. pkdata->SetSize( 0, nSize+1 );
  511. while( sizeof(qlkd) == file.Read( &qlkd, sizeof(qlkd) ) )
  512. {
  513. KDATA kd;
  514. convert_QL_Data_day_to_KDATA( dwMarket, sCode, &qlkd, &kd );
  515. pkdata->Add( kd );
  516. }
  517. file.Close();
  518. }
  519. }
  520. else
  521. {
  522. CSPFile file;
  523. if( pkdata && file.Open( sFileName, CSPFile::modeRead | CSPFile::shareDenyNone ) )
  524. {
  525. DWORD dwLen = file.GetLength();
  526. struct QL_Data_5min qlkd;
  527. int nSize = dwLen/sizeof(qlkd);
  528. int nOldMaindataType = pkdata->GetMaindataType();
  529. pkdata->Clear();
  530. pkdata->SetKType( nKType );
  531. pkdata->SetMaindataType( nOldMaindataType );
  532. pkdata->SetSize( 0, nSize+1 );
  533. while( sizeof(qlkd) == file.Read( &qlkd, sizeof(qlkd) ) )
  534. {
  535. KDATA kd;
  536. convert_QL_Data_5min_to_KDATA( dwMarket, sCode, &qlkd, &kd );
  537. pkdata->Add( kd );
  538. }
  539. file.Close();
  540. }
  541. }
  542. return pkdata->GetSize();
  543. }
  544. int CQianlong::LoadDRData( CStock *pstock )
  545. {
  546. return 0;
  547. }
  548. int CQianlong::StoreDRData( CStock *pstock )
  549. {
  550. return 0;
  551. }
  552. int CQianlong::LoadReport( CStock *pstock )
  553. {
  554. // load shtrace.dat sztrace.dat
  555. return 0;
  556. }
  557. int CQianlong::LoadMinute( CStock *pstock )
  558. {
  559. // load shminute.dat szminute.dat
  560. return 0;
  561. }
  562. int CQianlong::LoadOutline( CStock *pstock )
  563. {
  564. return 0;
  565. }
  566. int CQianlong::StoreReport( REPORT * pReport, int nCount, BOOL bBigTrade )
  567. {
  568. SP_ASSERT( FALSE );
  569. return 0;
  570. }
  571. int CQianlong::StoreMinute( MINUTE * pMinute, int nCount )
  572. {
  573. SP_ASSERT( FALSE );
  574. return 0;
  575. }
  576. int CQianlong::StoreOutline( OUTLINE * pOutline, int nCount )
  577. {
  578. SP_ASSERT( FALSE );
  579. return 0;
  580. }
  581. int CQianlong::DetectVersion( const char * szRootPath )
  582. {
  583. int nRet = versionUnknown;
  584. if( ! szRootPath ) return nRet;
  585. int  nCount = 0;
  586. CSPString sFileName = szRootPath;
  587. sFileName += ml_sh_now;
  588. CSPFile file;
  589. if( file.Open( sFileName, CSPFile::modeRead | CSPFile::shareDenyNone ) )
  590. {
  591. int nErrorCount = 1;
  592. int nTotalCount = 1;
  593. struct QL_Stock_info_V302 block;
  594. while( sizeof(block) == file.Read( &block, sizeof(block) ) )
  595. {
  596. nTotalCount ++;
  597. if( block.data_id != 0 && block.data_id != 0xFF && block.data_id != 0x94 )
  598. {
  599. nErrorCount ++;
  600. }
  601. }
  602. if( (nErrorCount << 5) < nTotalCount )
  603. {
  604. nRet = version302;
  605. }
  606. else
  607. {
  608. nErrorCount = 1;
  609. nTotalCount = 1;
  610. struct QL_Stock_info2_V304 block2;
  611. file.SeekToBegin();
  612. while( sizeof(block2) == file.Read( &block2, sizeof(block2) ) )
  613. {
  614. nTotalCount ++;
  615. if( block2.data_id != 0 && block2.data_id != 0xFF )
  616. {
  617. nErrorCount ++;
  618. }
  619. }
  620. if( (nErrorCount << 5) < nTotalCount )
  621. nRet = version304;
  622. }
  623. file.Close();
  624. }
  625. return nRet;
  626. }
  627. BOOL CQianlong::GetAccurateRoot( const char * rootpath, char *accurateroot, int maxlen )
  628. {
  629. if( 0 == rootpath || strlen(rootpath)==0 )
  630. return FALSE;
  631. // get rootpath
  632. CSPString strRoot = rootpath;
  633. int nLen = strRoot.GetLength();
  634. if( strRoot[nLen-1] != '\' && strRoot[nLen-1] != '/' )
  635. strRoot += CHAR_DIRSEP;
  636. nLen = strRoot.GetLength();
  637. if( 0 != access( strRoot + ml_sh_now, 0 ) )
  638. return FALSE;
  639. if( 0 != access( strRoot + ml_sh, 0 ) )
  640. return FALSE;
  641. if( 0 != access( strRoot + ml_sh_base, 0 ) )
  642. return FALSE;
  643. if( 0 != access( strRoot + ml_sh_day, 0 ) )
  644. return FALSE;
  645. if( 0 != access( strRoot + ml_sh_min, 0 ) )
  646. return FALSE;
  647. strncpy( accurateroot, strRoot, maxlen-1);
  648. accurateroot[maxlen-1] = '';
  649. return TRUE;
  650. }
  651. int CQianlong::InstallCodetbl( const char * filename, const char *orgname )
  652. {
  653. if( NULL == filename || strlen(filename) == 0
  654. || NULL == orgname || strlen(orgname) == 0 )
  655. return 0;
  656. CSPString sFileName = GetRootPath();
  657. sFileName += ml_dat;
  658. sFileName += orgname;
  659. return CSPFile::CopyFile( filename, sFileName, FALSE );
  660. }
  661. int CQianlong::InstallCodetblBlock( const char * filename, const char *orgname )
  662. {
  663. SP_ASSERT( FALSE );
  664. return 0;
  665. }
  666. int CQianlong::InstallCodetblFxjBlock( const char * filename, const char *orgname )
  667. {
  668. SP_ASSERT( FALSE );
  669. return 0;
  670. }
  671. int CQianlong::InstallKData( CKData &kdata, BOOL bOverwrite )
  672. {
  673. UINT nOpenFlags = CSPFile::modeCreate | CSPFile::modeReadWrite;
  674. if( !bOverwrite ) nOpenFlags |= CSPFile::modeNoTruncate;
  675. int nCount = 0;
  676. CSPFile fileTo;
  677. CSPString sFileName;
  678. CStockInfo stockinfo;
  679. DWORD dwMarket = kdata.ElementAt(0).m_dwMarket;
  680. CSPString sCode = kdata.ElementAt(0).m_szCode;
  681. stockinfo.SetStockCode( dwMarket, sCode );
  682. if( !GetFileName( sFileName, CStock::dataK, &stockinfo, kdata.GetKType() ) )
  683. return 0;
  684. if( CKData::IsDayOrMin(kdata.GetKType()) )
  685. {
  686. if( fileTo.Open( sFileName, nOpenFlags ) )
  687. {
  688. for( int i=0; i<kdata.GetSize(); i++ )
  689. {
  690. struct QL_Data_day qlkdnew;
  691. convert_KDATA_to_QL_Data_day( &(kdata.ElementAt(i)), &qlkdnew );
  692. struct QL_Data_day qlkd;
  693. memset( &qlkd, 0, sizeof(qlkd) );
  694. BOOL bHas = FALSE;
  695. BOOL bInsert = FALSE;
  696. while( sizeof(qlkd) == fileTo.Read( &qlkd, sizeof(qlkd) ) )
  697. {
  698. if( qlkd.day_date == qlkdnew.day_date )
  699. {
  700. bHas = TRUE;
  701. fileTo.Seek( fileTo.GetPosition()-sizeof(qlkd), CSPFile::begin );
  702. break;
  703. }
  704. if( qlkd.day_date > qlkdnew.day_date )
  705. {
  706. bInsert = TRUE;
  707. break;
  708. }
  709. }
  710. if( bHas || !bInsert )
  711. fileTo.Write( &qlkdnew, sizeof(qlkdnew) );
  712. else if( bInsert )
  713. {
  714. int nCur = fileTo.GetPosition();
  715. int nLen = fileTo.GetLength();
  716. BYTE * pbuffer = new BYTE[nLen-nCur+1];
  717. if( pbuffer )
  718. {
  719. if( nLen - nCur > 0 ) fileTo.Read( pbuffer, nLen-nCur );
  720. fileTo.Seek( nCur-sizeof(qlkd), CSPFile::begin );
  721. fileTo.Write( &qlkdnew, sizeof(qlkdnew) );
  722. fileTo.Write( &qlkd, sizeof(qlkd) );
  723. if( nLen - nCur > 0 ) fileTo.Write( pbuffer, nLen-nCur );
  724. delete [] pbuffer;
  725. }
  726. fileTo.Seek( nCur, CSPFile::begin );
  727. }
  728. nCount ++;
  729. }
  730. }
  731. }
  732. else
  733. {
  734. if( fileTo.Open( sFileName, nOpenFlags ) )
  735. {
  736. for( int i=0; i<kdata.GetSize(); i++ )
  737. {
  738. struct QL_Data_5min qlkdnew;
  739. convert_KDATA_to_QL_Data_5min( &(kdata.ElementAt(i)), &qlkdnew );
  740. struct QL_Data_5min qlkd;
  741. memset( &qlkd, 0, sizeof(qlkd) );
  742. BOOL bHas = FALSE;
  743. BOOL bInsert = FALSE;
  744. while( sizeof(qlkd) == fileTo.Read( &qlkd, sizeof(qlkd) ) )
  745. {
  746. if( qlkd.min_off == qlkdnew.min_off )
  747. {
  748. bHas = TRUE;
  749. fileTo.Seek( fileTo.GetPosition()-sizeof(qlkd), CSPFile::begin );
  750. break;
  751. }
  752. if( qlkd.min_off > qlkdnew.min_off )
  753. {
  754. bInsert = TRUE;
  755. break;
  756. }
  757. }
  758. if( bHas || !bInsert )
  759. fileTo.Write( &qlkdnew, sizeof(qlkdnew) );
  760. else if( bInsert )
  761. {
  762. int nCur = fileTo.GetPosition();
  763. int nLen = fileTo.GetLength();
  764. BYTE * pbuffer = new BYTE[nLen-nCur+1];
  765. if( pbuffer )
  766. {
  767. if( nLen - nCur > 0 ) fileTo.Read( pbuffer, nLen-nCur );
  768. fileTo.Seek( nCur-sizeof(qlkd), CSPFile::begin );
  769. fileTo.Write( &qlkdnew, sizeof(qlkdnew) );
  770. fileTo.Write( &qlkd, sizeof(qlkd) );
  771. if( nLen - nCur > 0 ) fileTo.Write( pbuffer, nLen-nCur );
  772. delete [] pbuffer;
  773. }
  774. fileTo.Seek( nCur, CSPFile::begin );
  775. }
  776. nCount ++;
  777. }
  778. }
  779. }
  780. return nCount;
  781. }
  782. int CQianlong::InstallKDataTy( const char * stkfile, int nKType,
  783. PROGRESS_CALLBACK fnCallback, void *cookie )
  784. {
  785. if( NULL == stkfile || strlen(stkfile) == 0 )
  786. return 0;
  787. int nTotalRecordCount = 0;
  788. int nProgCount = 0;
  789. int nCount = 0;
  790. CSPFile file;
  791. if( file.Open( stkfile, CSPFile::modeRead ) )
  792. {
  793. TYDAY_FHEADER header;
  794. if( sizeof(header) == file.Read(&header,sizeof(header)) )
  795. {
  796. nTotalRecordCount = header.recordcount;
  797. TYDAY_RECORD block;
  798. CKData kdata( nKType );
  799. CSPString sCurCode;
  800. while( sizeof(block) == file.Read(&block,sizeof(block)) )
  801. {
  802. nProgCount ++;
  803. if( fnCallback && nTotalRecordCount > 0 )
  804. fnCallback( PROG_PROGRESS, DWORD(STKLIB_MAXF_PROGRESS*nProgCount/nTotalRecordCount), NULL, cookie );
  805. KDATA kdnew;
  806. if( CKData::IsDayOrMin(nKType) )
  807. convert_TYDAY_RECORD_to_KDATA( &block, &kdnew );
  808. else
  809. convert_TYDAY_RECORD_MIN_to_KDATA( &block, &kdnew );
  810. if( sCurCode.IsEmpty() )
  811. sCurCode = kdnew.m_szCode;
  812. if( 0 == strcmp(kdnew.m_szCode,sCurCode) )
  813. kdata.Add( kdnew );
  814. else
  815. {
  816. nCount += InstallKData( kdata );
  817. kdata.RemoveAll();
  818. kdata.Add( kdnew );
  819. sCurCode = kdnew.m_szCode;
  820. }
  821. }
  822. if( kdata.GetSize() > 0 )
  823. {
  824. nCount += InstallKData( kdata );
  825. kdata.RemoveAll();
  826. }
  827. }
  828. file.Close();
  829. }
  830. if( fnCallback )
  831. fnCallback( PROG_PROGRESS, STKLIB_MAX_PROGRESS, NULL, cookie );
  832. return nCount;
  833. }
  834. int CQianlong::InstallKDataFxj( const char * dadfile, int nKType,
  835. PROGRESS_CALLBACK fnCallback, void *cookie )
  836. {
  837. if( NULL == dadfile || strlen(dadfile) == 0 )
  838. return 0;
  839. int nTotalStockCount = 0;
  840. int nProgCount = 0;
  841. int nCount = 0;
  842. CSPFile file;
  843. if( file.Open( dadfile, CSPFile::modeRead ) )
  844. {
  845. FXJDAY_FHEADER header;
  846. if( sizeof(header) == file.Read(&header,sizeof(header)) )
  847. {
  848. nTotalStockCount = header.m_dwStockCount;
  849. FXJDAY_RECORD block;
  850. CKData kdata( nKType );
  851. DWORD dwMarket = CStock::marketUnknown;
  852. CSPString sCurCode;
  853. while( sizeof(block) == file.Read(&block,sizeof(block)) )
  854. {
  855. if( -1 == block.m_dwMagic )
  856. {
  857. if( kdata.GetSize() > 0 )
  858. nCount += InstallKData( kdata );
  859. kdata.RemoveAll();
  860. if( 'HS' == block.m_wMarket )
  861. dwMarket = CStock::marketSHSE;
  862. else if( 'ZS' == block.m_wMarket )
  863. dwMarket = CStock::marketSZSE;
  864. else
  865. dwMarket = CStock::marketUnknown;
  866. char code[sizeof(block.m_szCode)+2];
  867. memset( code, 0, sizeof(code) );
  868. strncpy( code, block.m_szCode, min(sizeof(code)-1,sizeof(block.m_szCode)) );
  869. sCurCode = code;
  870. nProgCount ++;
  871. if( fnCallback && nTotalStockCount > 0 )
  872. fnCallback( PROG_PROGRESS, DWORD(STKLIB_MAXF_PROGRESS*nProgCount/nTotalStockCount), NULL, cookie );
  873. }
  874. else
  875. {
  876. KDATA kdnew;
  877. if( convert_FXJDAY_RECORD_to_KDATA( dwMarket, sCurCode, nKType, &block, &kdnew ) )
  878. kdata.Add( kdnew );
  879. }
  880. }
  881. if( kdata.GetSize() > 0 )
  882. {
  883. nCount += InstallKData( kdata );
  884. kdata.RemoveAll();
  885. }
  886. }
  887. file.Close();
  888. }
  889. if( fnCallback )
  890. fnCallback( PROG_PROGRESS, STKLIB_MAX_PROGRESS, NULL, cookie );
  891. return nCount;
  892. }
  893. int CQianlong::InstallDRData( CDRData & drdata )
  894. {
  895. SP_ASSERT( FALSE );
  896. return 0;
  897. }
  898. int CQianlong::InstallDRDataClk( const char * filename, const char *orgname )
  899. {
  900. SP_ASSERT( FALSE );
  901. return 0;
  902. }
  903. int CQianlong::InstallDRDataFxj( const char * fxjfilename )
  904. {
  905. SP_ASSERT( FALSE );
  906. return 0;
  907. }
  908. int CQianlong::InstallBasetable( const char * filename, const char * orgname )
  909. {
  910. SP_ASSERT( FALSE );
  911. return 0;
  912. }
  913. int CQianlong::InstallBasetableTdx( const char * filename )
  914. {
  915. SP_ASSERT( FALSE );
  916. return 0;
  917. }
  918. int CQianlong::InstallBasetableFxj( const char * filename )
  919. {
  920. SP_ASSERT( FALSE );
  921. return 0;
  922. }
  923. int CQianlong::InstallBaseText( const char * filename, const char *orgname )
  924. {
  925. if( NULL == filename || strlen(filename) == 0
  926. || NULL == orgname || strlen(orgname) == 0 )
  927. return 0;
  928. CSPString sCode = orgname;
  929. int nIndex = sCode.Find( '.' );
  930. if( -1 != nIndex )
  931. {
  932. sCode = sCode.Left(nIndex);
  933. CStockInfo stockinfo;
  934. stockinfo.SetStockCode( CStock::marketUnknown, sCode );
  935. CSPString sFileName;
  936. if( GetFileName( sFileName, CStock::dataBasetext, &stockinfo ) )
  937. {
  938. return CSPFile::CopyFile( filename, sFileName, FALSE );
  939. }
  940. }
  941. return 0;
  942. }
  943. int CQianlong::InstallBaseText( const char * buffer, int nLen, const char *orgname )
  944. {
  945. if( NULL == buffer || nLen <= 0
  946. || NULL == orgname || strlen(orgname) == 0 )
  947. return 0;
  948. CSPString sCode = orgname;
  949. int nIndex = sCode.Find( '.' );
  950. if( -1 != nIndex )
  951. {
  952. sCode = sCode.Left(nIndex);
  953. CStockInfo stockinfo;
  954. stockinfo.SetStockCode( CStock::marketUnknown, sCode );
  955. CSPString sFileName;
  956. CSPFile file;
  957. if( GetFileName( sFileName, CStock::dataBasetext, &stockinfo )
  958. && file.Open(sFileName,CSPFile::modeWrite|CSPFile::modeCreate) )
  959. {
  960. file.Write( buffer, nLen );
  961. file.Close();
  962. return 1;
  963. }
  964. }
  965. return 0;
  966. }
  967. int CQianlong::InstallNewsText( const char * filename, const char *orgname )
  968. {
  969. SP_ASSERT( FALSE );
  970. return 0;
  971. }
  972. int CQianlong::InstallNewsText( const char * buffer, int nLen, const char *orgname )
  973. {
  974. SP_ASSERT( FALSE );
  975. return 0;
  976. }
  977. BOOL CQianlong::GetFileName( CSPString &sFileName, int nDataType,
  978. CStockInfo * pInfo, int nKType )
  979. {
  980. if( NULL == pInfo || !pInfo->IsValidStock() )
  981. return FALSE;
  982. // 确定市场类型
  983. if( CStock::marketUnknown == pInfo->GetMarket() )
  984. pInfo->ResolveTypeAndMarket( );
  985. if( CStock::dataBasetext == nDataType )
  986. {
  987. sFileName = GetRootPath();
  988. if( pInfo->IsShenZhen() )
  989. sFileName += ml_sz_base;
  990. else
  991. sFileName += ml_sh_base;
  992. sFileName += CSPString(pInfo->GetStockCode()) + ml_ext_base;
  993. return TRUE;
  994. }
  995. else if( CStock::dataK == nDataType )
  996. {
  997. sFileName = GetRootPath();
  998. if( pInfo->IsShenZhen() )
  999. sFileName += ml_sz;
  1000. else
  1001. sFileName += ml_sh;
  1002. switch( nKType )
  1003. {
  1004. case CKData::ktypeMonth:
  1005. sFileName += CSPString(ml_month) + pInfo->GetStockCode() + ml_ext_month;
  1006. break;
  1007. case CKData::ktypeWeek:
  1008. sFileName += CSPString(ml_week) + pInfo->GetStockCode() + ml_ext_week;
  1009. break;
  1010. case CKData::ktypeDay:
  1011. sFileName += CSPString(ml_day) + pInfo->GetStockCode() + ml_ext_day;
  1012. break;
  1013. case CKData::ktypeMin60:
  1014. return FALSE;
  1015. case CKData::ktypeMin30:
  1016. return FALSE;
  1017. case CKData::ktypeMin15:
  1018. return FALSE;
  1019. case CKData::ktypeMin5:
  1020. sFileName += CSPString(ml_min5) + pInfo->GetStockCode() + ml_ext_min5;
  1021. break;
  1022. default:
  1023. SP_ASSERT( FALSE );
  1024. return FALSE;
  1025. }
  1026. return TRUE;
  1027. }
  1028. else if( CStock::dataDR == nDataType )
  1029. {
  1030. return FALSE;
  1031. }
  1032. return FALSE;
  1033. }