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

金融证券系统

开发平台:

Visual C++

  1. /*
  2. Cross Platform Core Code.
  3. Copyright(R) 2001-2002 Balang Software.
  4. All rights reserved.
  5. Using:
  6. class CMinute;
  7. */
  8. #include "StdAfx.h"
  9. #include "../Include/Stock.h"
  10. #ifdef _DEBUG
  11. #undef THIS_FILE
  12. static char THIS_FILE[] = __FILE__;
  13. #endif
  14. #ifdef _DEBUG
  15. #define new DEBUG_NEW
  16. #endif
  17. /////////////////////////////////////////////////////////////////////////////
  18. CMinute::CMinute()
  19. {
  20. m_pData = NULL;
  21. m_nSize = m_nMaxSize = m_nGrowBy = 0;
  22. }
  23. CMinute::CMinute( const CMinute &src )
  24. {
  25. m_pData = NULL;
  26. m_nSize = m_nMaxSize = m_nGrowBy = 0;
  27. *this = src;
  28. }
  29. CMinute::~CMinute()
  30. {
  31. if( m_pData )
  32. delete [] (BYTE*)m_pData;
  33. }
  34. void CMinute::SetSize(int nNewSize, int nGrowBy /* = -1 */)
  35. {
  36. SP_ASSERT(nNewSize >= 0);
  37. if (nGrowBy != -1)
  38. m_nGrowBy = nGrowBy;  // set new size
  39. if (nNewSize == 0)
  40. {
  41. // shrink to nothing
  42. delete [] (BYTE*)m_pData;
  43. m_pData = NULL;
  44. m_nSize = m_nMaxSize = 0;
  45. }
  46. else if (m_pData == NULL)
  47. {
  48. // create one with exact size
  49. #ifdef SIZE_T_MAX
  50. SP_ASSERT((long)nNewSize * sizeof(MINUTE) <= SIZE_T_MAX);  // no overflow
  51. #endif
  52. m_pData = (MINUTE*) new BYTE[nNewSize * sizeof(MINUTE)];
  53. memset(m_pData, 0, nNewSize * sizeof(MINUTE));  // zero fill
  54. m_nSize = m_nMaxSize = nNewSize;
  55. }
  56. else if (nNewSize <= m_nMaxSize)
  57. {
  58. // it fits
  59. if (nNewSize > m_nSize)
  60. {
  61. // initialize the new elements
  62. memset(&m_pData[m_nSize], 0, (nNewSize-m_nSize) * sizeof(MINUTE));
  63. }
  64. m_nSize = nNewSize;
  65. }
  66. else
  67. {
  68. // Otherwise grow array
  69. int nNewMax;
  70. if (nNewSize < m_nMaxSize + m_nGrowBy)
  71. nNewMax = m_nMaxSize + m_nGrowBy;  // granularity
  72. else
  73. nNewMax = nNewSize;  // no slush
  74. #ifdef SIZE_T_MAX
  75. SP_ASSERT((long)nNewMax * sizeof(MINUTE) <= SIZE_T_MAX);  // no overflow
  76. #endif
  77. MINUTE* pNewData = (MINUTE*) new BYTE[nNewMax * sizeof(MINUTE)];
  78. // copy new data from old
  79. memcpy(pNewData, m_pData, m_nSize * sizeof(MINUTE));
  80. // construct remaining elements
  81. SP_ASSERT(nNewSize > m_nSize);
  82. memset(&pNewData[m_nSize], 0, (nNewSize-m_nSize) * sizeof(MINUTE));
  83. // get rid of old stuff (note: no destructors called)
  84. delete [] (BYTE*)m_pData;
  85. m_pData = pNewData;
  86. m_nSize = nNewSize;
  87. m_nMaxSize = nNewMax;
  88. }
  89. }
  90. void CMinute::FreeExtra()
  91. {
  92. if (m_nSize != m_nMaxSize)
  93. {
  94. // shrink to desired size
  95. #ifdef SIZE_T_MAX
  96. SP_ASSERT((long)m_nSize * sizeof(MINUTE) <= SIZE_T_MAX);  // no overflow
  97. #endif
  98. MINUTE* pNewData = NULL;
  99. if (m_nSize != 0)
  100. {
  101. pNewData = (MINUTE*) new BYTE[m_nSize * sizeof(MINUTE)];
  102. // copy new data from old
  103. memcpy(pNewData, m_pData, m_nSize * sizeof(MINUTE));
  104. }
  105. // get rid of old stuff (note: no destructors called)
  106. delete [] (BYTE*)m_pData;
  107. m_pData = pNewData;
  108. m_nMaxSize = m_nSize;
  109. }
  110. }
  111. /////////////////////////////////////////////////////////////////////////////
  112. void CMinute::SetAtGrow(int nIndex, MINUTE newElement)
  113. {
  114. SP_ASSERT(nIndex >= 0);
  115. if (nIndex >= m_nSize)
  116. SetSize(nIndex+1);
  117. m_pData[nIndex] = newElement;
  118. }
  119. void CMinute::InsertAt(int nIndex, MINUTE newElement, int nCount /*=1*/)
  120. {
  121. SP_ASSERT(nIndex >= 0);    // will expand to meet need
  122. SP_ASSERT(nCount > 0);     // zero or negative size not allowed
  123. if (nIndex >= m_nSize)
  124. {
  125. // adding after the end of the array
  126. SetSize(nIndex + nCount);  // grow so nIndex is valid
  127. }
  128. else
  129. {
  130. // inserting in the middle of the array
  131. int nOldSize = m_nSize;
  132. SetSize(m_nSize + nCount);  // grow it to new size
  133. // shift old data up to fill gap
  134. memmove(&m_pData[nIndex+nCount], &m_pData[nIndex],
  135. (nOldSize-nIndex) * sizeof(MINUTE));
  136. // re-init slots we copied from
  137. memset(&m_pData[nIndex], 0, nCount * sizeof(MINUTE));
  138. }
  139. // insert new value in the gap
  140. SP_ASSERT(nIndex + nCount <= m_nSize);
  141. while (nCount--)
  142. m_pData[nIndex++] = newElement;
  143. }
  144. void CMinute::RemoveAt(int nIndex, int nCount /* = 1 */)
  145. {
  146. SP_ASSERT(nIndex >= 0);
  147. SP_ASSERT(nCount >= 0);
  148. SP_ASSERT(nIndex + nCount <= m_nSize);
  149. // just remove a range
  150. int nMoveCount = m_nSize - (nIndex + nCount);
  151. if (nMoveCount)
  152. memcpy(&m_pData[nIndex], &m_pData[nIndex + nCount],
  153. nMoveCount * sizeof(MINUTE));
  154. m_nSize -= nCount;
  155. }
  156. int CMinute::InsertMinuteSort( MINUTE newElement )
  157. {
  158. if( newElement.m_time <= 0 )
  159. return -1;
  160. else if( newElement.m_fNew < 1e-4 )
  161. return -1;
  162. else if( newElement.m_fVolume < 1e-4 )
  163. return -1;
  164. else if( !CSPTime::InTradeTime( newElement.m_time, 60 ) )
  165. return -1;
  166. time_t tmBegin = 0;
  167. if( GetSize() > 0 )
  168. {
  169. time_t tmLatest = ElementAt(GetSize()-1).m_time;
  170. CSPTime sptime(tmLatest);
  171. CSPTime sptimeBegin(sptime.GetYear(),sptime.GetMonth(),sptime.GetDay(),0,0,0);
  172. tmBegin = sptimeBegin.GetTime();
  173. }
  174. if( newElement.m_time <= tmBegin )
  175. return -1;
  176. for( int i=GetSize()-1; i>=0; i-- )
  177. {
  178. MINUTE & temp = ElementAt(i);
  179. if( newElement.m_time == temp.m_time )
  180. {
  181. SetAt(i,newElement);
  182. return i;
  183. }
  184. if( newElement.m_time > temp.m_time )
  185. {
  186. InsertAt(i+1,newElement);
  187. return i+1;
  188. }
  189. }
  190. InsertAt( 0, newElement );
  191. return 0;
  192. }
  193. int SortMinute(const void *p1,const void *p2)
  194. {
  195. MINUTE *pTemp1 = (MINUTE *)p1;
  196. MINUTE *pTemp2 = (MINUTE *)p2;
  197. if( pTemp1 && pTemp2 && pTemp1->m_time < pTemp2->m_time )
  198. return -1;
  199. else if( pTemp1 && pTemp2 && pTemp1->m_time > pTemp2->m_time )
  200. return 1;
  201. return 0;
  202. }
  203. void CMinute::Sort( )
  204. {
  205. if( m_pData )
  206. qsort( m_pData, GetSize(), sizeof(MINUTE), SortMinute );
  207. }
  208. void CMinute::RemoveDirty( )
  209. {
  210. time_t tmBegin = 0;
  211. if( GetSize() > 0 )
  212. {
  213. time_t tmLatest = ElementAt(GetSize()-1).m_time;
  214. CSPTime sptime(tmLatest);
  215. CSPTime sptimeBegin(sptime.GetYear(),sptime.GetMonth(),sptime.GetDay(),0,0,0);
  216. tmBegin = sptimeBegin.GetTime();
  217. }
  218. for( int i=GetSize()-1; i>=0; i-- )
  219. {
  220. if( ElementAt(i).m_time <= 0 )
  221. RemoveAt(i);
  222. else if( ElementAt(i).m_fNew < 1e-4 )
  223. RemoveAt(i);
  224. else if( ElementAt(i).m_fVolume < 1e-4 )
  225. RemoveAt(i);
  226. else if( !CSPTime::InTradeTime( ElementAt(i).m_time, 60 ) )
  227. RemoveAt(i);
  228. else if( ElementAt(i).m_time < tmBegin )
  229. RemoveAt(i);
  230. else if( i>1 && ElementAt(i).m_time == ElementAt(i-1).m_time )
  231. RemoveAt(i);
  232. }
  233. }
  234. void CMinute::InsertAt(int nStartIndex, CMinute* pNewArray)
  235. {
  236. SP_ASSERT(pNewArray != NULL);
  237. SP_ASSERT(nStartIndex >= 0);
  238. if (pNewArray->GetSize() > 0)
  239. {
  240. InsertAt(nStartIndex, pNewArray->GetAt(0), pNewArray->GetSize());
  241. for (int i = 0; i < pNewArray->GetSize(); i++)
  242. SetAt(nStartIndex + i, pNewArray->GetAt(i));
  243. }
  244. }
  245. CMinute & CMinute::operator = ( const CMinute &src )
  246. {
  247. Copy( src );
  248. return *this;
  249. }
  250. void CMinute::Copy( const CMinute &src )
  251. {
  252. SetSize( 0, src.GetSize()+5 );
  253. for( int i=0; i<src.GetSize(); i++ )
  254. {
  255. Add( src.GetAt(i) );
  256. }
  257. }
  258. BOOL CMinute::StatVolumeInfo( double *pdVolNow, double *pdVolOuter, double *pdVolInner )
  259. {
  260. time_t tmLatest = 0;
  261. double dVolNow = 0, dVolOuter = 0, dVolInner = 0;
  262. double dPriceLast = -1;
  263. BOOL bRise = TRUE;
  264. for( int k=0; k<GetSize(); k++ )
  265. {
  266. if( ElementAt(k).m_time > tmLatest )
  267. {
  268. tmLatest = ElementAt(k).m_time;
  269. dVolNow = ElementAt(k).m_fVolume;
  270. }
  271. double dPrice = ElementAt(k).m_fNew;
  272. if( 0 != k )
  273. {
  274. double dVolume = ElementAt(k).m_fVolume - ElementAt(k-1).m_fVolume;
  275. if( dPrice - dPriceLast > 1e-4 )
  276. bRise = TRUE;
  277. if( dPrice - dPriceLast < -1e-4 )
  278. bRise = FALSE;
  279. if( bRise ) dVolOuter += dVolume;
  280. else dVolInner += dVolume;
  281. }
  282. dPriceLast = dPrice;
  283. }
  284. if( pdVolNow )
  285. *pdVolNow = dVolNow;
  286. if( pdVolOuter )
  287. *pdVolOuter = dVolOuter;
  288. if( pdVolInner )
  289. *pdVolInner = dVolInner;
  290. return TRUE;
  291. }
  292. BOOL CMinute::StatDealInfo( CSPDWordArray & adwPrice, CSPDWordArray & adwVolume, double * pdMaxVolume )
  293. {
  294. adwPrice.RemoveAll();
  295. adwVolume.RemoveAll();
  296. for( int k=0; k<GetSize(); k++ )
  297. adwPrice.AddUnique( DWORD(ElementAt(k).m_fNew * 1000) );
  298. adwPrice.Sort( );
  299. adwVolume.SetSize( adwPrice.GetSize() );
  300. for( k=0; k<GetSize(); k++ )
  301. {
  302. DWORD dwPrice = DWORD(ElementAt(k).m_fNew * 1000);
  303. DWORD dwVolume = DWORD(ElementAt(k).m_fVolume);
  304. if( k > 0 )
  305. dwVolume = DWORD( ElementAt(k).m_fVolume - ElementAt(k-1).m_fVolume );
  306. for( int i=0; i<adwPrice.GetSize(); i++ )
  307. {
  308. if( adwPrice[i] == dwPrice )
  309. break;
  310. }
  311. if( i >= adwPrice.GetSize() )
  312. continue;
  313. adwVolume[i] += dwVolume;
  314. }
  315. double dMaxVolume = 0;
  316. for( k=0; k<adwVolume.GetSize(); k++ )
  317. {
  318. if( dMaxVolume < (double)adwVolume[k] )
  319. dMaxVolume = (double)adwVolume[k];
  320. }
  321. if( pdMaxVolume )
  322. *pdMaxVolume = dMaxVolume;
  323. return adwPrice.GetSize() > 0;
  324. }
  325. BOOL CMinute::GetDiffPercentMin5( double * pValue )
  326. {
  327. if( GetSize( ) < 2 )
  328. return FALSE;
  329. MINUTE & minCurrent = ElementAt(GetSize()-1);
  330. for( int i=GetSize()-2; i>=0; i-- )
  331. {
  332. LONG l = minCurrent.m_time - ElementAt(i).m_time;
  333. if( l >= 200 && l <= 600 )
  334. {
  335. if( ElementAt(i).m_fNew > 1e-4 && minCurrent.m_fNew > 1e-4 )
  336. {
  337. if( pValue ) *pValue = 100*minCurrent.m_fNew / ElementAt(i).m_fNew - 100;
  338. return TRUE;
  339. }
  340. break;
  341. }
  342. }
  343. return FALSE;
  344. }
  345. BOOL CMinute::GetLBDKMinMaxInfo( double dVolAverage, double *pdMin, double *pdMax )
  346. {
  347. if( dVolAverage < 1e-4 )
  348. return FALSE;
  349. double dMulti = 1 / dVolAverage;
  350. double dMin = 0, dMax = 1;
  351. for( int i=0; i<GetSize(); i++ )
  352. {
  353. CSPTime sptime(ElementAt(i).m_time);
  354. double dCurrent = dMulti * ElementAt(i).m_fVolume / CSPTime::GetTimeTradeRatioOfOneDay( sptime, sptime );
  355. if( 0 == i )
  356. {
  357. dMin = dCurrent;
  358. dMax = dCurrent;
  359. }
  360. if( dCurrent < dMin ) dMin = dCurrent;
  361. if( dCurrent > dMax ) dMax = dCurrent;
  362. }
  363. if( dMax < 1e-4 ) // 数据为零,缺省dMax=1
  364. dMax = 1;
  365. if( pdMin ) *pdMin = dMin;
  366. if( pdMax ) *pdMax = dMax;
  367. return TRUE;
  368. }
  369. BOOL CMinute::GetIndexWave( double *pdWave, int nIndex )
  370. {
  371. double dWave = 0;
  372. for( int k=nIndex-12; k<=nIndex; k++ )
  373. {
  374. if( k > 0 && k < GetSize() )
  375. dWave += ElementAt(k).m_fNew - ElementAt(k-1).m_fNew;
  376. }
  377. if( pdWave )
  378. *pdWave = dWave;
  379. return TRUE;
  380. }
  381. int CMinute::ToKData( CKData & kdata )
  382. {
  383. // WILLCHECK
  384. kdata.Clear();
  385. if( GetSize() <= 0 )
  386. return 0;
  387. DWORD dwType = ElementAt(0).m_dwType;
  388. if( 5 == dwType || 15 == dwType || 30 == dwType || 60 == dwType )
  389. {
  390. if( 5 == dwType )
  391. kdata.SetKType(CKData::ktypeMin5);
  392. else if( dwType )
  393. kdata.SetKType(CKData::ktypeMin15);
  394. else if( 30 == dwType )
  395. kdata.SetKType(CKData::ktypeMin30);
  396. else if( 60 == dwType )
  397. kdata.SetKType(CKData::ktypeMin60);
  398. kdata.SetSize( 0, GetSize() + 1 );
  399. for( int i=0; i<GetSize(); i++ )
  400. {
  401. MINUTE & min = ElementAt(i);
  402. KDATA kd;
  403. memset( &kd, 0, sizeof(kd) );
  404. kd.m_dwMarket = min.m_dwMarket;
  405. strncpy( kd.m_szCode, min.m_szCode, sizeof(kd.m_szCode)-1 );
  406. kd.m_time = min.m_time;
  407. CSPTime sptime(min.m_time);
  408. kd.m_date = sptime.ToStockTimeMin();
  409. kd.m_fOpen = (min.m_fHigh+min.m_fLow+min.m_fNew)/3;
  410. kd.m_fHigh = min.m_fHigh;
  411. kd.m_fLow = min.m_fLow;
  412. kd.m_fClose = min.m_fNew;
  413. kd.m_fVolume = min.m_fVolume;
  414. kd.m_fAmount = min.m_fAmount;
  415. kdata.Add( kd );
  416. }
  417. return kdata.GetSize();
  418. }
  419. kdata.SetKType(CKData::ktypeMin5);
  420. kdata.SetSize( 0, GetSize() / 5 + 5 );
  421. int nCount = 0;
  422. KDATA kd;
  423. for( int pos=0; pos<GetSize(); pos++ )
  424. {
  425. MINUTE & min = ElementAt( pos );
  426. nCount ++;
  427. if( 1 == nCount )
  428. {
  429. memset( &kd, 0, sizeof(kd) );
  430. kd.m_dwMarket = min.m_dwMarket;
  431. strncpy( kd.m_szCode, min.m_szCode, sizeof(kd.m_szCode)-1 );
  432. kd.m_fOpen = min.m_fNew;
  433. kd.m_fHigh = min.m_fHigh;
  434. kd.m_fLow = min.m_fLow;
  435. kd.m_fClose = min.m_fNew;
  436. kd.m_fVolume = min.m_fVolume;
  437. kd.m_fAmount = min.m_fAmount;
  438. }
  439. else
  440. {
  441. if( kd.m_fHigh < min.m_fHigh ) kd.m_fHigh = min.m_fHigh;
  442. if( kd.m_fLow > min.m_fLow ) kd.m_fLow = min.m_fLow;
  443. kd.m_fAmount += min.m_fAmount;
  444. kd.m_fVolume += min.m_fVolume;
  445. kd.m_fClose = min.m_fNew;
  446. }
  447. CSPTime sptime(min.m_time);
  448. DWORD date = sptime.ToStockTimeMin();
  449. if( !(date % 5) )
  450. {
  451. kd.m_time = min.m_time;
  452. kd.m_date = date;
  453. kdata.Add( kd );
  454. nCount = 0;
  455. }
  456. }
  457. return kdata.GetSize();
  458. }
  459. /////////////////////////////////////////////////////////////////////////////