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

金融证券系统

开发平台:

Visual C++

  1. // RealTime.cpp : implementation of the CRealTime class
  2. //
  3. #include "stdafx.h"
  4. #include "RealTime.h"
  5. #include <math.h>
  6. #ifdef _DEBUG
  7. #define new DEBUG_NEW
  8. #undef THIS_FILE
  9. static char THIS_FILE[] = __FILE__;
  10. #endif
  11. #define RT_DETERMINE_COLOR(x,y) ((x)-(y)>1e-4?clrRise:((x)-(y)<1e-4?clrFall:clrPlane))
  12. void DrawPriceAxisNumber(CDC * pDC, COLORREF clr, int nCount,
  13. int xStart, int yStart, int xEnd, int yEnd,
  14. double dLastClose, double fMin, double fMax, int nDotCount )
  15. {
  16. int nHeight = yEnd - yStart;
  17. if( nHeight <= 0 )
  18. return;
  19. if( nCount <= 0 )
  20. return;
  21. ASSERT( nDotCount >= 0 );
  22. CString strFmt;
  23. strFmt.Format( "%%.%df", nDotCount );
  24. pDC->SetTextColor( clr );
  25. CString strText;
  26. CSize sizeText;
  27. for( int k=0; k<=nCount; k++ )
  28. {
  29. double dCur = fMin+k*(fMax-fMin)/nCount;
  30. if( dCur < 0 && dCur > (0-0.6*pow(10,0-nDotCount)) )
  31. dCur = 0;
  32. strText.Format( strFmt, dCur );
  33. sizeText = pDC->GetTextExtent( strText );
  34. pDC->TextOut( xStart-sizeText.cx-1, yStart+(nCount-k)*nHeight/nCount-7, strText );
  35. }
  36. }
  37. BOOL DrawPriceVolumeAxis( CDC * pDC, CRect rectPrice, CRect rectVolume,
  38. int nGapYAxis, double dLastClose, double * pdMin, double * pdMax, double dMaxVolume, int nDotCount )
  39. {
  40. DECLARE_COLOR_DEFINATION
  41. ASSERT( pdMin && pdMax );
  42. if( NULL == pdMin || NULL == pdMax )
  43. return FALSE;
  44. if( rectPrice.Height() <= 0 || rectPrice.Width() <= 0 )
  45. return FALSE;
  46. if( rectVolume.Height() <= 0 || rectVolume.Width() <= 0 )
  47. return FALSE;
  48. ASSERT( rectPrice.left == rectVolume.left && rectPrice.right == rectVolume.right );
  49. ASSERT( nDotCount >= 0 );
  50. if( nGapYAxis <= 0 || nDotCount < 0 )
  51. return FALSE;
  52. if( dLastClose < 1e-4 )
  53. dLastClose = (*pdMin+*pdMax)/2;
  54. // 重新修正 *pdMin, *pdMax
  55. int nPriceLines = 2*((rectPrice.Height()/2)/nGapYAxis);
  56. int nVolumeLines = 2*((rectVolume.Height()/2)/nGapYAxis);
  57. double dABS = max(fabs(*pdMax-dLastClose),fabs(*pdMin-dLastClose));
  58. double dPrecision = pow(10,0-nDotCount);
  59. if( dABS < dPrecision*nPriceLines )
  60. dABS = dPrecision*nPriceLines;
  61. else if( dABS < 2*dPrecision*nPriceLines )
  62. dABS = 2*dPrecision*nPriceLines;
  63. else if( dABS < 3*dPrecision*nPriceLines )
  64. dABS = 3*dPrecision*nPriceLines;
  65. *pdMin = dLastClose-dABS;
  66. *pdMax = dLastClose+dABS;
  67. // Draw Border
  68. pDC->Draw3dRect( &rectPrice, clrBorder, clrBorder );
  69. pDC->Draw3dRect( &rectVolume, clrBorder, clrBorder );
  70. // Draw Lines
  71. for( int k=0; k<nPriceLines; k++ )
  72. DrawLine( pDC, 1, clrBorder, rectPrice.left, rectPrice.top+k*rectPrice.Height()/nPriceLines, rectPrice.right, rectPrice.top+k*rectPrice.Height()/nPriceLines );
  73. DrawLine( pDC, 2, clrBorder, rectPrice.left, rectPrice.top+rectPrice.Height()/2, rectPrice.right, rectPrice.top+rectPrice.Height()/2 );
  74. for( k=0; k<nVolumeLines; k++ )
  75. DrawLine( pDC, 1, clrBorder, rectVolume.left, rectVolume.top+k*rectVolume.Height()/nVolumeLines, rectVolume.right, rectVolume.top+k*rectVolume.Height()/nVolumeLines );
  76. // Draw Columns
  77. for(  k=1; k<=8; k++ )
  78. {
  79. if( k % 2 )
  80. DrawDashLine( pDC, 1, clrBorder, rectPrice.left+k*rectPrice.Width()/8, rectPrice.top, rectPrice.left+k*rectPrice.Width()/8, rectVolume.bottom );
  81. else
  82. DrawLine( pDC, 1, clrBorder, rectPrice.left+k*rectPrice.Width()/8, rectPrice.top, rectPrice.left+k*rectPrice.Width()/8, rectVolume.bottom );
  83. }
  84. // Draw Price Axis Number, Will Extent the rect
  85. CFont * pOldFont = AfxSelectDCFont( pDC, 12 );
  86. pDC->SetBkColor( clrBK );
  87. CSize sizeText;
  88. CString strFmt, strText;
  89. strFmt.Format( "%%.%df", nDotCount );
  90. double dMinAxis = dLastClose-dABS;
  91. double dMaxAxis = dLastClose+dABS;
  92. for( k=0; k<=nPriceLines && nPriceLines>0; k++ )
  93. {
  94. double dCur = dMinAxis+k*(dMaxAxis-dMinAxis)/nPriceLines;
  95. COLORREF clr = clrPlane;
  96. if( dCur-dLastClose > 1e-4)
  97. clr = clrRise;
  98. if( dCur-dLastClose < -1e-4 )
  99. clr = clrFall;
  100. if( dCur < 0 && dCur > (-0.51*pow(10,0-nDotCount)) )
  101. dCur = 0;
  102. strText.Format( strFmt, dCur );
  103. sizeText = pDC->GetTextExtent( strText );
  104. pDC->SetTextColor(  clr );
  105. pDC->TextOut( rectPrice.left-sizeText.cx-1, rectPrice.top+(nPriceLines-k)*rectPrice.Height()/nPriceLines-7, strText );
  106. double dCurPercent = 0.00;
  107. if( dLastClose > 1e-4 )
  108. dCurPercent = 100*fabs(dCur-dLastClose)/dLastClose;
  109. strText.Format( "%.2f%%", dCurPercent );
  110. pDC->TextOut( rectPrice.right+3, rectPrice.top+(nPriceLines-k)*rectPrice.Height()/nPriceLines-7, strText );
  111. }
  112. // Draw Volume Axis Number
  113. DrawAxisNumber( pDC, clrPlane, nVolumeLines, rectVolume.left, rectVolume.top, rectVolume.right, rectVolume.bottom,
  114. 0, dMaxVolume/100/*成交量手数*/, FALSE, FALSE, 0 );
  115. pDC->SelectObject( pOldFont );
  116. return TRUE;
  117. }
  118. /////////////////////////////////////////////////////////////////////////////
  119. // CRealTime
  120. #define RT_RDTITLE_HEIGHT 24
  121. #define RT_RDELEMENT_HEIGHT 16
  122. #define RT_RDCOLUMN_WIDTH 220
  123. CRealTime::CRealTime( )
  124. {
  125. m_pParent = NULL;
  126. m_nDrawMode = CRealTime::modePriceLine;
  127. m_nReportWhat = CRealTime::reportQuote;
  128. m_nTechLine = CRealTime::techNone;
  129. m_nIndexCurrent = -1;
  130. m_nCurrentStartPos = -1;
  131. m_nCurrentPageCount = -1;
  132. m_nCurrentSelectPos = -1;
  133. m_dMaxPrice = 0;
  134. m_dMinPrice = 0;
  135. ResetMargins( );
  136. ResetIndexCurrent( );
  137. }
  138. CRealTime::~CRealTime( )
  139. {
  140. ClearCurStock();
  141. }
  142. void CRealTime::SetParent( CWnd * pParent )
  143. {
  144. m_pParent = pParent;
  145. }
  146. void CRealTime::ResetMargins( int nMarginTop, int nMarginLeft,
  147. int nMarginCenter, int nMarginBottom,
  148. int nGapYAxis, int nWidthReport )
  149. {
  150. ASSERT( nMarginTop >= 0 && nMarginLeft >= 0 );
  151. ASSERT( nMarginCenter >= 0 && nMarginBottom >= 0 );
  152. ASSERT( nGapYAxis > 0 );
  153. ASSERT( nWidthReport >= 0 );
  154. m_nMarginTop = nMarginTop;
  155. m_nMarginLeft = nMarginLeft;
  156. m_nMarginCenter = nMarginCenter;
  157. m_nMarginBottom = nMarginBottom;
  158. m_nGapYAxis = nGapYAxis;
  159. m_nWidthReport = nWidthReport;
  160. if( m_nGapYAxis <= 0 )
  161. m_nGapYAxis = 18;
  162. }
  163. void CRealTime::ClearCurStock( )
  164. {
  165. m_CurStock.Clear();
  166. }
  167. BOOL CRealTime::SetCurStock( const char * szCode )
  168. {
  169. if( NULL == szCode || strlen(szCode) <= 0 )
  170. {
  171. ASSERT( FALSE );
  172. return FALSE;
  173. }
  174. CStockInfo info;
  175. if( !AfxGetStockContainer().GetStockInfo( szCode, &info ) )
  176. {
  177. ASSERT( FALSE );
  178. return FALSE;
  179. }
  180. return SetCurStock( info );
  181. }
  182. BOOL CRealTime::SetCurStock( CStockInfo & info )
  183. {
  184. if( m_CurStock.GetStockInfo().IsEqualTo( info.GetMarket(), info.GetStockCode() ) )
  185. {
  186. return TRUE;
  187. }
  188. ResetIndexCurrent( );
  189. ClearCurStock();
  190. m_CurStock.SetStockInfo( &info );
  191. return TRUE;
  192. }
  193. BOOL CRealTime::PrepareStockData( )
  194. {
  195. m_CurStock.GetReport().RemoveAll();
  196. m_CurStock.GetMinute().RemoveAll();
  197. m_CurStock.GetOutline().RemoveAll();
  198. // 读取本地文件
  199. m_CurStock.SetDatabase( &AfxGetDB() );
  200. // 取得最新行情
  201. m_CurStock.PrepareData( CStock::dataReport, CKData::ktypeDay, TRUE );
  202. m_CurStock.PrepareData( CStock::dataMinute, CKData::ktypeDay, TRUE );
  203. m_CurStock.PrepareData( CStock::dataOutline, CKData::ktypeDay, TRUE );
  204. AfxGetStkReceiver().GetReport( m_CurStock.GetStockInfo(), m_CurStock.GetReport() );
  205. int nLen = m_CurStock.GetReport().GetSize();
  206. if( nLen > 0 )
  207. UpdateStockInfoByREPORT( m_CurStock.GetStockInfo(), &(m_CurStock.GetReport().ElementAt(nLen-1)) );
  208. return TRUE;
  209. }
  210. void CRealTime::SetDrawMode( int nDrawMode, int nTechLine, int nReportWhat )
  211. {
  212. m_nDrawMode = nDrawMode;
  213. m_nTechLine = nTechLine;
  214. m_nReportWhat = nReportWhat;
  215. m_nCurrentStartPos = -1;
  216. m_nCurrentPageCount = -1;
  217. m_nCurrentSelectPos = -1;
  218. }
  219. int CRealTime::GetDrawMode( )
  220. {
  221. return m_nDrawMode;
  222. }
  223. int CRealTime::GetDrawTechLine( )
  224. {
  225. return m_nTechLine;
  226. }
  227. int CRealTime::GetReportWhat( )
  228. {
  229. return m_nReportWhat;
  230. }
  231. LRESULT CRealTime::OnStkReceiverData( WPARAM wParam, LPARAM lParam )
  232. {
  233. PCOMMPACKET pCommPacket = (PCOMMPACKET)lParam;
  234. switch( wParam )
  235. {
  236. case CStock::dataReport:
  237. if( pCommPacket && CStock::dataReport == pCommPacket->m_dwDataType )
  238. {
  239. BOOL bInv = FALSE;
  240. for(DWORD i=0; i<pCommPacket->m_dwCount; i++)
  241. {
  242. if( m_CurStock.GetStockInfo().IsEqualTo( pCommPacket->m_pReport[i].m_dwMarket, pCommPacket->m_pReport[i].m_szCode ) )
  243. {
  244. UpdateStockInfoByREPORT( m_CurStock.GetStockInfo(), &(pCommPacket->m_pReport[i]) );
  245. if( -1 != m_CurStock.GetReport().InsertReportSort( pCommPacket->m_pReport[i] ) )
  246. {
  247. MINUTE minute;
  248. if( convert_REPORT_to_MINUTE( &(pCommPacket->m_pReport[i]), &minute ) )
  249. m_CurStock.GetMinute().InsertMinuteSort( minute );
  250. m_nCurrentStartPos = -1;
  251. bInv = TRUE;
  252. }
  253. }
  254. }
  255. if( bInv && m_pParent && ::IsWindow(m_pParent->GetSafeHwnd()) )
  256. m_pParent->Invalidate();
  257. }
  258. break;
  259. case CStock::dataMinute:
  260. if( pCommPacket && CStock::dataMinute == pCommPacket->m_dwDataType )
  261. {
  262. int nOldSize = m_CurStock.GetMinute().GetSize();
  263. for(DWORD i=0; i<pCommPacket->m_dwCount; i++)
  264. {
  265. if( m_CurStock.GetStockInfo().IsEqualTo( pCommPacket->m_pMinute[i].m_dwMarket, pCommPacket->m_pMinute[i].m_szCode ) )
  266. m_CurStock.GetMinute().InsertMinuteSort( pCommPacket->m_pMinute[i] );
  267. }
  268. if( nOldSize != m_CurStock.GetMinute().GetSize() && m_pParent && ::IsWindow(m_pParent->GetSafeHwnd()) )
  269. {
  270. m_nCurrentStartPos = -1;
  271. m_pParent->Invalidate();
  272. }
  273. }
  274. break;
  275. }
  276. return 0L;
  277. }
  278. void CRealTime::Redraw( CDC * pDC, CRect rectAll )
  279. {
  280. ASSERT( m_pParent && ::IsWindow( m_pParent->GetSafeHwnd() ) );
  281. if( !m_pParent || !::IsWindow(m_pParent->GetSafeHwnd()) )
  282. return;
  283. CClientDC dc(m_pParent);
  284. if( NULL == pDC )
  285. pDC = &dc;
  286. ResetClient( rectAll );
  287. pDC->FillSolidRect( &rectAll, AfxGetProfile().GetColor(CColorClass::clrGraphBK) );
  288. if( CRealTime::modePriceLine == m_nDrawMode )
  289. {
  290. DrawPriceVolume( pDC );
  291. DrawLBDK( pDC );
  292. DrawMMLD( pDC );
  293. DrawReportRegion( pDC );
  294. DrawSelectionLine( pDC, TRUE );
  295. OnIndexCurrentChanged( );
  296. }
  297. else if( CRealTime::modeReportDetail == m_nDrawMode )
  298. {
  299. DrawReportDetail( pDC );
  300. }
  301. else if( CRealTime::modeMinuteDetail == m_nDrawMode )
  302. {
  303. DrawMinuteDetail( pDC );
  304. }
  305. else if( CRealTime::modeBigTradeDetail == m_nDrawMode )
  306. {
  307. DrawBigTradeDetail( pDC );
  308. }
  309. }
  310. void CRealTime::DrawReportRegion( CDC * pDC )
  311. {
  312. ASSERT( m_pParent && ::IsWindow( m_pParent->GetSafeHwnd() ) );
  313. if( !m_pParent || !::IsWindow(m_pParent->GetSafeHwnd()) )
  314. return;
  315. CClientDC dc(m_pParent);
  316. if( NULL == pDC )
  317. pDC = &dc;
  318. if( CRealTime::modePriceLine == m_nDrawMode )
  319. {
  320. switch( m_nReportWhat )
  321. {
  322. case CRealTime::reportQuote: DrawReportQuote( pDC ); break;
  323. case CRealTime::reportPrice: DrawReportPrice( pDC ); break;
  324. case CRealTime::reportMinute: DrawReportMinute( pDC ); break;
  325. case CRealTime::reportBuySellEx: DrawReportBuySellEx( pDC ); break;
  326. case CRealTime::reportValue: DrawReportValue( pDC ); break;
  327. case CRealTime::reportDistribute: DrawReportDistribute( pDC ); break;
  328. case CRealTime::reportBigTrade: DrawReportBigTrade( pDC ); break;
  329. }
  330. }
  331. }
  332. //////////////////////////////////////////////////////////////////////////////////////////////////////
  333. // 以下为分时价格线使用 modePriceLine
  334. void CRealTime::MoveLeft( BOOL bShiftPressed )
  335. {
  336. if( CRealTime::modePriceLine != m_nDrawMode )
  337. return;
  338. Move( -1, bShiftPressed, FALSE );
  339. }
  340. void CRealTime::MoveRight( BOOL bShiftPressed )
  341. {
  342. if( CRealTime::modePriceLine != m_nDrawMode )
  343. return;
  344. Move( 1, bShiftPressed, FALSE );
  345. }
  346. void CRealTime::MoveUp( BOOL bShiftPressed )
  347. {
  348. if( CRealTime::modePriceLine == m_nDrawMode )
  349. {
  350. int nTotalSize = 0;
  351. if( CRealTime::reportQuote == m_nReportWhat )
  352. nTotalSize = m_CurStock.GetReport().GetSize();
  353. // else if( CRealTime::reportPrice == m_nReportWhat )
  354. // nTotalSize = m_CurStock.GetMinute().GetSize();
  355. else if( CRealTime::reportMinute == m_nReportWhat )
  356. nTotalSize = m_CurStock.GetMinute().GetSize();
  357. else if( CRealTime::reportBuySellEx == m_nReportWhat )
  358. nTotalSize = m_CurStock.GetReport().GetSize();
  359. else if( CRealTime::reportBigTrade == m_nReportWhat )
  360. nTotalSize = m_aReportBigTrade.GetSize();
  361. else
  362. return;
  363. if( 0 == m_nCurrentStartPos )
  364. return;
  365. if( -1 == m_nCurrentStartPos )
  366. {
  367. m_nCurrentStartPos = 0;
  368. while( nTotalSize - m_nCurrentStartPos > m_nCurrentPageCount ) m_nCurrentStartPos += m_nCurrentPageCount;
  369. m_nCurrentStartPos -= m_nCurrentPageCount;
  370. }
  371. else
  372. m_nCurrentStartPos -= m_nCurrentPageCount;
  373. if( m_nCurrentStartPos < 0 || m_nCurrentStartPos >= nTotalSize )
  374. m_nCurrentStartPos = -1;
  375. DrawReportRegion( NULL );
  376. }
  377. }
  378. void CRealTime::MoveDown( BOOL bShiftPressed )
  379. {
  380. if( CRealTime::modePriceLine == m_nDrawMode )
  381. {
  382. int nTotalSize = 0;
  383. if( CRealTime::reportQuote == m_nReportWhat )
  384. nTotalSize = m_CurStock.GetReport().GetSize();
  385. // else if( CRealTime::reportPrice == m_nReportWhat )
  386. // nTotalSize = m_CurStock.GetMinute().GetSize();
  387. else if( CRealTime::reportMinute == m_nReportWhat )
  388. nTotalSize = m_CurStock.GetMinute().GetSize();
  389. else if( CRealTime::reportBuySellEx == m_nReportWhat )
  390. nTotalSize = m_CurStock.GetReport().GetSize();
  391. else if( CRealTime::reportBigTrade == m_nReportWhat )
  392. nTotalSize = m_aReportBigTrade.GetSize();
  393. else
  394. return;
  395. if( -1 != m_nCurrentStartPos )
  396. {
  397. m_nCurrentStartPos += m_nCurrentPageCount;
  398. }
  399. if( m_nCurrentStartPos < 0 || m_nCurrentStartPos >= nTotalSize )
  400. m_nCurrentStartPos = -1;
  401. DrawReportRegion( NULL );
  402. }
  403. }
  404. void CRealTime::MoveHome( BOOL bShiftPressed )
  405. {
  406. if( CRealTime::modePriceLine != m_nDrawMode )
  407. return;
  408. int nPos = ( m_CurStock.GetMinute().GetSize() > 0 ? 0 : -1 );
  409. MoveTo( nPos, bShiftPressed, FALSE );
  410. }
  411. void CRealTime::MoveEnd( BOOL bShiftPressed )
  412. {
  413. if( CRealTime::modePriceLine != m_nDrawMode )
  414. return;
  415. int nPos = ( m_CurStock.GetMinute().GetSize() > 0 ? m_CurStock.GetMinute().GetSize()-1 : -1 );
  416. MoveTo( nPos, bShiftPressed, FALSE );
  417. }
  418. void CRealTime::MoveTo( int nIndex, BOOL bShiftPressed, BOOL bCtrlPressed )
  419. {
  420. if( CRealTime::modePriceLine != m_nDrawMode )
  421. return;
  422. DrawSelectionLine( NULL, FALSE );
  423. // To Change m_anIndexCurrent
  424. if( bShiftPressed && nIndex >= 0 )
  425. {
  426. if( m_nIndexCurrent < 0 )
  427. {
  428. AddIndexCurrent( nIndex );
  429. }
  430. else if( m_nIndexCurrent <= nIndex )
  431. {
  432. for( int nSel=m_nIndexCurrent; nSel<=nIndex; nSel++ )
  433. {
  434. AddIndexCurrent( nSel );
  435. }
  436. }
  437. else
  438. {
  439. for( int nSel=nIndex; nSel<=m_nIndexCurrent; nSel++ )
  440. {
  441. AddIndexCurrent( nSel );
  442. }
  443. }
  444. }
  445. else if( bCtrlPressed && nIndex >= 0 )
  446. {
  447. AddIndexCurrent( nIndex );
  448. }
  449. else
  450. {
  451. m_anIndexCurrent.RemoveAll();
  452. }
  453. if( m_nIndexCurrent != nIndex )
  454. {
  455. m_nIndexCurrent = nIndex;
  456. OnIndexCurrentChanged( );
  457. }
  458. DrawSelectionLine( NULL, TRUE );
  459. }
  460. void CRealTime::Move( int nMove, BOOL bShiftPressed, BOOL bCtrlPressed )
  461. {
  462. if( CRealTime::modePriceLine != m_nDrawMode )
  463. return;
  464. int nIndexCurrent = m_nIndexCurrent;
  465. if( nIndexCurrent < 0 )
  466. {
  467. if( nMove < 0 )
  468. nIndexCurrent = m_CurStock.GetMinute().GetSize()-1;
  469. else if( nMove > 0 )
  470. nIndexCurrent = 0;
  471. }
  472. else
  473. {
  474. nIndexCurrent += nMove;
  475. }
  476. if( nIndexCurrent < 0 )
  477. nIndexCurrent = 0;
  478. if( nIndexCurrent >= m_CurStock.GetMinute().GetSize() )
  479. nIndexCurrent = m_CurStock.GetMinute().GetSize()-1;
  480. MoveTo( nIndexCurrent, bShiftPressed, bCtrlPressed );
  481. }
  482. void CRealTime::OnLButtonDown( UINT nFlags, CPoint point, BOOL bShiftPressed, BOOL bCtrlPressed )
  483. {
  484. if( CRealTime::modePriceLine == m_nDrawMode )
  485. {
  486. // Selection
  487. int nIndexClick = -1;
  488. CRect rect(m_rectPrice.left,m_rectPrice.top,m_rectPrice.right,m_rectAll.bottom-m_nMarginBottom);
  489. if( rect.PtInRect(point) )
  490. {
  491. DWORD dwSeconds = CSPTime::GetTradeSecondsOfOneDay();
  492. for( int nIndex=0; nIndex<m_CurStock.GetMinute().GetSize(); nIndex ++ )
  493. {
  494. CRect rectLine = rect;
  495. DWORD sec = CSPTime(m_CurStock.GetMinute()[nIndex].m_time).ToStockTimeSecOrder();
  496. DWORD secL = sec-100, secR = sec+100;
  497. if( nIndex > 0 )
  498. secL = CSPTime(m_CurStock.GetMinute()[nIndex-1].m_time).ToStockTimeSecOrder();
  499. if( nIndex < m_CurStock.GetMinute().GetSize()-1 )
  500. secR = CSPTime(m_CurStock.GetMinute()[nIndex+1].m_time).ToStockTimeSecOrder();
  501. rectLine.left = (int)( rect.left+rect.Width()*(secL+sec)*0.5/dwSeconds );
  502. rectLine.right = (int)( rect.left+rect.Width()*(sec+secR)*0.5/dwSeconds );
  503. if( rectLine.PtInRect(point) )
  504. {
  505. nIndexClick = nIndex;
  506. break;
  507. }
  508. }
  509. }
  510. MoveTo( nIndexClick, bShiftPressed, bCtrlPressed );
  511. if( CRealTime::modePriceLine == m_nDrawMode
  512. && CRealTime::reportBigTrade == m_nReportWhat )
  513. {
  514. // reportBigTrade 大单成交,选中股票
  515. if( m_rectReport.PtInRect(point) )
  516. {
  517. int nShowCount = (m_rectReport.Height()-RT_RDTITLE_HEIGHT) / RT_RDELEMENT_HEIGHT;
  518. if( nShowCount <= 0 ) nShowCount = 1;
  519. nIndexClick = -1;
  520. for( int nIndex=0; nIndex<nShowCount; nIndex ++ )
  521. {
  522. CRect rectElement = m_rectReport;
  523. rectElement.top = m_rectReport.top+RT_RDTITLE_HEIGHT+RT_RDELEMENT_HEIGHT*nIndex;
  524. rectElement.bottom = m_rectReport.top+RT_RDTITLE_HEIGHT+RT_RDELEMENT_HEIGHT*(nIndex+1);
  525. if( rectElement.PtInRect(point) )
  526. {
  527. nIndexClick = nIndex;
  528. break;
  529. }
  530. }
  531. // 画选中标记
  532. int nSelectPosNew = nIndexClick+m_nCurrentStartPos;
  533. if( -1 != nIndexClick && nSelectPosNew >= 0 && nSelectPosNew < m_aReportBigTrade.GetSize() )
  534. {
  535. DECLARE_COLOR_DEFINATION
  536. CClientDC dc(m_pParent);
  537. int y = m_rectReport.top+RT_RDTITLE_HEIGHT+RT_RDELEMENT_HEIGHT*(nIndexClick+1) - 1;
  538. if( y > m_rectReport.top && y < m_rectReport.bottom )
  539. DrawLine( &dc, 2, clrBorder, m_rectReport.left+5, y, m_rectReport.right-5, y );
  540. if( -1 != m_nCurrentSelectPos 
  541. && nSelectPosNew != m_nCurrentSelectPos
  542. && m_nCurrentSelectPos-m_nCurrentStartPos >= 0 )
  543. {
  544. y = m_rectReport.top+RT_RDTITLE_HEIGHT+RT_RDELEMENT_HEIGHT*(m_nCurrentSelectPos-m_nCurrentStartPos+1) - 1;
  545. if( y > m_rectReport.top && y < m_rectReport.bottom )
  546. DrawLine( &dc, 2, clrBK, m_rectReport.left+5, y, m_rectReport.right-5, y );
  547. }
  548. m_nCurrentSelectPos = nSelectPosNew;
  549. }
  550. }
  551. }
  552. }
  553. else if( CRealTime::modeBigTradeDetail == m_nDrawMode ) // 大单成交明细
  554. {
  555. int nColumnPerPage = GetColumnPerPage( m_rectAll );
  556. int nCountPerColumn = GetCountPerColumn( m_rectAll );
  557. int nCountPerPage = nCountPerColumn * nColumnPerPage;
  558. if( nCountPerPage <= 0 )
  559. return;
  560. int nOldSelectPos = m_nCurrentSelectPos;
  561. int nStartPos = m_nCurrentStartPos;
  562. for( int nColumn=0; nColumn<nColumnPerPage; nColumn ++ )
  563. {
  564. if( nStartPos >= m_aReportBigTrade.GetSize() )
  565. break;
  566. CRect rectColumn;
  567. rectColumn.top = m_rectAll.top + RT_RDTITLE_HEIGHT;
  568. rectColumn.bottom = m_rectAll.bottom;
  569. rectColumn.left = m_rectAll.left + nColumn*RT_RDCOLUMN_WIDTH;
  570. rectColumn.right = rectColumn.left + RT_RDCOLUMN_WIDTH;
  571. // 清除上次选中标记
  572. if( -1 != nOldSelectPos 
  573. && nOldSelectPos >= nStartPos
  574. && nOldSelectPos < nStartPos+nCountPerColumn )
  575. {
  576. DECLARE_COLOR_DEFINATION
  577. CClientDC dc(m_pParent);
  578. int y = rectColumn.top+RT_RDTITLE_HEIGHT+RT_RDELEMENT_HEIGHT*(nOldSelectPos-nStartPos+1) - 1;
  579. if( y > rectColumn.top && y < rectColumn.bottom )
  580. DrawLine( &dc, 2, clrBK, rectColumn.left+5, y, rectColumn.right-5, y );
  581. }
  582. if( rectColumn.PtInRect(point) )
  583. {
  584. int nIndexClick = -1;
  585. for( int nIndex=0; nIndex<nCountPerColumn; nIndex ++ )
  586. {
  587. CRect rectElement = rectColumn;
  588. rectElement.top = rectColumn.top+RT_RDTITLE_HEIGHT+RT_RDELEMENT_HEIGHT*nIndex;
  589. rectElement.bottom = rectColumn.top+RT_RDTITLE_HEIGHT+RT_RDELEMENT_HEIGHT*(nIndex+1);
  590. if( rectElement.PtInRect(point) )
  591. {
  592. nIndexClick = nIndex;
  593. break;
  594. }
  595. }
  596. // 画选中标记
  597. int nSelectPosNew = nIndexClick+nStartPos;
  598. if( -1 != nIndexClick && nSelectPosNew >= 0 && nSelectPosNew < m_aReportBigTrade.GetSize() )
  599. {
  600. DECLARE_COLOR_DEFINATION
  601. CClientDC dc(m_pParent);
  602. int y = rectColumn.top+RT_RDTITLE_HEIGHT+RT_RDELEMENT_HEIGHT*(nIndexClick+1) - 1;
  603. if( y > rectColumn.top && y < rectColumn.bottom )
  604. DrawLine( &dc, 2, clrBorder, rectColumn.left+5, y, rectColumn.right-5, y );
  605. m_nCurrentSelectPos = nSelectPosNew;
  606. }
  607. }
  608. nStartPos += nCountPerColumn;
  609. }
  610. }
  611. }
  612. void CRealTime::OnLButtonDblClk( UINT nFlags, CPoint point )
  613. {
  614. OnLButtonDown( nFlags, point, FALSE, FALSE );
  615. if( CRealTime::modePriceLine == m_nDrawMode
  616. && CRealTime::reportBigTrade == m_nReportWhat )
  617. {
  618. // reportBigTrade 大单成交,选中股票
  619. if( m_rectReport.PtInRect(point) )
  620. {
  621. if( m_nCurrentSelectPos >= 0 && m_nCurrentSelectPos < m_aReportBigTrade.GetSize() )
  622. {
  623. REPORT & report = m_aReportBigTrade.ElementAt(m_nCurrentSelectPos);
  624. AfxGetProfile().SetCurrentStock( report.m_szCode, FALSE );
  625. AfxGetStaticDoc()->UpdateAllViews( NULL, UPDATE_HINT_REALTIMEVIEW, NULL );
  626. }
  627. }
  628. }
  629. else if( CRealTime::modeBigTradeDetail == m_nDrawMode )
  630. {
  631. // 大单成交,选中股票
  632. if( m_nCurrentSelectPos >= 0 && m_nCurrentSelectPos < m_aReportBigTrade.GetSize() )
  633. {
  634. REPORT & report = m_aReportBigTrade.ElementAt(m_nCurrentSelectPos);
  635. AfxGetProfile().SetCurrentStock( report.m_szCode, FALSE );
  636. SetDrawMode( CRealTime::modePriceLine, GetDrawTechLine(), GetReportWhat() ); 
  637. AfxGetStaticDoc()->UpdateAllViews( NULL, UPDATE_HINT_REALTIMEVIEW, NULL );
  638. }
  639. }
  640. }
  641. void CRealTime::ResetIndexCurrent( int nIndexCurrent )
  642. {
  643. m_nIndexCurrent = nIndexCurrent;
  644. }
  645. BOOL CRealTime::AddIndexCurrent( int nIndex )
  646. {
  647. if( CRealTime::modePriceLine != m_nDrawMode )
  648. return FALSE;
  649. for( int k=0; k<m_anIndexCurrent.GetSize(); k++ )
  650. {
  651. if( (UINT)nIndex == m_anIndexCurrent[k] )
  652. return FALSE;
  653. }
  654. m_anIndexCurrent.Add( nIndex );
  655. return TRUE;
  656. }
  657. void CRealTime::OnIndexCurrentChanged( )
  658. {
  659. if( CRealTime::modePriceLine != m_nDrawMode )
  660. return;
  661. DECLARE_COLOR_DEFINATION
  662. if( !m_pParent || !::IsWindow(m_pParent->GetSafeHwnd()) )
  663. return;
  664. CClientDC dc(m_pParent);
  665. CDC *pDC = &dc;
  666. CRect rectTop(m_rectPrice.left+135,m_rectAll.top,m_rectPrice.right,m_rectPrice.top-1 );
  667. pDC->FillSolidRect( &rectTop, clrBK );
  668. if( m_nIndexCurrent < 0 || m_nIndexCurrent >= m_CurStock.GetMinute().GetSize() )
  669. return;
  670. MINUTE minute = m_CurStock.GetMinute().ElementAt(m_nIndexCurrent);
  671. // Fill Background
  672. pDC->SetBkColor( clrBK );
  673. CString strTemp;
  674. CFont * pOldFont = AfxSelectDCFont( pDC, 12 );
  675. int x = rectTop.left;
  676. int y = rectTop.top + 4;
  677. int right = rectTop.right-100;
  678. pDC->SetTextColor( clrText );
  679. strTemp.LoadString( IDS_REALTIME_TIME );
  680. if( x < right ) pDC->TextOut( x, y,   strTemp );
  681. strTemp.LoadString( IDS_REALTIME_PRICE );
  682. if( x+80 < right ) pDC->TextOut( x+80, y,  strTemp );
  683. strTemp.LoadString( IDS_REALTIME_VOLUME );
  684. if( x+160 < right ) pDC->TextOut( x+160, y,  strTemp );
  685. strTemp.LoadString( IDS_REALTIME_AMOUNT );
  686. if( x+290 < right ) pDC->TextOut( x+290, y,  strTemp );
  687. // Time
  688. CSPTime time(minute.m_time);
  689. strTemp = time.Format( "%H:%M" );
  690. pDC->SetTextColor( clrPlane );
  691. if( x+30 < right ) pDC->TextOut( x+30, y, strTemp );
  692. // Price
  693. CString strPriceFmt;
  694. strPriceFmt.Format( "%%.%df", m_CurStock.GetStockInfo().DigitBit() );
  695. strTemp.Format( strPriceFmt, minute.m_fNew );
  696. pDC->SetTextColor( RT_DETERMINE_COLOR( minute.m_fNew, m_CurStock.GetStockInfo().m_fLast ) );
  697. if( x+110 < right ) pDC->TextOut( x+110, y, strTemp );
  698. // Volume
  699. double dVolume = minute.m_fVolume;
  700. if( m_nIndexCurrent > 0 )
  701. dVolume -= m_CurStock.GetMinute()[m_nIndexCurrent-1].m_fVolume;
  702. strTemp.Format( "%.0f", dVolume*0.01 );
  703. pDC->SetTextColor( clrTitle );
  704. if( x+220 < right ) pDC->TextOut( x+220, y, strTemp );
  705. // Amount
  706. double dAmount = minute.m_fAmount;
  707. if( m_nIndexCurrent > 0 )
  708. dAmount -= m_CurStock.GetMinute()[m_nIndexCurrent-1].m_fAmount;
  709. strTemp.Format( "%.2f", dAmount*0.001 );
  710. pDC->SetTextColor( clrTitle );
  711. if( x+350 < right ) pDC->TextOut( x+350, y, strTemp );
  712. pDC->SelectObject( pOldFont );
  713. }
  714. void CRealTime::DrawSelectionLine( CDC * pDC, BOOL bAddOrRemove )
  715. {
  716. if( CRealTime::modePriceLine != m_nDrawMode )
  717. return;
  718. ASSERT( m_pParent && ::IsWindow( m_pParent->GetSafeHwnd() ) );
  719. if( !m_pParent || !::IsWindow(m_pParent->GetSafeHwnd()) )
  720. return;
  721. CClientDC dc(m_pParent);
  722. if( NULL == pDC )
  723. pDC = &dc;
  724. CPen penVLine( PS_SOLID, 1, AfxGetProfile().GetColor( CColorClass::clrLine1 ) );
  725. CPen * pOldPen = pDC->SelectObject( &penVLine );
  726. int nOldDrawMode = pDC->SetROP2( R2_XORPEN );
  727. DWORD dwSeconds = CSPTime::GetTradeSecondsOfOneDay();
  728. if( m_nIndexCurrent >= 0 && m_nIndexCurrent < m_CurStock.GetMinute().GetSize() )
  729. {
  730. DWORD sec = CSPTime(m_CurStock.GetMinute()[m_nIndexCurrent].m_time).ToStockTimeSecOrder();
  731. long xMedium = m_rectPrice.left+m_rectPrice.Width()*sec/dwSeconds;
  732. pDC->MoveTo( xMedium, m_rectPrice.top );
  733. pDC->LineTo( xMedium, m_rectAll.bottom - m_nMarginBottom );
  734. }
  735. for( int k=0; k<m_anIndexCurrent.GetSize(); k++ )
  736. {
  737. int nIndex = m_anIndexCurrent[k];
  738. if( nIndex == m_nIndexCurrent )
  739. continue;
  740. if( nIndex >= 0 && nIndex < m_CurStock.GetMinute().GetSize() )
  741. {
  742. DWORD sec = CSPTime(m_CurStock.GetMinute()[nIndex].m_time).ToStockTimeSecOrder();
  743. long xMedium = m_rectPrice.left+m_rectPrice.Width()*sec/dwSeconds;
  744. pDC->MoveTo( xMedium, m_rectPrice.top );
  745. pDC->LineTo( xMedium, m_rectAll.bottom - m_nMarginBottom );
  746. }
  747. }
  748. pDC->SetROP2( nOldDrawMode );
  749. pDC->SelectObject( pOldPen );
  750. }
  751. void CRealTime::ResetClient( CRect rectAll )
  752. {
  753. if( rectAll.IsRectEmpty() )
  754. return;
  755. m_rectAll = rectAll;
  756. // 买卖信息Rect
  757. m_rectReport.top = m_rectAll.top + m_nMarginTop + 7;
  758. m_rectReport.left = m_rectAll.right - m_nWidthReport;
  759. m_rectReport.bottom = m_rectAll.bottom - m_nMarginBottom;
  760. m_rectReport.right = m_rectAll.right;
  761. if( CRealTime::modePriceLine != m_nDrawMode )
  762. m_rectReport.SetRectEmpty();
  763. if( CRealTime::reportNone == m_nReportWhat )
  764. m_rectReport.SetRectEmpty();
  765. // 价格Rect
  766. m_rectPrice.top = m_rectAll.top + m_nMarginTop;
  767. m_rectPrice.left = m_rectAll.left + m_nMarginLeft;
  768. m_rectPrice.bottom = m_rectAll.top + (m_rectAll.Height() - m_nMarginTop - m_nMarginBottom)*7/10;
  769. m_rectPrice.right = m_rectAll.right - m_rectReport.Width() - m_nMarginCenter;
  770. // 成交量Rect
  771. m_rectVolume.top = m_rectPrice.bottom + 2;
  772. m_rectVolume.left = m_rectPrice.left;
  773. m_rectVolume.bottom = m_rectAll.bottom - m_nMarginBottom;
  774. m_rectVolume.right = m_rectPrice.right;
  775. // 量比多空指标
  776. m_rectLBDK.top = m_rectAll.bottom - m_nMarginBottom;
  777. m_rectLBDK.left = m_rectPrice.left;
  778. m_rectLBDK.bottom = m_rectAll.bottom - m_nMarginBottom;
  779. m_rectLBDK.right = m_rectPrice.right;
  780. // 买卖力道
  781. m_rectMMLD.top = m_rectAll.bottom - m_nMarginBottom;
  782. m_rectMMLD.left = m_rectPrice.left;
  783. m_rectMMLD.bottom = m_rectAll.bottom - m_nMarginBottom;
  784. m_rectMMLD.right = m_rectPrice.right;
  785. if( CRealTime::techLBDK == m_nTechLine )// 如果显示量比多空
  786. {
  787. m_rectPrice.bottom = m_rectAll.top + (m_rectAll.Height() - m_nMarginTop - m_nMarginBottom)*5/10;
  788. m_rectVolume.top = m_rectPrice.bottom + 2;
  789. m_rectVolume.bottom = m_rectVolume.top + m_rectVolume.Height()/2;
  790. m_rectLBDK.top = m_rectVolume.bottom + 1;
  791. }
  792. else if( CRealTime::techMMLD == m_nTechLine )// 如果显示买卖力道
  793. {
  794. m_rectPrice.bottom = m_rectAll.top + (m_rectAll.Height() - m_nMarginTop - m_nMarginBottom)*5/10;
  795. m_rectVolume.top = m_rectPrice.bottom + 2;
  796. m_rectVolume.bottom = m_rectVolume.top + m_rectVolume.Height()/2;
  797. m_rectMMLD.top = m_rectVolume.bottom + 1;
  798. }
  799. }
  800. void CRealTime::DrawDateAxis( CDC * pDC )
  801. {
  802. DECLARE_COLOR_DEFINATION
  803. CRect rect( m_rectAll.left, m_rectAll.bottom-m_nMarginBottom+1, m_rectPrice.right, m_rectAll.bottom );
  804. pDC->FillSolidRect( &rect, clrBK );
  805. pDC->SetBkColor( clrBK );
  806. pDC->SetTextColor( clrDJ );
  807. CFont * pOldFont = AfxSelectDCFont( pDC, 12 );
  808. UINT nAlignOld = pDC->SetTextAlign( TA_TOP | TA_CENTER );
  809. rect.left = m_rectPrice.left;
  810. int nStep = rect.Width()/4;
  811. pDC->TextOut( rect.left, rect.top, "09:30" );
  812. pDC->TextOut( rect.left+nStep, rect.top, "10:30" );
  813. pDC->TextOut( rect.left+nStep*2, rect.top, "11:30" );
  814. pDC->TextOut( rect.left+nStep*3, rect.top, "14:00" );
  815. pDC->TextOut( rect.right, rect.top, "15:00" );
  816. pDC->SetTextAlign( nAlignOld );
  817. pDC->SelectObject( pOldFont );
  818. }
  819. BOOL CRealTime::GetMinMaxInfo( double *pdLastClose, double *pdMin, double *pdMax, double *pdMaxVolume, BOOL bUptoAxis )
  820. {
  821. double dLastClose = 0;
  822. if( pdLastClose )
  823. dLastClose = *pdLastClose;
  824. double dMin = dLastClose, dMax = dLastClose, dMaxVolume = 10;
  825. BOOL bPriceOK = FALSE;
  826. REPORT report;
  827. if( m_CurStock.GetReport().GetSize() > 0 )
  828. {
  829. report = m_CurStock.GetReport().ElementAt( m_CurStock.GetReport().GetSize()-1 );
  830. if( report.m_fNew > 1e-4 && report.m_fHigh > 1e-4 && report.m_fLow > 1e-4 )
  831. {
  832. dMin = report.m_fLow;
  833. dMax = report.m_fHigh;
  834. bPriceOK = TRUE;
  835. }
  836. }
  837. for( int i=0; i<m_CurStock.GetMinute().GetSize(); i++ )
  838. {
  839. MINUTE & m = m_CurStock.GetMinute().ElementAt(i);
  840. if( !bPriceOK && dMin < 1e-4 )
  841. dMin = m.m_fNew;
  842. if( !bPriceOK && m.m_fNew < dMin )
  843. dMin = m.m_fNew;
  844. if( !bPriceOK && m.m_fNew > dMax )
  845. dMax = m.m_fNew;
  846. double dVolume = (i > 0 ? m_CurStock.GetMinute()[i].m_fVolume-m_CurStock.GetMinute()[i-1].m_fVolume : m_CurStock.GetMinute()[i].m_fVolume);
  847. if( dVolume > dMaxVolume )
  848. dMaxVolume = dVolume;
  849. }
  850. if( dLastClose < 1e-4 )
  851. dLastClose = (dMin+dMax)/2;
  852. if( bUptoAxis )
  853. {
  854. double dABS = 1.00 * max(fabs(dMax-dLastClose),fabs(dMin-dLastClose));
  855. if( dABS < dLastClose * 0.001 )
  856. dABS = dLastClose * 0.001;
  857. dMin = dLastClose-dABS;
  858. dMax = dLastClose+dABS;
  859. }
  860. if( pdLastClose )
  861. *pdLastClose = dLastClose;
  862. if( pdMin )
  863. *pdMin = dMin;
  864. if( pdMax )
  865. *pdMax = dMax;
  866. if( pdMaxVolume )
  867. *pdMaxVolume = dMaxVolume;
  868. return TRUE;
  869. }
  870. void CRealTime::DrawPriceVolume( CDC * pDC )
  871. {
  872. DECLARE_COLOR_DEFINATION
  873. // Draw Time Axis String
  874. DrawDateAxis( pDC );
  875. // Draw Title
  876. CString strTitle;
  877. pDC->SetTextColor( clrTitle );
  878. pDC->SetBkColor( clrBK );
  879. strTitle.LoadString( IDS_REALTIME_TITLE );
  880. if( CRealTime::modePriceLine != m_nDrawMode )
  881. strTitle = m_CurStock.GetStockCode();
  882. pDC->TextOut( m_rectPrice.left+1, m_rectAll.top+2, strTitle );
  883. double dMin = 0, dMax = 0, dMaxVolume = 0;
  884. double dLastClose = m_CurStock.GetStockInfo().m_fLast;
  885. if( ! GetMinMaxInfo( &dLastClose, &dMin, &dMax, &dMaxVolume, TRUE ) )
  886. return;
  887. // Draw Price Axis
  888. DrawPriceVolumeAxis( pDC, m_rectPrice, m_rectVolume, m_nGapYAxis,
  889. dLastClose, &dMin, &dMax, dMaxVolume, m_CurStock.GetStockInfo().DigitBit() );
  890. m_dMaxPrice = dMax;
  891. m_dMinPrice = dMin;
  892. // Draw Price and Volume Line
  893. CStockInfo & info = m_CurStock.GetStockInfo();
  894. CMinute & aMinute = m_CurStock.GetMinute();
  895. DWORD secNow = CSPTime::GetCurrentTime().ToStockTimeSecOrder();
  896. DWORD secStep = 60;
  897. double dPriceMA= dLastClose;
  898. int ptr = 0;
  899. int xPos = m_rectPrice.left;
  900. int yPosMid = m_rectPrice.top+m_rectPrice.Height()/2;
  901. int yPos = yPosMid;
  902. int yPosMA = yPos;
  903. int yPosLast = yPos;
  904. COLORREF clrLine1 = AfxGetProfile().GetColor(CColorClass::clrLine1);
  905. COLORREF clrLine2 = AfxGetProfile().GetColor(CColorClass::clrLine3);
  906. COLORREF clrWave = clrRise;
  907. COLORREF clrVolume = clrRise;
  908. DWORD dwSeconds = CSPTime::GetTradeSecondsOfOneDay();
  909. for( DWORD sec=0; sec<=dwSeconds; sec+=secStep )
  910. {
  911. BOOL bDrawed = FALSE;
  912. for( ; ptr<aMinute.GetSize(); ptr++ )
  913. {
  914. DWORD secTemp = CSPTime(aMinute[ptr].m_time).ToStockTimeSecOrder();
  915. if( secTemp > sec )
  916. break;
  917. if( (long)secTemp <= (long)sec-(long)secStep )
  918. continue;
  919. if( aMinute[ptr].m_fNew < 1e-4 )
  920. aMinute[ptr].m_fNew = m_CurStock.GetStockInfo().m_fLast;
  921. int xPosNew = m_rectPrice.left+m_rectPrice.Width()*secTemp/dwSeconds;
  922. yPosLast = yPos;
  923. // Draw Price Line
  924. CPen pen1( PS_SOLID, 1, clrLine1 );
  925. CPen * pOldPen = pDC->SelectObject( &pen1 );
  926. pDC->MoveTo( xPos, yPos );
  927. double dPriceNew = aMinute[ptr].m_fNew;
  928. if( dPriceNew <= dMax && dPriceNew >= dMin && dMax-dMin > 1e-4 )
  929. {
  930. yPos = (int)( m_rectPrice.top+m_rectPrice.Height()*(dMax-dPriceNew)/(dMax-dMin) );
  931. if( yPos <= m_rectPrice.top ) yPos = m_rectPrice.top+1;
  932. if( yPos >= m_rectPrice.bottom ) yPos = m_rectPrice.bottom-1;
  933. pDC->LineTo( xPosNew, yPos );
  934. }
  935. // Draw Price MA Lime
  936. CPen pen2( PS_SOLID, 1, clrLine2 );
  937. pDC->SelectObject( &pen2 );
  938. pDC->MoveTo( xPos, yPosMA );
  939. dPriceMA = (dPriceNew + ptr*dPriceMA)/(ptr+1);
  940. if( dPriceMA <= dMax && dPriceMA >= dMin
  941. && dPriceNew <= dMax && dPriceNew >= dMin && dMax-dMin > 1e-4 )
  942. {
  943. yPosMA = (int)( m_rectPrice.top+m_rectPrice.Height()*(dMax-dPriceMA)/(dMax-dMin) );
  944. if( yPosMA <= m_rectPrice.top ) yPosMA = m_rectPrice.top+1;
  945. if( yPosMA >= m_rectPrice.bottom ) yPosMA = m_rectPrice.bottom-1;
  946. pDC->LineTo( xPosNew, yPosMA );
  947. }
  948. // Draw Wave Line
  949. double dWave = 0;
  950. if( info.IsIndex() && aMinute.GetIndexWave( &dWave, ptr ) )
  951. {
  952. if( dWave > 0 ) clrWave = clrRise;
  953. if( dWave < 0 ) clrWave = clrFall;
  954. CPen pen3( PS_SOLID, 1, clrWave );
  955. pDC->SelectObject( &pen3 );
  956. pDC->MoveTo( xPosNew, yPosMid );
  957. if( fabs(dWave) < (dMax-dMin)*0.5
  958. && dPriceNew <= dMax && dPriceNew >= dMin && dMax-dMin > 1e-4)
  959. pDC->LineTo( xPosNew, yPosMid + m_rectPrice.Height() * 0.5 * dWave /(dMax-dMin) );
  960. }
  961. // Draw Volume Line
  962. if( yPos < yPosLast ) clrVolume = clrRise;
  963. if( yPos > yPosLast ) clrVolume = clrFall;
  964. CPen pen4( PS_SOLID, 1, clrVolume );
  965. pDC->SelectObject( &pen4 );
  966. pDC->MoveTo( xPosNew, m_rectVolume.bottom-1 );
  967. double dVolume = 0;
  968. if( ptr > 0 )
  969. dVolume = aMinute[ptr].m_fVolume-aMinute[ptr-1].m_fVolume;
  970. else if( sec <= secStep )
  971. dVolume = aMinute[ptr].m_fVolume;
  972. if( dVolume >= 0 && dVolume <= dMaxVolume && dMaxVolume > 1e-4
  973. && dPriceNew <= dMax && dPriceNew >= dMin && dMax-dMin > 1e-4)
  974. pDC->LineTo( xPosNew, (int)( m_rectVolume.bottom-m_rectVolume.Height()*dVolume/dMaxVolume ) );
  975. pDC->SelectObject( pOldPen );
  976. xPos = xPosNew;
  977. bDrawed = TRUE;
  978. }
  979. if( !bDrawed && sec <= secNow )
  980. {
  981. int xPosNew = m_rectPrice.left+m_rectPrice.Width()*sec/dwSeconds;
  982. // Draw Price Line
  983. CPen pen1( PS_SOLID, 1, clrLine1 );
  984. CPen * pOldPen = pDC->SelectObject( &pen1 );
  985. pDC->MoveTo( xPos, yPos );
  986. pDC->LineTo( xPosNew, yPos );
  987. // Draw Price MA Line
  988. CPen pen2( PS_SOLID, 1, clrLine2 );
  989. pDC->SelectObject( &pen2 );
  990. pDC->MoveTo( xPos, yPosMA );
  991. pDC->LineTo( xPosNew, yPosMA );
  992. pDC->SelectObject( pOldPen );
  993. xPos = xPosNew;
  994. }
  995. }
  996. }
  997. // 量比(多空)指标
  998. void CRealTime::DrawLBDK( CDC * pDC )
  999. {
  1000. if( CRealTime::techLBDK != m_nTechLine )
  1001. return;
  1002. DECLARE_COLOR_DEFINATION
  1003. // Draw Rect
  1004. pDC->FillSolidRect( &m_rectLBDK, clrBK );
  1005. pDC->Draw3dRect( &m_rectLBDK, clrBorder, clrBorder );
  1006. // Draw Title
  1007. CString strLBDK;
  1008. strLBDK.LoadString( IDS_REALTIME_LBDK );
  1009. DrawTechTitle( pDC, m_rectLBDK.left+5, m_rectLBDK.top+1, strLBDK, TA_LEFT | TA_TOP, 14, clrBK, clrTitle );
  1010. // Prepare Calculate
  1011. CStockInfo & info = m_CurStock.GetStockInfo();
  1012. CMinute & aMinute = m_CurStock.GetMinute();
  1013. double dVolRatio = 0;
  1014. if( !info.GetRatioVolume( &dVolRatio, info.m_datetech, 5 ) || dVolRatio < 1e-4 )
  1015. return;
  1016. double dVolAverage = (info.m_fVolume / dVolRatio);
  1017. // Draw Axis
  1018. double dMin = 0, dMax = 0;
  1019. if( !aMinute.GetLBDKMinMaxInfo( dVolAverage, &dMin, &dMax )
  1020. || !DrawAxis( pDC, m_rectLBDK, 0, 5, dMin, dMax, FALSE, FALSE, 2 ) )
  1021. return;
  1022. // Draw
  1023. DWORD secNow = CSPTime::GetCurrentTime().ToStockTimeSecOrder();
  1024. DWORD secStep = 60;
  1025. int ptr = 0;
  1026. int xPos = m_rectLBDK.left;
  1027. int yPos = m_rectLBDK.top+m_rectLBDK.Height()/2;
  1028. COLORREF clrLine1 = AfxGetProfile().GetColor(CColorClass::clrLine1);
  1029. DWORD dwSeconds = CSPTime::GetTradeSecondsOfOneDay();
  1030. for( DWORD sec=0; sec<=dwSeconds; sec+=secStep )
  1031. {
  1032. BOOL bDrawed = FALSE;
  1033. for( ; ptr<aMinute.GetSize(); ptr++ )
  1034. {
  1035. DWORD secTemp = CSPTime(aMinute[ptr].m_time).ToStockTimeSecOrder();
  1036. if( secTemp > sec )
  1037. break;
  1038. if( (long)secTemp <= (long)sec-(long)secStep )
  1039. continue;
  1040. int xPosNew = m_rectLBDK.left+m_rectLBDK.Width()*secTemp/dwSeconds;
  1041. // Draw LBDK Line
  1042. CPen pen1( PS_SOLID, 1, clrLine1 );
  1043. CPen * pOldPen = pDC->SelectObject( &pen1 );
  1044. pDC->MoveTo( xPos, yPos );
  1045. double dVolRatioNew = aMinute[ptr].m_fVolume/dVolAverage;
  1046. if( secTemp > 0 )
  1047. dVolRatioNew = dVolRatioNew * dwSeconds / secTemp;
  1048. if( dVolRatioNew <= dMax && dVolRatioNew >= dMin && dMax-dMin > 1e-4)
  1049. {
  1050. yPos = (int)( m_rectLBDK.top+m_rectLBDK.Height()*(dMax-dVolRatioNew)/(dMax-dMin) );
  1051. if( yPos <= m_rectLBDK.top ) yPos = m_rectLBDK.top+1;
  1052. if( yPos >= m_rectLBDK.bottom ) yPos = m_rectLBDK.bottom-1;
  1053. pDC->LineTo( xPosNew, yPos );
  1054. }
  1055. pDC->SelectObject( pOldPen );
  1056. xPos = xPosNew;
  1057. bDrawed = TRUE;
  1058. }
  1059. if( !bDrawed && sec <= secNow )
  1060. {
  1061. int xPosNew = m_rectLBDK.left+m_rectLBDK.Width()*sec/dwSeconds;
  1062. // Draw LBDK Line
  1063. CPen pen1( PS_SOLID, 1, clrLine1 );
  1064. CPen * pOldPen = pDC->SelectObject( &pen1 );
  1065. pDC->MoveTo( xPos, yPos );
  1066. pDC->LineTo( xPosNew, yPos );
  1067. pDC->SelectObject( pOldPen );
  1068. xPos = xPosNew;
  1069. }
  1070. }
  1071. }
  1072. // 买卖力道指标
  1073. void CRealTime::DrawMMLD( CDC * pDC )
  1074. {
  1075. if( CRealTime::techMMLD != m_nTechLine )
  1076. return;
  1077. DECLARE_COLOR_DEFINATION
  1078. // Draw Rect
  1079. pDC->FillSolidRect( &m_rectMMLD, clrBK );
  1080. pDC->Draw3dRect( &m_rectMMLD, clrBorder, clrBorder );
  1081. // Draw Title
  1082. CString strMMLD;
  1083. strMMLD.LoadString( IDS_REALTIME_MMLD );
  1084. DrawTechTitle( pDC, m_rectMMLD.left+5, m_rectMMLD.top+1, strMMLD, TA_LEFT | TA_TOP, 14, clrBK, clrTitle );
  1085. // Draw
  1086. CStockInfo & info = m_CurStock.GetStockInfo();
  1087. CReport & aReport = m_CurStock.GetReport();
  1088. // Draw Axis
  1089. double dMin = 0, dMax = 0;
  1090. if( !aReport.GetMMLDMinMaxInfo( &dMin, &dMax )
  1091. || !DrawAxis( pDC, m_rectMMLD, 0, 5, dMin*0.01, dMax*0.01, FALSE, FALSE, 0 ) )
  1092. return;
  1093. // Draw
  1094. DWORD secNow = CSPTime::GetCurrentTime().ToStockTimeSecOrder();
  1095. DWORD secStep = 60;
  1096. int ptr = 0;
  1097. int xPos = m_rectMMLD.left;
  1098. int yPosBuy = m_rectMMLD.top+m_rectMMLD.Height()/2;
  1099. int yPosSell = yPosBuy, yPosDiff = yPosBuy;
  1100. COLORREF clrLine1 = AfxGetProfile().GetColor(CColorClass::clrLine1);
  1101. COLORREF clrLine2 = AfxGetProfile().GetColor(CColorClass::clrLine3);
  1102. DWORD dwSeconds = CSPTime::GetTradeSecondsOfOneDay();
  1103. for( DWORD sec=0; sec<=dwSeconds; sec+=secStep )
  1104. {
  1105. BOOL bDrawed = FALSE;
  1106. for( ; ptr<aReport.GetSize(); ptr++ )
  1107. {
  1108. DWORD secTemp = CSPTime(aReport[ptr].m_time).ToStockTimeSecOrder();
  1109. if( secTemp > sec )
  1110. break;
  1111. if( (long)secTemp <= (long)sec-(long)secStep )
  1112. continue;
  1113. int xPosNew = m_rectMMLD.left+m_rectMMLD.Width()*secTemp/dwSeconds;
  1114. double dVolBuy = 0, dVolSell = 0, dVolDiff = 0;
  1115. if( !aReport.GetMMLD( ptr, &dVolBuy, &dVolSell, &dVolDiff ) )
  1116. break;
  1117. // Draw Buy Line
  1118. CPen pen1( PS_SOLID, 1, clrLine1 );
  1119. CPen * pOldPen = pDC->SelectObject( &pen1 );
  1120. pDC->MoveTo( xPos, yPosBuy );
  1121. if( dVolBuy <= dMax && dVolBuy >= dMin && dMax-dMin > 1e-4)
  1122. {
  1123. yPosBuy = (int)( m_rectMMLD.top+m_rectMMLD.Height()*(dMax-dVolBuy)/(dMax-dMin) );
  1124. if( yPosBuy <= m_rectMMLD.top ) yPosBuy = m_rectMMLD.top+1;
  1125. if( yPosBuy >= m_rectMMLD.bottom ) yPosBuy = m_rectMMLD.bottom-1;
  1126. pDC->LineTo( xPosNew, yPosBuy );
  1127. }
  1128. // Draw Sell Line
  1129. CPen pen2( PS_SOLID, 1, clrLine2 );
  1130. pDC->SelectObject( &pen2 );
  1131. pDC->MoveTo( xPos, yPosSell );
  1132. if( dVolSell <= dMax && dVolSell >= dMin )
  1133. {
  1134. yPosSell = (int)( m_rectMMLD.top+m_rectMMLD.Height()*(dMax-dVolSell)/(dMax-dMin) );
  1135. if( yPosSell <= m_rectMMLD.top ) yPosSell = m_rectMMLD.top+1;
  1136. if( yPosSell >= m_rectMMLD.bottom ) yPosSell = m_rectMMLD.bottom-1;
  1137. pDC->LineTo( xPosNew, yPosSell );
  1138. }
  1139. // Draw Diff Line
  1140. CPen pen3( PS_SOLID, 1, dVolDiff > 0 ? clrRise : clrFall );
  1141. pDC->SelectObject( &pen3 );
  1142. pDC->MoveTo( xPosNew, m_rectMMLD.top+m_rectMMLD.Height()/2 );
  1143. if( dVolDiff*0.5 <= dMax && dVolDiff*0.5 >= dMin && dMax-dMin > 1e-4 )
  1144. {
  1145. yPosDiff = (int)( m_rectMMLD.bottom-m_rectMMLD.Height()*(dVolDiff*0.5+dMax-dMin)*0.5/(dMax-dMin) );
  1146. if( yPosDiff <= m_rectMMLD.top ) yPosDiff = m_rectMMLD.top+1;
  1147. if( yPosDiff >= m_rectMMLD.bottom ) yPosDiff = m_rectMMLD.bottom-1;
  1148. pDC->LineTo( xPosNew, yPosDiff );
  1149. }
  1150. pDC->SelectObject( pOldPen );
  1151. xPos = xPosNew;
  1152. bDrawed = TRUE;
  1153. }
  1154. if( !bDrawed && sec <= secNow )
  1155. {
  1156. int xPosNew = m_rectMMLD.left+m_rectMMLD.Width()*sec/dwSeconds;
  1157. // Draw Buy Line
  1158. CPen pen1( PS_SOLID, 1, clrLine1 );
  1159. CPen * pOldPen = pDC->SelectObject( &pen1 );
  1160. pDC->MoveTo( xPos, yPosBuy );
  1161. pDC->LineTo( xPosNew, yPosBuy );
  1162. // Draw Sell Line
  1163. CPen pen2( PS_SOLID, 1, clrLine2 );
  1164. pDC->SelectObject( &pen2 );
  1165. pDC->MoveTo( xPos, yPosSell );
  1166. pDC->LineTo( xPosNew, yPosSell );
  1167. // Draw Diff Line
  1168. CPen pen3( PS_SOLID, 1, yPosDiff > m_rectMMLD.top+m_rectMMLD.Height() ? clrRise : clrFall );
  1169. pDC->SelectObject( &pen3 );
  1170. pDC->MoveTo( xPosNew, m_rectMMLD.top+m_rectMMLD.Height()/2 );
  1171. pDC->LineTo( xPosNew, yPosDiff );
  1172. pDC->SelectObject( pOldPen );
  1173. xPos = xPosNew;
  1174. }
  1175. }
  1176. }
  1177. int CRealTime::DrawBuySell( CDC * pDC, int xStart, int yStart, int nWidth )
  1178. {
  1179. DECLARE_COLOR_DEFINATION
  1180. CStockInfo & info = m_CurStock.GetStockInfo();
  1181. CString strTemp, strTempFmt;
  1182. // Draw Name And Code
  1183. CFont * pOldFont = AfxSelectDCFont( pDC, 18 );
  1184. pDC->SetTextColor( clrTitle );
  1185. pDC->TextOut( xStart+1, m_rectAll.top+3, info.GetStockName() );
  1186. pDC->SetTextColor( clrText );
  1187. pDC->TextOut( xStart+96, m_rectAll.top+3, info.GetStockCode() );
  1188. // Select Report Font
  1189. AfxSelectDCFont( pDC, 14 );
  1190. // Draw Report Names
  1191. int x = xStart+2;
  1192. int x2 = xStart+2+nWidth/2;
  1193. int y = yStart;
  1194. pDC->SetTextColor( clrText );
  1195. // 委比和委差
  1196. strTemp.LoadString( IDS_REALTIME_BSRATIO ); // "委比";
  1197. pDC->TextOut( x, y+2,   strTemp );
  1198. strTemp.LoadString( IDS_REALTIME_BSDIFF ); // "委差";
  1199. pDC->TextOut( x2, y+2,   strTemp );
  1200. // 委卖数
  1201. DrawLine( pDC, 1, clrBorder, xStart, y+19, xStart+nWidth, y+19 );
  1202. strTemp.LoadString( IDS_REALTIME_SELL5 ); // "卖⑤";
  1203. pDC->TextOut( x, y+21, strTemp );
  1204. strTemp.LoadString( IDS_REALTIME_SELL4 ); // "卖④";
  1205. pDC->TextOut( x, y+37, strTemp );
  1206. strTemp.LoadString( IDS_REALTIME_SELL3 ); // "卖③";
  1207. pDC->TextOut( x, y+53, strTemp );
  1208. strTemp.LoadString( IDS_REALTIME_SELL2 ); // "卖②";
  1209. pDC->TextOut( x, y+69, strTemp );
  1210. strTemp.LoadString( IDS_REALTIME_SELL1 ); // "卖①";
  1211. pDC->TextOut( x, y+85, strTemp );
  1212. // 委买数
  1213. DrawLine( pDC, 1, clrBorder, xStart, y+102, xStart+nWidth, y+102 );
  1214. strTemp.LoadString( IDS_REALTIME_BUY1 ); // "买①";
  1215. pDC->TextOut( x, y+104, strTemp );
  1216. strTemp.LoadString( IDS_REALTIME_BUY2 ); // "买②";
  1217. pDC->TextOut( x, y+120, strTemp );
  1218. strTemp.LoadString( IDS_REALTIME_BUY3 ); // "买③";
  1219. pDC->TextOut( x, y+136, strTemp );
  1220. strTemp.LoadString( IDS_REALTIME_BUY4 ); // "买④";
  1221. pDC->TextOut( x, y+152, strTemp );
  1222. strTemp.LoadString( IDS_REALTIME_BUY5 ); // "买⑤";
  1223. pDC->TextOut( x, y+168, strTemp );
  1224. // 其他信息报告
  1225. DrawLine( pDC, 1, clrBorder, xStart, y+185, xStart+nWidth, y+185 );
  1226. strTemp.LoadString( IDS_REALTIME_PRICENOW ); // "成交";
  1227. pDC->TextOut( x, y+187, strTemp );
  1228. strTemp.LoadString( IDS_REALTIME_PRICEAVE ); // "均价";
  1229. pDC->TextOut( x2, y+187, strTemp );
  1230. strTemp.LoadString( IDS_REALTIME_PRICEDIFF ); // "涨跌";
  1231. pDC->TextOut( x, y+203, strTemp );
  1232. strTemp.LoadString( IDS_REALTIME_PRICEOPEN ); // "开盘";
  1233. pDC->TextOut( x2, y+203, strTemp );
  1234. strTemp.LoadString( IDS_REALTIME_PRICEDIFFPERCENT ); // "幅度";
  1235. pDC->TextOut( x, y+219, strTemp );
  1236. strTemp.LoadString( IDS_REALTIME_PRICEHIGH ); // "最高";
  1237. pDC->TextOut( x2, y+219, strTemp );
  1238. strTemp.LoadString( IDS_REALTIME_VOLSUM ); // "总手";
  1239. pDC->TextOut( x, y+235, strTemp );
  1240. strTemp.LoadString( IDS_REALTIME_PRICELOW ); // "最低";
  1241. pDC->TextOut( x2, y+235, strTemp );
  1242. strTemp.LoadString( IDS_REALTIME_VOLNOW ); // "现手";
  1243. pDC->TextOut( x, y+251, strTemp );
  1244. strTemp.LoadString( IDS_REALTIME_VOLRATION ); // "量比";
  1245. pDC->TextOut( x2, y+251, strTemp );
  1246. // 内外盘
  1247. DrawLine( pDC, 1, clrBorder, xStart, y+268, xStart+nWidth, y+268 );
  1248. strTemp.LoadString( IDS_REALTIME_VOLOUTER ); // "外盘";
  1249. pDC->TextOut( x, y+270, strTemp );
  1250. strTemp.LoadString( IDS_REALTIME_VOLINNER ); // "内盘";
  1251. pDC->TextOut( x2, y+270, strTemp );
  1252. DrawLine( pDC, 1, clrBorder, xStart, y+287, xStart+nWidth, y+287 );
  1253. // 涨家数,跌家数
  1254. if( info.IsIndex() )
  1255. {
  1256. strTemp.LoadString( IDS_REALTIME_ADVANCE ); // "涨家数";
  1257. pDC->TextOut( x, y+289, strTemp );
  1258. strTemp.LoadString( IDS_REALTIME_DECLINE ); // "跌家数";
  1259. pDC->TextOut( x2, y+289, strTemp );
  1260. DrawLine( pDC, 1, clrBorder, xStart, y+306, xStart+nWidth, y+306 );
  1261. }
  1262. // Draw Report Values
  1263. x = xStart-1+nWidth/2;
  1264. x2 = xStart+nWidth-1;
  1265. UINT nOldAlign = pDC->SetTextAlign( TA_RIGHT | TA_TOP );
  1266. pDC->SetTextColor( clrPlane );
  1267. // 价格小数位数格式串
  1268. CString strPriceFmt;
  1269. strPriceFmt.Format( "%%.%df", info.DigitBit() );
  1270. if( info.IsIndex() )
  1271. {
  1272. // 委比和委差
  1273. double dRatio = 0, dDiff = 0;
  1274. strTemp.Format( "%.2f%%", dRatio );
  1275. pDC->TextOut( x, y+2,   strTemp );
  1276. strTemp.Format( "%.0f", dDiff*0.01 );
  1277. pDC->TextOut( x2, y+2,   strTemp );
  1278. // 委卖数
  1279. pDC->SetTextColor( clrText );
  1280. strTemp.Format( strPriceFmt, 0.0f );
  1281. pDC->TextOut( x, y+21, strTemp );
  1282. strTemp.Format( "%.0f", 0.0f );
  1283. pDC->TextOut( x2, y+21, strTemp );
  1284. strTemp.Format( strPriceFmt, 0.0f );
  1285. pDC->TextOut( x, y+37, strTemp );
  1286. strTemp.Format( "%.0f", 0.0f );
  1287. pDC->TextOut( x2, y+37, strTemp );
  1288. strTemp.Format( strPriceFmt, 0.0f );
  1289. pDC->TextOut( x, y+53, strTemp );
  1290. strTemp.Format( "%.0f", 0.0f );
  1291. pDC->TextOut( x2, y+53, strTemp );
  1292. strTemp.Format( strPriceFmt, 0.0f );
  1293. pDC->TextOut( x, y+69, strTemp );
  1294. strTemp.Format( "%.0f", 0.0f );
  1295. pDC->TextOut( x2, y+69, strTemp );
  1296. strTemp.Format( strPriceFmt, 0.0f );
  1297. pDC->TextOut( x, y+85, strTemp );
  1298. strTemp.Format( "%.0f", 0.0f );
  1299. pDC->TextOut( x2, y+85, strTemp );
  1300. // 委买数
  1301. strTemp.Format( strPriceFmt, 0.0f );
  1302. pDC->TextOut( x, y+104, strTemp );
  1303. strTemp.Format( "%.0f", 0.0f );
  1304. pDC->TextOut( x2, y+104, strTemp );
  1305. strTemp.Format( strPriceFmt, 0.0f );
  1306. pDC->TextOut( x, y+120, strTemp );
  1307. strTemp.Format( "%.0f", 0.0f );
  1308. pDC->TextOut( x2, y+120, strTemp );
  1309. strTemp.Format( strPriceFmt, 0.0f );
  1310. pDC->TextOut( x, y+136, strTemp );
  1311. strTemp.Format( "%.0f", 0.0f );
  1312. pDC->TextOut( x2, y+136, strTemp );
  1313. strTemp.Format( strPriceFmt, 0.0f );
  1314. pDC->TextOut( x, y+152, strTemp );
  1315. strTemp.Format( "%.0f", 0.0f );
  1316. pDC->TextOut( x2, y+152, strTemp );
  1317. strTemp.Format( strPriceFmt, 0.0f );
  1318. pDC->TextOut( x, y+168, strTemp );
  1319. strTemp.Format( "%.0f", 0.0f );
  1320. pDC->TextOut( x2, y+168, strTemp );
  1321. }
  1322. else
  1323. {
  1324. // 委比和委差
  1325. double dRatio = 0, dDiff = 0;
  1326. if( info.GetSellBuyRatio( &dRatio, &dDiff ) )
  1327. {
  1328. strTemp.Format( "%.2f%%", dRatio );
  1329. pDC->TextOut( x, y+2,   strTemp );
  1330. strTemp.Format( "%.0f", dDiff*0.01 );
  1331. pDC->TextOut( x2, y+2,   strTemp );
  1332. }
  1333. // 委卖数
  1334. pDC->SetTextColor( RT_DETERMINE_COLOR(info.m_fSellPrice[4],info.m_fLast) );
  1335. strTemp.Format( strPriceFmt, info.m_fSellPrice[4] );
  1336. pDC->TextOut( x, y+21, strTemp );
  1337. strTemp.Format( "%.0f", info.m_fSellVolume[4]/100 );
  1338. pDC->TextOut( x2, y+21, strTemp );
  1339. pDC->SetTextColor( RT_DETERMINE_COLOR(info.m_fSellPrice[3],info.m_fLast) );
  1340. strTemp.Format( strPriceFmt, info.m_fSellPrice[3] );
  1341. pDC->TextOut( x, y+37, strTemp );
  1342. strTemp.Format( "%.0f", info.m_fSellVolume[3]/100 );
  1343. pDC->TextOut( x2, y+37, strTemp );
  1344. pDC->SetTextColor( RT_DETERMINE_COLOR(info.m_fSellPrice[2],info.m_fLast) );
  1345. strTemp.Format( strPriceFmt, info.m_fSellPrice[2] );
  1346. pDC->TextOut( x, y+53, strTemp );
  1347. strTemp.Format( "%.0f", info.m_fSellVolume[2]/100 );
  1348. pDC->TextOut( x2, y+53, strTemp );
  1349. pDC->SetTextColor( RT_DETERMINE_COLOR(info.m_fSellPrice[1],info.m_fLast) );
  1350. strTemp.Format( strPriceFmt, info.m_fSellPrice[1] );
  1351. pDC->TextOut( x, y+69, strTemp );
  1352. strTemp.Format( "%.0f", info.m_fSellVolume[1]/100 );
  1353. pDC->TextOut( x2, y+69, strTemp );
  1354. pDC->SetTextColor( RT_DETERMINE_COLOR(info.m_fSellPrice[0],info.m_fLast) );
  1355. strTemp.Format( strPriceFmt, info.m_fSellPrice[0] );
  1356. pDC->TextOut( x, y+85, strTemp );
  1357. strTemp.Format( "%.0f", info.m_fSellVolume[0]/100 );
  1358. pDC->TextOut( x2, y+85, strTemp );
  1359. // 委买数
  1360. pDC->SetTextColor( RT_DETERMINE_COLOR(info.m_fBuyPrice[0],info.m_fLast) );
  1361. strTemp.Format( strPriceFmt, info.m_fBuyPrice[0] );
  1362. pDC->TextOut( x, y+104, strTemp );
  1363. strTemp.Format( "%.0f", info.m_fBuyVolume[0]/100 );
  1364. pDC->TextOut( x2, y+104, strTemp );
  1365. pDC->SetTextColor( RT_DETERMINE_COLOR(info.m_fBuyPrice[1],info.m_fLast) );
  1366. strTemp.Format( strPriceFmt, info.m_fBuyPrice[1] );
  1367. pDC->TextOut( x, y+120, strTemp );
  1368. strTemp.Format( "%.0f", info.m_fBuyVolume[1]/100 );
  1369. pDC->TextOut( x2, y+120, strTemp );
  1370. pDC->SetTextColor( RT_DETERMINE_COLOR(info.m_fBuyPrice[2],info.m_fLast) );
  1371. strTemp.Format( strPriceFmt, info.m_fBuyPrice[2] );
  1372. pDC->TextOut( x, y+136, strTemp );
  1373. strTemp.Format( "%.0f", info.m_fBuyVolume[2]/100 );
  1374. pDC->TextOut( x2, y+136, strTemp );
  1375. pDC->SetTextColor( RT_DETERMINE_COLOR(info.m_fBuyPrice[3],info.m_fLast) );
  1376. strTemp.Format( strPriceFmt, info.m_fBuyPrice[3] );
  1377. pDC->TextOut( x, y+152, strTemp );
  1378. strTemp.Format( "%.0f", info.m_fBuyVolume[3]/100 );
  1379. pDC->TextOut( x2, y+152, strTemp );
  1380. pDC->SetTextColor( RT_DETERMINE_COLOR(info.m_fBuyPrice[4],info.m_fLast) );
  1381. strTemp.Format( strPriceFmt, info.m_fBuyPrice[4] );
  1382. pDC->TextOut( x, y+168, strTemp );
  1383. strTemp.Format( "%.0f", info.m_fBuyVolume[4]/100 );
  1384. pDC->TextOut( x2, y+168, strTemp );
  1385. }
  1386. // 其他信息报告
  1387. // 成交
  1388. pDC->SetTextColor( RT_DETERMINE_COLOR(info.m_fClose,info.m_fLast) );
  1389. strTemp.Format( strPriceFmt, info.m_fClose );
  1390. pDC->TextOut( x, y+187, strTemp );
  1391. // 均价
  1392. pDC->SetTextColor( clrPlane );
  1393. strTemp = "-";
  1394. if( info.m_fVolume > 0 )
  1395. {
  1396. double dAve = info.m_fAmount/info.m_fVolume;
  1397. pDC->SetTextColor( RT_DETERMINE_COLOR(dAve,info.m_fLast) );
  1398. strTemp.Format( strPriceFmt, dAve );
  1399. }
  1400. pDC->TextOut( x2, y+187, strTemp );
  1401. // 涨跌
  1402. pDC->SetTextColor( RT_DETERMINE_COLOR(info.m_fClose,info.m_fLast) );
  1403. strTemp.Format( strPriceFmt, info.m_fClose-info.m_fLast );
  1404. pDC->TextOut( x, y+203, strTemp );
  1405. // 开盘
  1406. pDC->SetTextColor( RT_DETERMINE_COLOR(info.m_fOpen,info.m_fLast) );
  1407. strTemp.Format( strPriceFmt, info.m_fOpen );
  1408. pDC->TextOut( x2, y+203, strTemp );
  1409. // 幅度
  1410. pDC->SetTextColor( RT_DETERMINE_COLOR(info.m_fClose,info.m_fLast) );
  1411. strTemp = "-";
  1412. if( info.m_fLast > 1e-4 )
  1413. strTemp.Format( "%.2f%%", 100*(info.m_fClose-info.m_fLast)/info.m_fLast );
  1414. pDC->TextOut( x, y+219, strTemp );
  1415. // 最高
  1416. pDC->SetTextColor( RT_DETERMINE_COLOR(info.m_fHigh,info.m_fLast) );
  1417. strTemp.Format( strPriceFmt, info.m_fHigh );
  1418. pDC->TextOut( x2, y+219, strTemp );
  1419. // 总手
  1420. pDC->SetTextColor( clrPlane );
  1421. strTemp.Format( "%.0f", info.m_fVolume/100. );
  1422. pDC->TextOut( x, y+235, strTemp );
  1423. // 最低
  1424. pDC->SetTextColor( RT_DETERMINE_COLOR(info.m_fLow,info.m_fLast) );
  1425. strTemp.Format( strPriceFmt, info.m_fLow );
  1426. pDC->TextOut( x2, y+235, strTemp );
  1427. // 现手
  1428. pDC->SetTextColor( clrPlane );
  1429. strTemp = "-";
  1430. double dVolNow = 0, dVolOuter = 0, dVolInner = 0;
  1431. BOOL bStatSuc = m_CurStock.GetMinute().StatVolumeInfo( &dVolNow, &dVolOuter, &dVolInner );
  1432. if( bStatSuc )
  1433. strTemp.Format( "%.0f", dVolNow/100. );
  1434. pDC->TextOut( x, y+251, strTemp );
  1435. // 量比
  1436. pDC->SetTextColor( clrPlane );
  1437. double dVolRatio = 0;
  1438. strTemp = "-";
  1439. if( info.GetRatioVolume( &dVolRatio, info.m_datetech, AfxGetProfile().GetRatioVolumeDays() ) )
  1440. {
  1441. CSPTime tTrade;
  1442. if( tTrade.FromStockTimeDay( info.m_datetech ) )
  1443. dVolRatio = dVolRatio / CSPTime::GetTimeTradeRatioOfOneDay( tTrade, CSPTime::GetCurrentTime() );
  1444. strTemp.Format( "%.2f", dVolRatio );
  1445. }
  1446. pDC->TextOut( x2, y+251, strTemp );
  1447. // 外盘
  1448. pDC->SetTextColor( clrRise );
  1449. strTemp = "-";
  1450. if( bStatSuc )
  1451. strTemp.Format( "%.0f", dVolOuter/100 );
  1452. pDC->TextOut( x, y+270, strTemp );
  1453. // 内盘
  1454. pDC->SetTextColor( clrFall );
  1455. strTemp = "-";
  1456. if( bStatSuc )
  1457. strTemp.Format( "%.0f", dVolInner/100 );
  1458. pDC->TextOut( x2, y+270, strTemp );
  1459. // 涨家数,跌家数
  1460. int nRetValue = 287;
  1461. if( info.IsIndex() )
  1462. {
  1463. pDC->SetTextColor( clrRise );
  1464. strTemp = "-";
  1465. if( info.m_dwAdvance > 0 )
  1466. strTemp.Format( "%uf", info.m_dwAdvance );
  1467. pDC->TextOut( x, y+289, strTemp );
  1468. pDC->SetTextColor( clrFall );
  1469. strTemp = "-";
  1470. if( info.m_dwDecline > 0 )
  1471. strTemp.Format( "%uf", info.m_dwDecline );
  1472. pDC->TextOut( x2, y+289, strTemp );
  1473. nRetValue = 306;
  1474. }
  1475. pDC->SetTextAlign( nOldAlign );
  1476. pDC->SelectObject( pOldFont );
  1477. return nRetValue;
  1478. }
  1479. int CRealTime::DrawBuySellEx( CDC * pDC, int xStart, int yStart, int nWidth )
  1480. {
  1481. DECLARE_COLOR_DEFINATION
  1482. CStockInfo & info = m_CurStock.GetStockInfo();
  1483. CString strTemp, strTempFmt;
  1484. // Draw Name And Code
  1485. CFont * pOldFont = AfxSelectDCFont( pDC, 18 );
  1486. pDC->SetTextColor( clrTitle );
  1487. pDC->TextOut( xStart+1, m_rectAll.top+3, info.GetStockName() );
  1488. pDC->SetTextColor( clrText );
  1489. pDC->TextOut( xStart+96, m_rectAll.top+3, info.GetStockCode() );
  1490. // Select Report Font
  1491. AfxSelectDCFont( pDC, 14 );
  1492. // Draw Report Names
  1493. int x = xStart+2;
  1494. int x2 = xStart+2+nWidth/2;
  1495. int y = yStart;
  1496. pDC->SetTextColor( clrText );
  1497. // 委比和委差
  1498. strTemp.LoadString( IDS_REALTIME_BSRATIO ); // "委比";
  1499. pDC->TextOut( x, y+2,   strTemp );
  1500. strTemp.LoadString( IDS_REALTIME_BSDIFF ); // "委差";
  1501. pDC->TextOut( x2, y+2,   strTemp );
  1502. // 委卖数
  1503. DrawLine( pDC, 1, clrBorder, xStart, y+19, xStart+nWidth, y+19 );
  1504. pDC->SetTextColor( clrNewKLine );
  1505. strTemp.LoadString( IDS_REALTIME_SELL8 ); // "卖⑧";
  1506. pDC->TextOut( x, y+21, strTemp );
  1507. strTemp.LoadString( IDS_REALTIME_SELL7 ); // "卖⑦";
  1508. pDC->TextOut( x, y+37, strTemp );
  1509. strTemp.LoadString( IDS_REALTIME_SELL6 ); // "卖⑥";
  1510. pDC->TextOut( x, y+53, strTemp );
  1511. pDC->SetTextColor( clrText );
  1512. strTemp.LoadString( IDS_REALTIME_SELL5 ); // "卖⑤";
  1513. pDC->TextOut( x, y+69, strTemp );
  1514. strTemp.LoadString( IDS_REALTIME_SELL4 ); // "卖④";
  1515. pDC->TextOut( x, y+85, strTemp );
  1516. strTemp.LoadString( IDS_REALTIME_SELL3 ); // "卖③";
  1517. pDC->TextOut( x, y+101, strTemp );
  1518. strTemp.LoadString( IDS_REALTIME_SELL2 ); // "卖②";
  1519. pDC->TextOut( x, y+117, strTemp );
  1520. strTemp.LoadString( IDS_REALTIME_SELL1 ); // "卖①";
  1521. pDC->TextOut( x, y+133, strTemp );
  1522. // 委买数
  1523. DrawLine( pDC, 1, clrBorder, xStart, y+150, xStart+nWidth, y+150 );
  1524. strTemp.LoadString( IDS_REALTIME_BUY1 ); // "买①";
  1525. pDC->TextOut( x, y+152, strTemp );
  1526. strTemp.LoadString( IDS_REALTIME_BUY2 ); // "买②";
  1527. pDC->TextOut( x, y+168, strTemp );
  1528. strTemp.LoadString( IDS_REALTIME_BUY3 ); // "买③";
  1529. pDC->TextOut( x, y+184, strTemp );
  1530. strTemp.LoadString( IDS_REALTIME_BUY4 ); // "买④";
  1531. pDC->TextOut( x, y+200, strTemp );
  1532. strTemp.LoadString( IDS_REALTIME_BUY5 ); // "买⑤";
  1533. pDC->TextOut( x, y+216, strTemp );
  1534. pDC->SetTextColor( clrNewKLine );
  1535. strTemp.LoadString( IDS_REALTIME_BUY6 ); // "买⑥";
  1536. pDC->TextOut( x, y+232, strTemp );
  1537. strTemp.LoadString( IDS_REALTIME_BUY7 ); // "买⑦";
  1538. pDC->TextOut( x, y+248, strTemp );
  1539. strTemp.LoadString( IDS_REALTIME_BUY8 ); // "买⑧";
  1540. pDC->TextOut( x, y+264, strTemp );
  1541. pDC->SetTextColor( clrText );
  1542. // 其他信息报告
  1543. DrawLine( pDC, 1, clrBorder, xStart, y+281, xStart+nWidth, y+281 );
  1544. strTemp.LoadString( IDS_REALTIME_PRICENOW ); // "成交";
  1545. pDC->TextOut( x, y+283, strTemp );
  1546. strTemp.LoadString( IDS_REALTIME_PRICEAVE ); // "均价";
  1547. pDC->TextOut( x2, y+283, strTemp );
  1548. strTemp.LoadString( IDS_REALTIME_PRICEDIFF ); // "涨跌";
  1549. pDC->TextOut( x, y+299, strTemp );
  1550. strTemp.LoadString( IDS_REALTIME_PRICEOPEN ); // "开盘";
  1551. pDC->TextOut( x2, y+299, strTemp );
  1552. strTemp.LoadString( IDS_REALTIME_PRICEDIFFPERCENT ); // "幅度";
  1553. pDC->TextOut( x, y+315, strTemp );
  1554. strTemp.LoadString( IDS_REALTIME_PRICEHIGH ); // "最高";
  1555. pDC->TextOut( x2, y+315, strTemp );
  1556. strTemp.LoadString( IDS_REALTIME_VOLSUM ); // "总手";
  1557. pDC->TextOut( x, y+331, strTemp );
  1558. strTemp.LoadString( IDS_REALTIME_PRICELOW ); // "最低";
  1559. pDC->TextOut( x2, y+331, strTemp );
  1560. strTemp.LoadString( IDS_REALTIME_VOLNOW ); // "现手";
  1561. pDC->TextOut( x, y+347, strTemp );
  1562. strTemp.LoadString( IDS_REALTIME_VOLRATION ); // "量比";
  1563. pDC->TextOut( x2, y+347, strTemp );
  1564. // 内外盘
  1565. DrawLine( pDC, 1, clrBorder, xStart, y+364, xStart+nWidth, y+364 );
  1566. strTemp.LoadString( IDS_REALTIME_VOLOUTER ); // "外盘";
  1567. pDC->TextOut( x, y+366, strTemp );
  1568. strTemp.LoadString( IDS_REALTIME_VOLINNER ); // "内盘";
  1569. pDC->TextOut( x2, y+366, strTemp );
  1570. DrawLine( pDC, 1, clrBorder, xStart, y+383, xStart+nWidth, y+383 );
  1571. // 涨家数,跌家数
  1572. if( info.IsIndex() )
  1573. {
  1574. strTemp.LoadString( IDS_REALTIME_ADVANCE ); // "涨家数";
  1575. pDC->TextOut( x, y+385, strTemp );
  1576. strTemp.LoadString( IDS_REALTIME_DECLINE ); // "跌家数";
  1577. pDC->TextOut( x2, y+385, strTemp );
  1578. DrawLine( pDC, 1, clrBorder, xStart, y+402, xStart+nWidth, y+402 );
  1579. }
  1580. // Draw Report Values
  1581. x = xStart-1+nWidth/2;
  1582. x2 = xStart+nWidth-1;
  1583. UINT nOldAlign = pDC->SetTextAlign( TA_RIGHT | TA_TOP );
  1584. pDC->SetTextColor( clrPlane );
  1585. // 委比和委差
  1586. double dRatio = 0, dDiff = 0;
  1587. if( info.IsIndex() || info.GetSellBuyRatio( &dRatio, &dDiff ) )
  1588. {
  1589. strTemp.Format( "%.2f%%", dRatio );
  1590. pDC->TextOut( x, y+2,   strTemp );
  1591. strTemp.Format( "%.0f", dDiff*0.01 );
  1592. pDC->TextOut( x2, y+2,   strTemp );
  1593. }
  1594. // 价格小数位数格式串
  1595. CString strPriceFmt;
  1596. strPriceFmt.Format( "%%.%df", info.DigitBit() );
  1597. // 委卖数
  1598. float fSellPrice[8], fSellVolume[8], fBuyPrice[8], fBuyVolume[8];
  1599. m_CurStock.GetReport().StatBuySellEx( fSellPrice, fSellVolume, fBuyPrice, fBuyVolume, 8 );
  1600. if( info.IsIndex() )
  1601. {
  1602. memset( fSellPrice, 0, sizeof(fSellPrice) );
  1603. memset( fSellVolume, 0, sizeof(fSellVolume) );
  1604. memset( fBuyPrice, 0, sizeof(fBuyPrice) );
  1605. memset( fBuyVolume, 0, sizeof(fBuyVolume) );
  1606. }
  1607. pDC->SetTextColor( RT_DETERMINE_COLOR(fSellPrice[7],info.m_fLast) );
  1608. strTemp.Format( strPriceFmt, fSellPrice[7] );
  1609. pDC->TextOut( x, y+21, strTemp );
  1610. strTemp.Format( "%.0f", fSellVolume[7]/100 );
  1611. pDC->TextOut( x2, y+21, strTemp );
  1612. pDC->SetTextColor( RT_DETERMINE_COLOR(fSellPrice[6],info.m_fLast) );
  1613. strTemp.Format( strPriceFmt, fSellPrice[6] );
  1614. pDC->TextOut( x, y+37, strTemp );
  1615. strTemp.Format( "%.0f", fSellVolume[6]/100 );
  1616. pDC->TextOut( x2, y+37, strTemp );
  1617. pDC->SetTextColor( RT_DETERMINE_COLOR(fSellPrice[5],info.m_fLast) );
  1618. strTemp.Format( strPriceFmt, fSellPrice[5] );
  1619. pDC->TextOut( x, y+53, strTemp );
  1620. strTemp.Format( "%.0f", fSellVolume[5]/100 );
  1621. pDC->TextOut( x2, y+53, strTemp );
  1622. pDC->SetTextColor( RT_DETERMINE_COLOR(fSellPrice[4],info.m_fLast) );
  1623. strTemp.Format( strPriceFmt, fSellPrice[4] );
  1624. pDC->TextOut( x, y+69, strTemp );
  1625. strTemp.Format( "%.0f", fSellVolume[4]/100 );
  1626. pDC->TextOut( x2, y+69, strTemp );
  1627. pDC->SetTextColor( RT_DETERMINE_COLOR(fSellPrice[3],info.m_fLast) );
  1628. strTemp.Format( strPriceFmt, fSellPrice[3] );
  1629. pDC->TextOut( x, y+85, strTemp );
  1630. strTemp.Format( "%.0f", fSellVolume[3]/100 );
  1631. pDC->TextOut( x2, y+85, strTemp );
  1632. pDC->SetTextColor( RT_DETERMINE_COLOR(fSellPrice[2],info.m_fLast) );
  1633. strTemp.Format( strPriceFmt, fSellPrice[2] );
  1634. pDC->TextOut( x, y+101, strTemp );
  1635. strTemp.Format( "%.0f", fSellVolume[2]/100 );
  1636. pDC->TextOut( x2, y+101, strTemp );
  1637. pDC->SetTextColor( RT_DETERMINE_COLOR(fSellPrice[1],info.m_fLast) );
  1638. strTemp.Format( strPriceFmt, fSellPrice[1] );
  1639. pDC->TextOut( x, y+117, strTemp );
  1640. strTemp.Format( "%.0f", fSellVolume[1]/100 );
  1641. pDC->TextOut( x2, y+117, strTemp );
  1642. pDC->SetTextColor( RT_DETERMINE_COLOR(fSellPrice[0],info.m_fLast) );
  1643. strTemp.Format( strPriceFmt, fSellPrice[0] );
  1644. pDC->TextOut( x, y+133, strTemp );
  1645. strTemp.Format( "%.0f", fSellVolume[0]/100 );
  1646. pDC->TextOut( x2, y+133, strTemp );
  1647. // 委买数
  1648. pDC->SetTextColor( RT_DETERMINE_COLOR(fBuyPrice[0],info.m_fLast) );
  1649. strTemp.Format( strPriceFmt, fBuyPrice[0] );
  1650. pDC->TextOut( x, y+152, strTemp );
  1651. strTemp.Format( "%.0f", fBuyVolume[0]/100 );
  1652. pDC->TextOut( x2, y+152, strTemp );
  1653. pDC->SetTextColor( RT_DETERMINE_COLOR(fBuyPrice[1],info.m_fLast) );
  1654. strTemp.Format( strPriceFmt, fBuyPrice[1] );
  1655. pDC->TextOut( x, y+168, strTemp );
  1656. strTemp.Format( "%.0f", fBuyVolume[1]/100 );
  1657. pDC->TextOut( x2, y+168, strTemp );
  1658. pDC->SetTextColor( RT_DETERMINE_COLOR(fBuyPrice[2],info.m_fLast) );
  1659. strTemp.Format( strPriceFmt, fBuyPrice[2] );
  1660. pDC->TextOut( x, y+184, strTemp );
  1661. strTemp.Format( "%.0f", fBuyVolume[2]/100 );
  1662. pDC->TextOut( x2, y+184, strTemp );
  1663. pDC->SetTextColor( RT_DETERMINE_COLOR(fBuyPrice[3],info.m_fLast) );
  1664. strTemp.Format( strPriceFmt, fBuyPrice[3] );
  1665. pDC->TextOut( x, y+200, strTemp );
  1666. strTemp.Format( "%.0f", fBuyVolume[3]/100 );
  1667. pDC->TextOut( x2, y+200, strTemp );
  1668. pDC->SetTextColor( RT_DETERMINE_COLOR(fBuyPrice[4],info.m_fLast) );
  1669. strTemp.Format( strPriceFmt, fBuyPrice[4] );
  1670. pDC->TextOut( x, y+216, strTemp );
  1671. strTemp.Format( "%.0f", fBuyVolume[4]/100 );
  1672. pDC->TextOut( x2, y+216, strTemp );
  1673. pDC->SetTextColor( RT_DETERMINE_COLOR(fBuyPrice[5],info.m_fLast) );
  1674. strTemp.Format( strPriceFmt, fBuyPrice[5] );
  1675. pDC->TextOut( x, y+232, strTemp );
  1676. strTemp.Format( "%.0f", fBuyVolume[5]/100 );
  1677. pDC->TextOut( x2, y+232, strTemp );
  1678. pDC->SetTextColor( RT_DETERMINE_COLOR(fBuyPrice[6],info.m_fLast) );
  1679. strTemp.Format( strPriceFmt, fBuyPrice[6] );
  1680. pDC->TextOut( x, y+248, strTemp );
  1681. strTemp.Format( "%.0f", fBuyVolume[6]/100 );
  1682. pDC->TextOut( x2, y+248, strTemp );
  1683. pDC->SetTextColor( RT_DETERMINE_COLOR(fBuyPrice[7],info.m_fLast) );
  1684. strTemp.Format( strPriceFmt, fBuyPrice[7] );
  1685. pDC->TextOut( x, y+264, strTemp );
  1686. strTemp.Format( "%.0f", fBuyVolume[7]/100 );
  1687. pDC->TextOut( x2, y+264, strTemp );
  1688. // 其他信息报告
  1689. // 成交
  1690. pDC->SetTextColor( RT_DETERMINE_COLOR(info.m_fClose,info.m_fLast) );
  1691. strTemp.Format( strPriceFmt, info.m_fClose );
  1692. pDC->TextOut( x, y+283, strTemp );
  1693. // 均价
  1694. pDC->SetTextColor( clrPlane );
  1695. strTemp = "-";
  1696. if( info.m_fVolume > 0 )
  1697. {
  1698. double dAve = info.m_fAmount/info.m_fVolume;
  1699. pDC->SetTextColor( RT_DETERMINE_COLOR(dAve,info.m_fLast) );
  1700. strTemp.Format( strPriceFmt, dAve );
  1701. }
  1702. pDC->TextOut( x2, y+283, strTemp );
  1703. // 涨跌
  1704. pDC->SetTextColor( RT_DETERMINE_COLOR(info.m_fClose,info.m_fLast) );
  1705. strTemp.Format( strPriceFmt, info.m_fClose-info.m_fLast );
  1706. pDC->TextOut( x, y+299, strTemp );
  1707. // 开盘
  1708. pDC->SetTextColor( RT_DETERMINE_COLOR(info.m_fOpen,info.m_fLast) );
  1709. strTemp.Format( strPriceFmt, info.m_fOpen );
  1710. pDC->TextOut( x2, y+299, strTemp );
  1711. // 幅度
  1712. pDC->SetTextColor( RT_DETERMINE_COLOR(info.m_fClose,info.m_fLast) );
  1713. strTemp = "-";
  1714. if( info.m_fLast > 1e-4 )
  1715. strTemp.Format( "%.2f%%", 100*(info.m_fClose-info.m_fLast)/info.m_fLast );
  1716. pDC->TextOut( x, y+315, strTemp );
  1717. // 最高
  1718. pDC->SetTextColor( RT_DETERMINE_COLOR(info.m_fHigh,info.m_fLast) );
  1719. strTemp.Format( strPriceFmt, info.m_fHigh );
  1720. pDC->TextOut( x2, y+315, strTemp );
  1721. // 总手
  1722. pDC->SetTextColor( clrPlane );
  1723. strTemp.Format( "%.0f", info.m_fVolume/100. );
  1724. pDC->TextOut( x, y+331, strTemp );
  1725. // 最低
  1726. pDC->SetTextColor( RT_DETERMINE_COLOR(info.m_fLow,info.m_fLast) );
  1727. strTemp.Format( strPriceFmt, info.m_fLow );
  1728. pDC->TextOut( x2, y+331, strTemp );
  1729. // 现手
  1730. pDC->SetTextColor( clrPlane );
  1731. strTemp = "-";
  1732. double dVolNow = 0, dVolOuter = 0, dVolInner = 0;
  1733. BOOL bStatSuc = m_CurStock.GetMinute().StatVolumeInfo( &dVolNow, &dVolOuter, &dVolInner );
  1734. if( bStatSuc )
  1735. strTemp.Format( "%.0f", dVolNow/100. );
  1736. pDC->TextOut( x, y+347, strTemp );
  1737. // 量比
  1738. pDC->SetTextColor( clrPlane );
  1739. double dVolRatio = 0;
  1740. strTemp = "-";
  1741. if( info.GetRatioVolume( &dVolRatio, info.m_datetech, AfxGetProfile().GetRatioVolumeDays() ) )
  1742. {
  1743. CSPTime tTrade;
  1744. if( tTrade.FromStockTimeDay( info.m_datetech ) )
  1745. dVolRatio = dVolRatio / CSPTime::GetTimeTradeRatioOfOneDay( tTrade, CSPTime::GetCurrentTime() );
  1746. strTemp.Format( "%.2f", dVolRatio );
  1747. }
  1748. pDC->TextOut( x2, y+347, strTemp );
  1749. // 外盘
  1750. pDC->SetTextColor( clrRise );
  1751. strTemp = "-";
  1752. if( bStatSuc )
  1753. strTemp.Format( "%.0f", dVolOuter/100 );
  1754. pDC->TextOut( x, y+366, strTemp );
  1755. // 内盘
  1756. pDC->SetTextColor( clrFall );
  1757. strTemp = "-";
  1758. if( bStatSuc )
  1759. strTemp.Format( "%.0f", dVolInner/100 );
  1760. pDC->TextOut( x2, y+366, strTemp );
  1761. // 涨家数,跌家数
  1762. int nRetValue = 383;
  1763. if( info.IsIndex() )
  1764. {
  1765. pDC->SetTextColor( clrRise );
  1766. strTemp = "-";
  1767. if( info.m_dwAdvance > 0 )
  1768. strTemp.Format( "%uf", info.m_dwAdvance );
  1769. pDC->TextOut( x, y+385, strTemp );
  1770. pDC->SetTextColor( clrFall );
  1771. strTemp = "-";
  1772. if( info.m_dwDecline > 0 )
  1773. strTemp.Format( "%uf", info.m_dwDecline );
  1774. pDC->TextOut( x2, y+385, strTemp );
  1775. nRetValue = 402;
  1776. }
  1777. pDC->SetTextAlign( nOldAlign );
  1778. pDC->SelectObject( pOldFont );
  1779. return nRetValue;
  1780. }
  1781. void CRealTime::DrawReportQuote( CDC * pDC )
  1782. {
  1783. DECLARE_COLOR_DEFINATION
  1784. if( m_rectReport.IsRectEmpty() )
  1785. return;
  1786. // Draw Rect
  1787. pDC->FillSolidRect( &m_rectReport, clrBK );
  1788. pDC->Draw3dRect( &m_rectReport, clrBorder, clrBorder );
  1789. pDC->SetBkColor( clrBK );
  1790. int nBuySellHeight = DrawBuySell( pDC, m_rectReport.left, m_rectReport.top, m_rectReport.Width() );
  1791. CStockInfo & info = m_CurStock.GetStockInfo();
  1792. CReport & aReport = m_CurStock.GetReport();
  1793. CRect rect = m_rectReport;
  1794. rect.top = m_rectReport.top + nBuySellHeight + 1;
  1795. m_nCurrentPageCount = (rect.Height()-RT_RDTITLE_HEIGHT) / RT_RDELEMENT_HEIGHT;
  1796. if( m_nCurrentPageCount <= 0 ) m_nCurrentPageCount = 1;
  1797. m_nCurrentStartPos = CheckValidStartPos( m_nCurrentStartPos, aReport.GetSize(), m_nCurrentPageCount, FALSE );
  1798. DrawReportColumn( pDC, info, aReport, m_nCurrentStartPos, m_nCurrentPageCount, rect );
  1799. }
  1800. void CRealTime::DrawReportPrice( CDC * pDC )
  1801. {
  1802. DECLARE_COLOR_DEFINATION
  1803. if( m_rectReport.IsRectEmpty() )
  1804. return;
  1805. // Draw Rect
  1806. pDC->FillSolidRect( &m_rectReport, clrBK );
  1807. pDC->Draw3dRect( &m_rectReport, clrBorder, clrBorder );
  1808. pDC->SetBkColor( clrBK );
  1809. int nBuySellHeight = DrawBuySell( pDC, m_rectReport.left, m_rectReport.top, m_rectReport.Width() );
  1810. UINT nOldAlign = pDC->SetTextAlign( TA_LEFT | TA_TOP );
  1811. CFont * pOldFont = AfxSelectDCFont( pDC, 14 );
  1812. CStockInfo & info = m_CurStock.GetStockInfo();
  1813. CMinute & aMinute = m_CurStock.GetMinute();
  1814. // 成交价量
  1815. int y = m_rectReport.top + nBuySellHeight + 2;
  1816. int x = m_rectReport.left+2;
  1817. int x2 = (int)(x+0.55*m_rectReport.Width());
  1818. int x3 = m_rectReport.right-1;
  1819. int nMaxDrawCount = (m_rectReport.bottom-y-1)/16;
  1820. CSPDWordArray adwPrice, adwVolume;
  1821. double dMaxVolume = 5;
  1822. // 价格小数位数格式串
  1823. CString strPriceFmt;
  1824. strPriceFmt.Format( "%%.%df", info.DigitBit() );
  1825. DrawLine( pDC, 1, clrBorder, m_rectReport.left, m_rectReport.top+nBuySellHeight+1, m_rectReport.right, m_rectReport.top+nBuySellHeight+1 );
  1826. if( aMinute.GetSize() > 0 && nMaxDrawCount > 0
  1827. && aMinute.StatDealInfo( adwPrice, adwVolume, &dMaxVolume ) 
  1828. && dMaxVolume >= 1 )
  1829. {
  1830. int nStartPos = 0;
  1831. if( adwPrice.GetSize() > nMaxDrawCount )
  1832. nStartPos = adwPrice.GetSize()-nMaxDrawCount;
  1833. for( int i=nStartPos; i<adwPrice.GetSize(); i++ )
  1834. {
  1835. // Price
  1836. double dPrice = double(adwPrice[i]) * 0.001;
  1837. CString strPrice;
  1838. strPrice.Format( strPriceFmt, dPrice );
  1839. pDC->SetTextColor( RT_DETERMINE_COLOR(dPrice,info.m_fLast) );
  1840. pDC->SetTextAlign( TA_LEFT | TA_TOP );
  1841. pDC->TextOut( x, y+16*(i-nStartPos), strPrice );
  1842. // Volume
  1843. CString strVolume;
  1844. strVolume.Format( "%.0f", double(adwVolume[i]) * 0.01 );
  1845. pDC->SetTextColor( clrText );
  1846. pDC->SetTextAlign( TA_RIGHT | TA_TOP );
  1847. pDC->TextOut( x2, y+16*(i-nStartPos), strVolume );
  1848. // Volume Rect
  1849. CRect rect( x2+2, y+16*(i-nStartPos)+2, x3-3, y+16*(i-nStartPos+1)-2 );
  1850. rect.right = rect.left + rect.Width() * (double)adwVolume[i] / dMaxVolume;
  1851. pDC->FillSolidRect( &rect, clrRise );
  1852. pDC->SetBkColor( clrBK );
  1853. }
  1854. }
  1855. pDC->SetTextAlign( nOldAlign );
  1856. pDC->SelectObject( pOldFont );
  1857. }
  1858. void CRealTime::DrawReportMinute( CDC * pDC )
  1859. {
  1860. DECLARE_COLOR_DEFINATION
  1861. if( m_rectReport.IsRectEmpty() )
  1862. return;
  1863. // Draw Rect
  1864. pDC->FillSolidRect( &m_rectReport, clrBK );
  1865. pDC->Draw3dRect( &m_rectReport, clrBorder, clrBorder );
  1866. pDC->SetBkColor( clrBK );
  1867. int nBuySellHeight = DrawBuySell( pDC, m_rectReport.left, m_rectReport.top, m_rectReport.Width() );
  1868. CStockInfo & info = m_CurStock.GetStockInfo();
  1869. CMinute & aMinute = m_CurStock.GetMinute();
  1870. CRect rect = m_rectReport;
  1871. rect.top = m_rectReport.top + nBuySellHeight + 1;
  1872. m_nCurrentPageCount = (rect.Height()-RT_RDTITLE_HEIGHT) / RT_RDELEMENT_HEIGHT;
  1873. if( m_nCurrentPageCount <= 0 ) m_nCurrentPageCount = 1;
  1874. m_nCurrentStartPos = CheckValidStartPos( m_nCurrentStartPos, aMinute.GetSize(), m_nCurrentPageCount, FALSE );
  1875. DrawMinuteColumn( pDC, info, aMinute, m_nCurrentStartPos, m_nCurrentPageCount, rect );
  1876. }
  1877. void CRealTime::DrawReportBuySellEx( CDC * pDC )
  1878. {
  1879. DECLARE_COLOR_DEFINATION
  1880. if( m_rectReport.IsRectEmpty() )
  1881. return;
  1882. // Draw Rect
  1883. pDC->FillSolidRect( &m_rectReport, clrBK );
  1884. pDC->Draw3dRect( &m_rectReport, clrBorder, clrBorder );
  1885. pDC->SetBkColor( clrBK );
  1886. int nBuySellHeight = DrawBuySellEx( pDC, m_rectReport.left, m_rectReport.top, m_rectReport.Width() );
  1887. CStockInfo & info = m_CurStock.GetStockInfo();
  1888. CReport & aReport = m_CurStock.GetReport();
  1889. CRect rect = m_rectReport;
  1890. rect.top = m_rectReport.top + nBuySellHeight + 1;
  1891. m_nCurrentPageCount = (rect.Height()-RT_RDTITLE_HEIGHT) / RT_RDELEMENT_HEIGHT;
  1892. if( m_nCurrentPageCount <= 0 ) m_nCurrentPageCount = 1;
  1893. m_nCurrentStartPos = CheckValidStartPos( m_nCurrentStartPos, aReport.GetSize(), m_nCurrentPageCount, FALSE );
  1894. DrawReportColumn( pDC, info, aReport, m_nCurrentStartPos, m_nCurrentPageCount, rect );
  1895. }
  1896. void CRealTime::DrawReportValue( CDC * pDC )
  1897. {
  1898. DECLARE_COLOR_DEFINATION
  1899. if( m_rectReport.IsRectEmpty() )
  1900. return;
  1901. // Draw Rect
  1902. pDC->FillSolidRect( &m_rectReport, clrBK );
  1903. pDC->Draw3dRect( &m_rectReport, clrBorder, clrBorder );
  1904. pDC->SetBkColor( clrBK );
  1905. int nBuySellHeight = DrawBuySell( pDC, m_rectReport.left, m_rectReport.top, m_rectReport.Width() );
  1906. CFont * pOldFont = AfxSelectDCFont( pDC, 14 );
  1907. CStockInfo & info = m_CurStock.GetStockInfo();
  1908. CString strTemp;
  1909. int y = m_rectReport.top + nBuySellHeight + 2;
  1910. int x = m_rectReport.left+2;
  1911. int x2 = (int)(x+0.9*m_rectReport.Width());
  1912. pDC->SetTextColor( clrText );
  1913. DrawLine( pDC, 1, clrBorder, m_rectReport.left, m_rectReport.top+nBuySellHeight+1, m_rectReport.right, m_rectReport.top+nBuySellHeight+1 );
  1914. // Draw Names
  1915. // 涨停价、跌停价
  1916. strTemp.LoadString( IDS_REALTIME_RISINGLIMIT ); // 涨停价
  1917. pDC->TextOut( x, y+2,   strTemp );
  1918. strTemp.LoadString( IDS_REALTIME_FALLINGLIMIT ); // 跌停价
  1919. pDC->TextOut( x, y+18,   strTemp );
  1920. // 逆势操作系统
  1921. DrawLine( pDC, 1, clrBorder, m_rectReport.left, y+35, m_rectReport.right, y+35 );
  1922. strTemp.LoadString( IDS_REALTIME_AH ); // AH
  1923. pDC->TextOut( x, y+37, strTemp );
  1924. strTemp.LoadString( IDS_REALTIME_NH ); // NH
  1925. pDC->TextOut( x, y+53, strTemp );
  1926. strTemp.LoadString( IDS_REALTIME_NL ); // NL
  1927. pDC->TextOut( x, y+69, strTemp );
  1928. strTemp.LoadString( IDS_REALTIME_AL ); // AL
  1929. pDC->TextOut( x, y+85, strTemp );
  1930. // Draw Values
  1931. UINT nOldAlign = pDC->SetTextAlign( TA_RIGHT | TA_TOP );
  1932. pDC->SetTextColor( clrPlane );
  1933. // 价格小数位数格式串
  1934. CString strPriceFmt;
  1935. strPriceFmt.Format( "%%.%df", info.DigitBit() );
  1936. // 涨停价、跌停价
  1937. pDC->SetTextColor( clrRise );
  1938. strTemp.Format( strPriceFmt, info.m_fLast*1.10 );
  1939. pDC->TextOut( x2, y+2, strTemp );
  1940. pDC->SetTextColor( clrFall );
  1941. strTemp.Format( strPriceFmt, info.m_fLast*0.90 );
  1942. pDC->TextOut( x2, y+18, strTemp );
  1943. pDC->SetTextColor( RT_DETERMINE_COLOR(info.m_fSellPrice[2],info.m_fLast) );
  1944. // 逆势操作系统
  1945. AfxPrepareStockData( &AfxGetDB(), m_CurStock, CKData::ktypeDay, CKData::formatXDRdown, CKData::mdtypeClose, FALSE, FALSE );
  1946. CKData & kdata = m_CurStock.GetKDataDay();
  1947. if( kdata.GetSize() > 0 )
  1948. {
  1949. CCDP cdp(&kdata);
  1950. cdp.AttachParameters( AfxGetProfile().GetTechParameters().cdp );
  1951. double dAH = 0, dNH = 0, dAL = 0, dNL = 0;
  1952. if( cdp.Calculate( &dAH, &dNH, &dAL, &dNL, kdata.GetSize()-1, FALSE ) )
  1953. {
  1954. pDC->SetTextColor( RT_DETERMINE_COLOR(dAH,info.m_fLast) );
  1955. strTemp.Format( strPriceFmt, dAH );
  1956. pDC->TextOut( x2, y+37, strTemp );
  1957. pDC->SetTextColor( RT_DETERMINE_COLOR(dAH,info.m_fLast) );
  1958. strTemp.Format( strPriceFmt, dNH );
  1959. pDC->TextOut( x2, y+53, strTemp );
  1960. pDC->SetTextColor( RT_DETERMINE_COLOR(dAH,info.m_fLast) );
  1961. strTemp.Format( strPriceFmt, dNL );
  1962. pDC->TextOut( x2, y+69, strTemp );
  1963. pDC->SetTextColor( RT_DETERMINE_COLOR(dAH,info.m_fLast) );
  1964. strTemp.Format( strPriceFmt, dAL );
  1965. pDC->TextOut( x2, y+85, strTemp );
  1966. }
  1967. }
  1968. pDC->SetTextAlign( nOldAlign );
  1969. pDC->SelectObject( pOldFont );
  1970. }
  1971. void CRealTime::DrawReportDistribute( CDC * pDC )
  1972. {
  1973. DECLARE_COLOR_DEFINATION
  1974. if( m_rectReport.IsRectEmpty() )
  1975. return;
  1976. CStockInfo & info = m_CurStock.GetStockInfo();
  1977. CMinute & aMinute = m_CurStock.GetMinute();
  1978. // Draw Rect
  1979. pDC->FillSolidRect( &m_rectReport, clrBK );
  1980. pDC->Draw3dRect( &m_rectReport, clrBorder, clrBorder );
  1981. pDC->SetBkColor( clrBK );
  1982. // Draw Name And Code
  1983. CFont * pOldFont = AfxSelectDCFont( pDC, 18 );
  1984. UINT nOldAlign = pDC->SetTextAlign( TA_LEFT | TA_TOP );
  1985. pDC->SetTextColor( clrTitle );
  1986. pDC->TextOut( m_rectReport.left+1, m_rectAll.top+3, info.GetStockName() );
  1987. pDC->SetTextColor( clrText );
  1988. pDC->TextOut( m_rectReport.left+96, m_rectAll.top+3, info.GetStockCode() );
  1989. // Select Report Font
  1990. AfxSelectDCFont( pDC, 14 );
  1991. int y = m_rectPrice.top;
  1992. int x = m_rectReport.left+2;
  1993. int xMaxLen = m_rectReport.Width() - 8;
  1994. CSPDWordArray adwPrice, adwVolume;
  1995. double dMaxVolume = 5;
  1996. if( aMinute.GetSize() > 0
  1997. && aMinute.StatDealInfo( adwPrice, adwVolume, &dMaxVolume ) 
  1998. && dMaxVolume >= 1 
  1999. && m_dMaxPrice - m_dMinPrice > 1e-4 )
  2000. {
  2001. for( int i=0; i<adwPrice.GetSize(); i++ )
  2002. {
  2003. // Price, Volume
  2004. double dPrice = double(adwPrice[i]) * 0.001;
  2005. int yPos = (int)( m_rectPrice.top+m_rectPrice.Height()*(m_dMaxPrice-dPrice)/(m_dMaxPrice-m_dMinPrice) );
  2006. int xEnd = x + xMaxLen * (double)adwVolume[i] / dMaxVolume;
  2007. if( yPos > m_rectReport.top && yPos < m_rectReport.bottom
  2008. && xEnd > x && xEnd < m_rectReport.right )
  2009. {
  2010. // Volume Rect
  2011. CRect rect( x, yPos, xEnd, yPos+2 );
  2012. pDC->FillSolidRect( &rect, clrRise );
  2013. }
  2014. pDC->SetBkColor( clrBK );
  2015. }
  2016. }
  2017. pDC->SetTextAlign( nOldAlign );
  2018. pDC->SelectObject( pOldFont );
  2019. }
  2020. void CRealTime::DrawReportBigTrade( CDC * pDC )
  2021. {
  2022. DECLARE_COLOR_DEFINATION
  2023. if( m_rectReport.IsRectEmpty() )
  2024. return;
  2025. // Load Report
  2026. LoadReportBigTrade( );
  2027. CReport & aReport = m_aReportBigTrade;
  2028. CStockInfo & info = m_CurStock.GetStockInfo();
  2029. // Draw Rect
  2030. pDC->FillSolidRect( &m_rectReport, clrBK );
  2031. pDC->Draw3dRect( &m_rectReport, clrBorder, clrBorder );
  2032. pDC->SetBkColor( clrBK );
  2033. // Draw Name And Code
  2034. CFont * pOldFont = AfxSelectDCFont( pDC, 18 );
  2035. UINT nOldAlign = pDC->SetTextAlign( TA_LEFT | TA_TOP );
  2036. pDC->SetTextColor( clrTitle );
  2037. pDC->TextOut( m_rectReport.left+1, m_rectAll.top+3, info.GetStockName() );
  2038. pDC->SetTextColor( clrText );
  2039. pDC->TextOut( m_rectReport.left+96, m_rectAll.top+3, info.GetStockCode() );
  2040. pDC->SetTextAlign( nOldAlign );
  2041. pDC->SelectObject( pOldFont );
  2042. CRect rect = m_rectReport;
  2043. m_nCurrentPageCount = (rect.Height()-RT_RDTITLE_HEIGHT) / RT_RDELEMENT_HEIGHT;
  2044. if( m_nCurrentPageCount <= 0 ) m_nCurrentPageCount = 1;
  2045. m_nCurrentStartPos = CheckValidStartPos( m_nCurrentStartPos, aReport.GetSize(), m_nCurrentPageCount, FALSE );
  2046. DrawBigTradeColumn( pDC, aReport, m_nCurrentStartPos, m_nCurrentPageCount, rect );
  2047. }
  2048. BOOL CRealTime::LoadReportBigTrade( )
  2049. {
  2050. int nOldSize = m_aReportBigTrade.GetSize();
  2051. CStock stock;
  2052. stock.SetStockCode( CStock::marketSHSE, STKLIB_CODE_ZLDD );
  2053. AfxGetDB().LoadReport( &stock );
  2054. m_aReportBigTrade = stock.GetReport();
  2055. stock.SetStockCode( CStock::marketSZSE, STKLIB_CODE_ZLDD );
  2056. AfxGetDB().LoadReport( &stock );
  2057. m_aReportBigTrade.InsertAt( 0, &(stock.GetReport()) );
  2058. m_aReportBigTrade.Sort( );
  2059. if( nOldSize != m_aReportBigTrade.GetSize() )
  2060. m_nCurrentStartPos = -1;
  2061. if( m_nCurrentSelectPos < 0 || m_nCurrentSelectPos >= m_aReportBigTrade.GetSize() )
  2062. m_nCurrentSelectPos = -1;
  2063. return TRUE;
  2064. }
  2065. //////////////////////////////////////////////////////////////////////////////////////////////////////
  2066. // 以下为明细使用 modeReportDetail, modeMinuteDetail, modeBigTradeDetail
  2067. int CRealTime::GetColumnPerPage( CRect rectAll )
  2068. {
  2069. int nColumns = rectAll.Width() / RT_RDCOLUMN_WIDTH;
  2070. if( nColumns <= 0 )
  2071. nColumns = 1;
  2072. return nColumns;
  2073. }
  2074. int CRealTime::GetCountPerColumn( CRect rectAll )
  2075. {
  2076. int nCount = (rectAll.Height() - RT_RDTITLE_HEIGHT*2) / RT_RDELEMENT_HEIGHT;
  2077. if( nCount <= 0 )
  2078. nCount = 1;
  2079. return nCount;
  2080. }
  2081. int CRealTime::CheckValidStartPos( int nStartPosOld, int nTotalCount, int nPageCount, BOOL bAlignBegin )
  2082. {
  2083. int nStartPos = nStartPosOld;
  2084. if( -1 == nStartPos ) // 缺省从后开始
  2085. {
  2086. if( bAlignBegin )
  2087. {
  2088. nStartPos = 0;
  2089. while( nTotalCount - nStartPos > nPageCount ) nStartPos += nPageCount;
  2090. }
  2091. else
  2092. {
  2093. nStartPos = nTotalCount - nPageCount;
  2094. if( nStartPos < 0 )
  2095. nStartPos = 0;
  2096. }
  2097. }
  2098. if( nStartPos < 0 || nStartPos >= nTotalCount )
  2099. nStartPos = 0;
  2100. return nStartPos;
  2101. }
  2102. void CRealTime::PageUp( )
  2103. {
  2104. int nTotalSize = 0;
  2105. if( CRealTime::modeReportDetail == m_nDrawMode )
  2106. nTotalSize = m_CurStock.GetReport().GetSize();
  2107. else if( CRealTime::modeMinuteDetail == m_nDrawMode )
  2108. nTotalSize = m_CurStock.GetMinute().GetSize();
  2109. else if( CRealTime::modeBigTradeDetail == m_nDrawMode )
  2110. nTotalSize = m_aReportBigTrade.GetSize();
  2111. else
  2112. return;
  2113. int nColumnPerPage = GetColumnPerPage( m_rectAll );
  2114. int nCountPerColumn = GetCountPerColumn( m_rectAll );
  2115. int nCountPerPage = nCountPerColumn * nColumnPerPage;
  2116. if( 0 == m_nCurrentStartPos )
  2117. return;
  2118. if( -1 == m_nCurrentStartPos )
  2119. {
  2120. m_nCurrentStartPos = 0;
  2121. while( nTotalSize - m_nCurrentStartPos > nCountPerPage ) m_nCurrentStartPos += nCountPerPage;
  2122. m_nCurrentStartPos -= nCountPerPage;
  2123. }
  2124. else
  2125. m_nCurrentStartPos -= nCountPerPage;
  2126. if( m_nCurrentStartPos < 0 || m_nCurrentStartPos >= nTotalSize )
  2127. m_nCurrentStartPos = -1;
  2128. Redraw( NULL, m_rectAll );
  2129. }
  2130. void CRealTime::PageDown( )
  2131. {
  2132. int nTotalSize = 0;
  2133. if( CRealTime::modeReportDetail == m_nDrawMode )
  2134. nTotalSize = m_CurStock.GetReport().GetSize();
  2135. else if( CRealTime::modeMinuteDetail == m_nDrawMode )
  2136. nTotalSize = m_CurStock.GetMinute().GetSize();
  2137. else if( CRealTime::modeBigTradeDetail == m_nDrawMode )
  2138. nTotalSize = m_aReportBigTrade.GetSize();
  2139. else
  2140. return;
  2141. int nColumnPerPage = GetColumnPerPage( m_rectAll );
  2142. int nCountPerColumn = GetCountPerColumn( m_rectAll );
  2143. int nCountPerPage = nCountPerColumn * nColumnPerPage;
  2144. if( -1 != m_nCurrentStartPos )
  2145. {
  2146. m_nCurrentStartPos += nCountPerPage;
  2147. }
  2148. if( m_nCurrentStartPos < 0 || m_nCurrentStartPos >= nTotalSize )
  2149. m_nCurrentStartPos = -1;
  2150. Redraw( NULL, m_rectAll );
  2151. }
  2152. //////////////////////////////////////////////////////////////////////////////////////////////////////
  2153. // 以下为每笔成交明细使用 modeReportDetail
  2154. void CRealTime::DrawReportDetail( CDC * pDC )
  2155. {
  2156. DECLARE_COLOR_DEFINATION
  2157. CStockInfo & info = m_CurStock.GetStockInfo();
  2158. CReport & aReport = m_CurStock.GetReport();
  2159. // set bkcolor
  2160. pDC->SetBkColor( clrBK );
  2161. // Draw Name And Code
  2162. CFont * pOldFont = AfxSelectDCFont( pDC, 18 );
  2163. pDC->SetTextColor( clrTitle );
  2164. pDC->TextOut( m_rectAll.left+1, m_rectAll.top+3, info.GetStockName() );
  2165. pDC->TextOut( m_rectAll.left+96, m_rectAll.top+3, info.GetStockCode() );
  2166. // Draw Title
  2167. CString strTitle;
  2168. strTitle.LoadString( IDS_REALTIME_REPORTDETAILTITLE );
  2169. pDC->TextOut( m_rectAll.left+180, m_rectAll.top+3, strTitle );
  2170. // Select Report Font
  2171. AfxSelectDCFont( pDC, 14 );
  2172. // 成交明细
  2173. int nColumnPerPage = GetColumnPerPage( m_rectAll );
  2174. int nCountPerColumn = GetCountPerColumn( m_rectAll );
  2175. int nCountPerPage = nCountPerColumn * nColumnPerPage;
  2176. if( nCountPerPage <= 0 )
  2177. return;
  2178. m_nCurrentStartPos = CheckValidStartPos( m_nCurrentStartPos, aReport.GetSize(), nCountPerPage, TRUE );
  2179. int nStartPos = m_nCurrentStartPos;
  2180. for( int nColumn=0; nColumn<nColumnPerPage; nColumn ++ )
  2181. {
  2182. if( nStartPos >= aReport.GetSize() )
  2183. break;
  2184. CRect rectColumn;
  2185. rectColumn.top = m_rectAll.top + RT_RDTITLE_HEIGHT;
  2186. rectColumn.bottom = m_rectAll.bottom;
  2187. rectColumn.left = m_rectAll.left + nColumn*RT_RDCOLUMN_WIDTH;
  2188. rectColumn.right = rectColumn.left + RT_RDCOLUMN_WIDTH;
  2189. DrawReportColumn( pDC, info, aReport, nStartPos, nCountPerColumn, rectColumn );
  2190. nStartPos += nCountPerColumn;
  2191. }
  2192. pDC->SelectObject( pOldFont );
  2193. }
  2194. void CRealTime::DrawReportColumn( CDC * pDC, CStockInfo & info, CReport & aReport, int nStartPos, int nMaxCount, CRect rect )
  2195. {
  2196. DECLARE_COLOR_DEFINATION
  2197. int y = rect.top + RT_RDTITLE_HEIGHT;
  2198. int x = rect.left+2;
  2199. int x2 = (int)(x+0.55*rect.Width());
  2200. int x3 = rect.right-1;
  2201. // Draw Border
  2202. pDC->Draw3dRect( &rect, clrBorder, clrBorder );
  2203. DrawLine( pDC, 1, clrBorder, rect.left, rect.top+RT_RDTITLE_HEIGHT-2 , rect.right, rect.top+RT_RDTITLE_HEIGHT-2 );
  2204. // Set Align
  2205. pDC->SetBkColor( clrBK );
  2206. UINT nOldAlign = pDC->SetTextAlign( TA_LEFT | TA_TOP );
  2207. // Draw Title Text
  2208. CString strTemp;
  2209. CFont * pOldFont = AfxSelectDCFont( pDC, 14 );
  2210. pDC->SetTextColor( clrText );
  2211. strTemp.LoadString( IDS_REALTIME_TIME );
  2212. pDC->TextOut( x+1, rect.top+5, strTemp );
  2213. pDC->SetTextAlign( TA_RIGHT | TA_TOP );
  2214. strTemp.LoadString( IDS_REALTIME_PRICE );
  2215. pDC->TextOut( x2-1, rect.top+5, strTemp );
  2216. strTemp.LoadString( IDS_REALTIME_VOLUME );
  2217. pDC->TextOut( x3-1, rect.top+5, strTemp );
  2218. // 价格小数位数格式串
  2219. CString strPriceFmt;
  2220. strPriceFmt.Format( "%%.%df", info.DigitBit() );
  2221. for( int i=nStartPos; i<aReport.GetSize() && i-nStartPos+1<=nMaxCount; i++ )
  2222. {
  2223. REPORT report = aReport.ElementAt(i);
  2224. // Time
  2225. CSPTime time(report.m_time);
  2226. CString strTime = time.Format("%H:%M");
  2227. pDC->SetTextColor( clrText );
  2228. pDC->SetTextAlign( TA_LEFT | TA_TOP );
  2229. pDC->TextOut( x, y+RT_RDELEMENT_HEIGHT*(i-nStartPos), strTime );
  2230. // Price
  2231. CString strPrice;
  2232. strPrice.Format( strPriceFmt, report.m_fNew );
  2233. pDC->SetTextColor( RT_DETERMINE_COLOR(report.m_fNew,report.m_fLast) );
  2234. pDC->SetTextAlign( TA_RIGHT | TA_TOP );
  2235. pDC->TextOut( x2, y+RT_RDELEMENT_HEIGHT*(i-nStartPos), strPrice );
  2236. // Volume
  2237. double dVolume = (i > 0 ? aReport[i].m_fVolume-aReport[i-1].m_fVolume : aReport[i].m_fVolume);
  2238. double dMidPrice = (i > 0 ? (aReport[i-1].m_fBuyPrice[0]+aReport[i-1].m_fSellPrice[0])/2 : (aReport[i].m_fBuyPrice[0]+aReport[i].m_fSellPrice[0])/2 );
  2239. if( dMidPrice < 1e-4 )
  2240. dMidPrice = report.m_fLast;
  2241. CString strVolume, strUp, strDown;
  2242. strUp.LoadString( IDS_SLISTVIEW_UP );
  2243. strDown.LoadString( IDS_SLISTVIEW_DOWN );
  2244. strVolume.Format( "%.0f", dVolume/100 );
  2245. if( report.m_fNew-dMidPrice > 1e-4 )
  2246. strVolume += strUp;
  2247. else if( report.m_fNew-dMidPrice < 1e-4 )
  2248. strVolume += strDown;
  2249. else
  2250. strVolume += "-";
  2251. pDC->SetTextColor( RT_DETERMINE_COLOR(report.m_fNew,dMidPrice) );
  2252. pDC->SetTextAlign( TA_RIGHT | TA_TOP );
  2253. pDC->TextOut( x3, y+RT_RDELEMENT_HEIGHT*(i-nStartPos), strVolume );
  2254. }
  2255. pDC->SetTextAlign( nOldAlign );
  2256. pDC->SelectObject( pOldFont );
  2257. }
  2258. //////////////////////////////////////////////////////////////////////////////////////////////////////
  2259. // 以下为分钟成交明细使用 modeMinuteDetail
  2260. void CRealTime::DrawMinuteDetail( CDC * pDC )
  2261. {
  2262. DECLARE_COLOR_DEFINATION
  2263. CStockInfo & info = m_CurStock.GetStockInfo();
  2264. CMinute & aMinute = m_CurStock.GetMinute();
  2265. // set bkcolor
  2266. pDC->SetBkColor( clrBK );
  2267. // Draw Name And Code
  2268. CFont * pOldFont = AfxSelectDCFont( pDC, 18 );
  2269. pDC->SetTextColor( clrTitle );
  2270. pDC->TextOut( m_rectAll.left+1, m_rectAll.top+3, info.GetStockName() );
  2271. pDC->TextOut( m_rectAll.left+96, m_rectAll.top+3, info.GetStockCode() );
  2272. // Draw Title
  2273. CString strTitle;
  2274. strTitle.LoadString( IDS_REALTIME_MINUTEDETAILTITLE );
  2275. pDC->TextOut( m_rectAll.left+180, m_rectAll.top+3, strTitle );
  2276. // Select Report Font
  2277. AfxSelectDCFont( pDC, 14 );
  2278. // 成交明细
  2279. int nColumnPerPage = GetColumnPerPage( m_rectAll );
  2280. int nCountPerColumn = GetCountPerColumn( m_rectAll );
  2281. int nCountPerPage = nCountPerColumn * nColumnPerPage;
  2282. if( nCountPerPage <= 0 )
  2283. return;
  2284. m_nCurrentStartPos = CheckValidStartPos( m_nCurrentStartPos, aMinute.GetSize(), nCountPerPage, TRUE );
  2285. int nStartPos = m_nCurrentStartPos;
  2286. for( int nColumn=0; nColumn<nColumnPerPage; nColumn ++ )
  2287. {
  2288. if( nStartPos >= aMinute.GetSize() )
  2289. break;
  2290. CRect rectColumn;
  2291. rectColumn.top = m_rectAll.top + RT_RDTITLE_HEIGHT;
  2292. rectColumn.bottom = m_rectAll.bottom;
  2293. rectColumn.left = m_rectAll.left + nColumn*RT_RDCOLUMN_WIDTH;
  2294. rectColumn.right = rectColumn.left + RT_RDCOLUMN_WIDTH;
  2295. DrawMinuteColumn( pDC, info, aMinute, nStartPos, nCountPerColumn, rectColumn );
  2296. nStartPos += nCountPerColumn;
  2297. }
  2298. pDC->SelectObject( pOldFont );
  2299. }
  2300. void CRealTime::DrawMinuteColumn( CDC * pDC, CStockInfo & info, CMinute & aMinute, int nStartPos, int nMaxCount, CRect rect )
  2301. {
  2302. DECLARE_COLOR_DEFINATION
  2303. int y = rect.top + RT_RDTITLE_HEIGHT;
  2304. int x = rect.left+2;
  2305. int x2 = (int)(x+0.55*rect.Width());
  2306. int x3 = rect.right-1;
  2307. // Draw Border
  2308. pDC->Draw3dRect( &rect, clrBorder, clrBorder );
  2309. DrawLine( pDC, 1, clrBorder, rect.left, rect.top+RT_RDTITLE_HEIGHT-2 , rect.right, rect.top+RT_RDTITLE_HEIGHT-2 );
  2310. // Set Align
  2311. pDC->SetBkColor( clrBK );
  2312. UINT nOldAlign = pDC->SetTextAlign( TA_LEFT | TA_TOP );
  2313. // Draw Title Text
  2314. CString strTemp;
  2315. CFont * pOldFont = AfxSelectDCFont( pDC, 14 );
  2316. pDC->SetTextColor( clrText );
  2317. strTemp.LoadString( IDS_REALTIME_TIME );
  2318. pDC->TextOut( x+1, rect.top+5, strTemp );
  2319. pDC->SetTextAlign( TA_RIGHT | TA_TOP );
  2320. strTemp.LoadString( IDS_REALTIME_PRICE );
  2321. pDC->TextOut( x2-1, rect.top+5, strTemp );
  2322. strTemp.LoadString( IDS_REALTIME_VOLUME );
  2323. pDC->TextOut( x3-1, rect.top+5, strTemp );
  2324. // 价格小数位数格式串
  2325. CString strPriceFmt;
  2326. strPriceFmt.Format( "%%.%df", info.DigitBit() );
  2327. double dLastClose = info.m_fLast;
  2328. for( int i=nStartPos; i<aMinute.GetSize() && i-nStartPos+1<=nMaxCount; i++ )
  2329. {
  2330. MINUTE minute = aMinute.ElementAt(i);
  2331. // Time
  2332. CSPTime time(minute.m_time);
  2333. CString strTime = time.Format("%H:%M");
  2334. pDC->SetTextColor( clrText );
  2335. pDC->SetTextAlign( TA_LEFT | TA_TOP );
  2336. pDC->TextOut( x, y+RT_RDELEMENT_HEIGHT*(i-nStartPos), strTime );
  2337. // Price
  2338. CString strPrice;
  2339. strPrice.Format( strPriceFmt, minute.m_fNew );
  2340. pDC->SetTextColor( RT_DETERMINE_COLOR(minute.m_fNew,dLastClose) );
  2341. pDC->SetTextAlign( TA_RIGHT | TA_TOP );
  2342. pDC->TextOut( x2, y+RT_RDELEMENT_HEIGHT*(i-nStartPos), strPrice );
  2343. // Volume
  2344. double dVolume = (i > 0 ? aMinute[i].m_fVolume-aMinute[i-1].m_fVolume : aMinute[i].m_fVolume);
  2345. CString strVolume;
  2346. strVolume.Format( "%.0f", dVolume/100 );
  2347. pDC->SetTextColor( RT_DETERMINE_COLOR(minute.m_fNew,dLastClose) );
  2348. pDC->SetTextAlign( TA_RIGHT | TA_TOP );
  2349. pDC->TextOut( x3, y+RT_RDELEMENT_HEIGHT*(i-nStartPos), strVolume );
  2350. }
  2351. pDC->SetTextAlign( nOldAlign );
  2352. pDC->SelectObject( pOldFont );
  2353. }
  2354. //////////////////////////////////////////////////////////////////////////////////////////////////////
  2355. // 以下为大单成交明细使用 modeBigTradeDetail
  2356. void CRealTime::DrawBigTradeDetail( CDC * pDC )
  2357. {
  2358. DECLARE_COLOR_DEFINATION
  2359. // Load Report
  2360. LoadReportBigTrade( );
  2361. CReport & aReport = m_aReportBigTrade;
  2362. // set bkcolor
  2363. pDC->SetBkColor( clrBK );
  2364. // Draw Title
  2365. CFont * pOldFont = AfxSelectDCFont( pDC, 18 );
  2366. pDC->SetTextColor( clrTitle );
  2367. CString strTitle;
  2368. strTitle.LoadString( IDS_REALTIME_BIGTRADEDETAILTITLE );
  2369. pDC->TextOut( m_rectAll.left+180, m_rectAll.top+3, strTitle );
  2370. // Select Report Font
  2371. AfxSelectDCFont( pDC, 14 );
  2372. // 
  2373. int nColumnPerPage = GetColumnPerPage( m_rectAll );
  2374. int nCountPerColumn = GetCountPerColumn( m_rectAll );
  2375. int nCountPerPage = nCountPerColumn * nColumnPerPage;
  2376. if( nCountPerPage <= 0 )
  2377. return;
  2378. m_nCurrentStartPos = CheckValidStartPos( m_nCurrentStartPos, aReport.GetSize(), nCountPerPage, TRUE );
  2379. int nStartPos = m_nCurrentStartPos;
  2380. for( int nColumn=0; nColumn<nColumnPerPage; nColumn ++ )
  2381. {
  2382. if( nStartPos >= aReport.GetSize() )
  2383. break;
  2384. CRect rectColumn;
  2385. rectColumn.top = m_rectAll.top + RT_RDTITLE_HEIGHT;
  2386. rectColumn.bottom = m_rectAll.bottom;
  2387. rectColumn.left = m_rectAll.left + nColumn*RT_RDCOLUMN_WIDTH;
  2388. rectColumn.right = rectColumn.left + RT_RDCOLUMN_WIDTH;
  2389. DrawBigTradeColumn( pDC, aReport, nStartPos, nCountPerColumn, rectColumn );
  2390. nStartPos += nCountPerColumn;
  2391. }
  2392. pDC->SelectObject( pOldFont );
  2393. }
  2394. void CRealTime::DrawBigTradeColumn( CDC * pDC, CReport & aReport, int nStartPos, int nMaxCount, CRect rect )
  2395. {
  2396. DECLARE_COLOR_DEFINATION
  2397. int y = rect.top + RT_RDTITLE_HEIGHT;
  2398. int x = rect.left+2;
  2399. int x2 = (int)(x+0.48*rect.Width());
  2400. int x3 = (int)(x+0.68*rect.Width());
  2401. int x4 = rect.right-1;
  2402. // Draw Border
  2403. pDC->Draw3dRect( &rect, clrBorder, clrBorder );
  2404. DrawLine( pDC, 1, clrBorder, rect.left, rect.top+RT_RDTITLE_HEIGHT-2 , rect.right, rect.top+RT_RDTITLE_HEIGHT-2 );
  2405. // Set Align
  2406. pDC->SetBkColor( clrBK );
  2407. UINT nOldAlign = pDC->SetTextAlign( TA_LEFT | TA_TOP );
  2408. // Draw Title Text
  2409. CString strTemp;
  2410. CFont * pOldFont = AfxSelectDCFont( pDC, 14 );
  2411. pDC->SetTextColor( clrText );
  2412. strTemp.LoadString( IDS_REALTIME_TIME );
  2413. pDC->TextOut( x+1, rect.top+5, strTemp );
  2414. pDC->SetTextAlign( TA_RIGHT | TA_TOP );
  2415. strTemp.LoadString( IDS_REALTIME_STOCKNAME );
  2416. pDC->TextOut( x2-1, rect.top+5, strTemp );
  2417. strTemp.LoadString( IDS_REALTIME_PRICE );
  2418. pDC->TextOut( x3-1, rect.top+5, strTemp );
  2419. strTemp.LoadString( IDS_REALTIME_VOLUME );
  2420. pDC->TextOut( x4-1, rect.top+5, strTemp );
  2421. for( int i=nStartPos; i<aReport.GetSize() && i-nStartPos+1<=nMaxCount; i++ )
  2422. {
  2423. REPORT report = aReport.ElementAt(i);
  2424. // Time
  2425. CSPTime time(report.m_time);
  2426. CString strTime = time.Format("%H:%M");
  2427. pDC->SetTextColor( clrText );
  2428. pDC->SetTextAlign( TA_LEFT | TA_TOP );
  2429. pDC->TextOut( x, y+RT_RDELEMENT_HEIGHT*(i-nStartPos), strTime );
  2430. // Stock Name
  2431. pDC->SetTextAlign( TA_RIGHT | TA_TOP );
  2432. pDC->TextOut( x2, y+RT_RDELEMENT_HEIGHT*(i-nStartPos), report.m_szName );
  2433. // Price
  2434. CString strPrice;
  2435. strPrice.Format( "%.2f", report.m_fNew );
  2436. pDC->SetTextColor( RT_DETERMINE_COLOR(report.m_fNew,report.m_fLast) );
  2437. pDC->SetTextAlign( TA_RIGHT | TA_TOP );
  2438. pDC->TextOut( x3, y+RT_RDELEMENT_HEIGHT*(i-nStartPos), strPrice );
  2439. // Volume
  2440. // 大单成交的REPORT中的m_fVolume和m_fAmount已转换为成交数量
  2441. double dVolume = aReport[i].m_fVolume;
  2442. double dMidPrice = (aReport[i].m_fBuyPrice[0]+aReport[i].m_fSellPrice[0])/2;
  2443. if( dMidPrice < 1e-4 )
  2444. dMidPrice = report.m_fLast;
  2445. CString strVolume, strUp, strDown;
  2446. strUp.LoadString( IDS_SLISTVIEW_UP );
  2447. strDown.LoadString( IDS_SLISTVIEW_DOWN );
  2448. strVolume.Format( "%.0f", dVolume/100 );
  2449. if( report.m_fNew-dMidPrice > 1e-4 )
  2450. strVolume += strUp;
  2451. else if( report.m_fNew-dMidPrice < 1e-4 )
  2452. strVolume += strDown;
  2453. else
  2454. strVolume += "-";
  2455. pDC->SetTextColor( RT_DETERMINE_COLOR(report.m_fNew,dMidPrice) );
  2456. pDC->SetTextAlign( TA_RIGHT | TA_TOP );
  2457. pDC->TextOut( x4, y+RT_RDELEMENT_HEIGHT*(i-nStartPos), strVolume );
  2458. }
  2459. if( m_nCurrentSelectPos >= 0 && m_nCurrentSelectPos < m_aReportBigTrade.GetSize()
  2460. && m_nCurrentSelectPos >= nStartPos && m_nCurrentSelectPos < nStartPos + nMaxCount )
  2461. {
  2462. int y = rect.top+RT_RDTITLE_HEIGHT+RT_RDELEMENT_HEIGHT*(m_nCurrentSelectPos-nStartPos+1) - 1;
  2463. if( y > rect.top && y < rect.bottom )
  2464. DrawLine( pDC, 2, clrBorder, rect.left+5, y, rect.right-5, y );
  2465. }
  2466. pDC->SetTextAlign( nOldAlign );
  2467. pDC->SelectObject( pOldFont );
  2468. }