⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 realtime.cpp

📁 股票软件
💻 CPP
📖 第 1 页 / 共 5 页
字号:
// RealTime.cpp : implementation of the CRealTime class
//

#include "stdafx.h"
#include "RealTime.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


#define TOOLBARHIGHT 20

BOOL bShowReport = FALSE;


#define	RT_DETERMINE_COLOR(x,y)	((x)-(y)>1e-4?clrRise:((x)-(y)<1e-4?clrFall:clrPlane))

void DrawPriceAxisNumber(CDC * pDC, COLORREF clr, int nCount,
					int xStart, int yStart, int xEnd, int yEnd,
					double dLastClose, double fMin, double fMax, int nDotCount )
{
	int	nHeight	= yEnd - yStart;
	if( nHeight <= 0 )
		return;
	if( nCount <= 0 )
		return;
	ASSERT( nDotCount >= 0 );

	CString	strFmt;
	strFmt.Format( "%%.%df", nDotCount );

	pDC->SetTextColor( clr );
	CString	strText;
	CSize	sizeText;
	
	for( int k=0; k<=nCount; k++ )
	{
		double	dCur	= fMin+k*(fMax-fMin)/nCount;
		if( dCur < 0 && dCur > (0-0.6*pow((double)10,0-nDotCount)) )
			dCur	= 0;
		strText.Format( strFmt, dCur );
		sizeText	= pDC->GetTextExtent( strText );
		pDC->TextOut( xStart-sizeText.cx-1, yStart+(nCount-k)*nHeight/nCount-7, strText );
	}
}

BOOL DrawPriceVolumeAxis(	CDC * pDC, CRect rectPrice, CRect rectVolume,
							int nGapYAxis, double dLastClose, double * pdMin, double * pdMax, double dMaxVolume, int nDotCount )
{
	DECLARE_COLOR_DEFINATION

	ASSERT( pdMin && pdMax );
	if( NULL == pdMin || NULL == pdMax )
		return FALSE;
	if( rectPrice.Height() <= 0 || rectPrice.Width() <= 0 )
		return FALSE;
	if( rectVolume.Height() <= 0 || rectVolume.Width() <= 0 )
		return FALSE;
	ASSERT( rectPrice.left == rectVolume.left && rectPrice.right == rectVolume.right );
	ASSERT( nDotCount >= 0 );
	if( nGapYAxis <= 0 || nDotCount < 0 )
		return FALSE;
	if( dLastClose < 1e-4 )
		dLastClose	= (*pdMin+*pdMax)/2;
	
	// 重新修正 *pdMin, *pdMax
	int	nPriceLines		= 2*((rectPrice.Height()/2)/nGapYAxis);
	int	nVolumeLines	= 2*((rectVolume.Height()/2)/nGapYAxis);
	double dABS = max(fabs(*pdMax-dLastClose),fabs(*pdMin-dLastClose));
	double dPrecision = pow((double)10,0-nDotCount);
	if( dABS < dPrecision*nPriceLines )
		dABS	= dPrecision*nPriceLines;
	else if( dABS < 2*dPrecision*nPriceLines )
		dABS	= 2*dPrecision*nPriceLines;
	else if( dABS < 3*dPrecision*nPriceLines )
		dABS	= 3*dPrecision*nPriceLines;
	*pdMin	= dLastClose-dABS;
	*pdMax	= dLastClose+dABS;
	
	// Draw Border
	pDC->Draw3dRect( &rectPrice, clrBorder, clrBorder );
	pDC->Draw3dRect( &rectVolume, clrBorder, clrBorder );

	int k=0;
	// Draw Lines
	for(  k=0; k<nPriceLines; k++ )
		DrawLine( pDC, 1, clrBorder, rectPrice.left, rectPrice.top+k*rectPrice.Height()/nPriceLines, rectPrice.right, rectPrice.top+k*rectPrice.Height()/nPriceLines );
	DrawLine( pDC, 2, clrBorder, rectPrice.left, rectPrice.top+rectPrice.Height()/2, rectPrice.right, rectPrice.top+rectPrice.Height()/2 );
	for(  k=0; k<nVolumeLines; k++ )
		DrawLine( pDC, 1, clrBorder, rectVolume.left, rectVolume.top+k*rectVolume.Height()/nVolumeLines, rectVolume.right, rectVolume.top+k*rectVolume.Height()/nVolumeLines );

	// Draw Columns
	for(  k=1; k<=8; k++ )
	{
		if( k % 2 )
			DrawDashLine( pDC, 1, clrBorder, rectPrice.left+k*rectPrice.Width()/8, rectPrice.top, rectPrice.left+k*rectPrice.Width()/8, rectVolume.bottom );
		else
			DrawLine( pDC, 1, clrBorder, rectPrice.left+k*rectPrice.Width()/8, rectPrice.top, rectPrice.left+k*rectPrice.Width()/8, rectVolume.bottom );
	}

	// Draw Price Axis Number, Will Extent the rect
	CFont	* pOldFont	= AfxSelectDCFont( pDC, 12 );
	pDC->SetBkColor( clrBK );
	CSize	sizeText;
	CString	strFmt, strText;
	strFmt.Format( "%%.%df", nDotCount );
	double	dMinAxis = dLastClose-dABS;
	double	dMaxAxis = dLastClose+dABS;

	for(  k=0; k<=nPriceLines && nPriceLines>0; k++ )
	{
		double	dCur	= dMinAxis+k*(dMaxAxis-dMinAxis)/nPriceLines;
		COLORREF	clr	= clrPlane;
		if( dCur-dLastClose > 1e-4)
			clr	= clrRise;
		if( dCur-dLastClose < -1e-4 )
			clr	= clrFall;

		if( dCur < 0 && dCur > (-0.51*pow((double)10,0-nDotCount)) )
			dCur	= 0;
		strText.Format( strFmt, dCur );
		sizeText	= pDC->GetTextExtent( strText );
		pDC->SetTextColor(  clr );
		pDC->TextOut( rectPrice.left-sizeText.cx-1, rectPrice.top+(nPriceLines-k)*rectPrice.Height()/nPriceLines-7, strText );

		double	dCurPercent	= 0.00;
		if( dLastClose > 1e-4 )
			dCurPercent	= 100*fabs(dCur-dLastClose)/dLastClose;
		strText.Format( "%.2f%%", dCurPercent );
		pDC->TextOut( rectPrice.right+3, rectPrice.top+(nPriceLines-k)*rectPrice.Height()/nPriceLines-7, strText );
	}

	// Draw Volume Axis Number
	DrawAxisNumber(	pDC, clrPlane, nVolumeLines, rectVolume.left, rectVolume.top, rectVolume.right, rectVolume.bottom,
					0, dMaxVolume/100/*成交量手数*/, FALSE, FALSE, 0 );

	pDC->SelectObject( pOldFont );
	return TRUE;
}

/////////////////////////////////////////////////////////////////////////////
// CRealTime

#define	RT_RDTITLE_HEIGHT	24
#define	RT_RDELEMENT_HEIGHT	16
#define	RT_RDCOLUMN_WIDTH	220

CRealTime::CRealTime( )
{
	m_pParent			= NULL;
	m_nDrawMode			= CRealTime::modePriceLine;
	m_nReportWhat		= CRealTime::reportQuote;
	m_nTechLine			= CRealTime::techNone;

	m_nIndexCurrent		= -1;

	m_nCurrentStartPos	= -1;
	m_nCurrentPageCount	= -1;
	m_nCurrentSelectPos	= -1;

	m_dMaxPrice			= 0;
	m_dMinPrice			= 0;
	
	ResetMargins( );
	ResetIndexCurrent( );
}

CRealTime::~CRealTime( )
{
	ClearCurStock();
}

void CRealTime::SetParent( CWnd * pParent )
{
	m_pParent	= pParent;
}

void CRealTime::ResetMargins(	int nMarginTop, int nMarginLeft,
								int nMarginCenter, int nMarginBottom,
								int nGapYAxis, int nWidthReport )
{
	ASSERT( nMarginTop >= 0 && nMarginLeft >= 0 );
	ASSERT( nMarginCenter >= 0 && nMarginBottom >= 0 );
	ASSERT( nGapYAxis > 0 );
	ASSERT( nWidthReport >= 0 );

	m_nMarginTop		= nMarginTop;
	m_nMarginLeft		= nMarginLeft;
	m_nMarginCenter		= nMarginCenter;
	m_nMarginBottom		= nMarginBottom;
	m_nGapYAxis		= nGapYAxis;
	m_nWidthReport	= nWidthReport;

	if( m_nGapYAxis <= 0 )
		m_nGapYAxis	= 18;
}

void CRealTime::ClearCurStock( )
{
	m_CurStock.Clear();
}

BOOL CRealTime::SetCurStock( const char * szCode )
{
	if( NULL == szCode || strlen(szCode) <= 0 )
	{
		ASSERT( FALSE );
		return FALSE;
	}

	CStockInfo	info;
	if( !AfxGetStockContainer().GetStockInfo( szCode, &info ) )
	{
		ASSERT( FALSE );
		return FALSE;
	}

	return SetCurStock( info );
}

BOOL CRealTime::SetCurStock( CStockInfo & info )
{
	if( m_CurStock.GetStockInfo().IsEqualTo( info.GetMarket(), info.GetStockCode() ) )
	{
		return TRUE;
	}

	ResetIndexCurrent( );
	ClearCurStock();
	m_CurStock.SetStockInfo( &info );
	
	return TRUE;
}

BOOL CRealTime::PrepareStockData( )
{
	m_CurStock.GetReport().RemoveAll();
	m_CurStock.GetMinute().RemoveAll();
	m_CurStock.GetOutline().RemoveAll();

	// 读取本地文件
	m_CurStock.SetDatabase( &AfxGetDB() );

	// 取得最新行情
	m_CurStock.PrepareData( CStock::dataReport, CKData::ktypeDay, TRUE );
	m_CurStock.PrepareData( CStock::dataMinute, CKData::ktypeDay, TRUE );
	m_CurStock.PrepareData( CStock::dataOutline, CKData::ktypeDay, TRUE );

	AfxGetStkReceiver().GetReport( m_CurStock.GetStockInfo(), m_CurStock.GetReport() );

	int	nLen = m_CurStock.GetReport().GetSize();
	if( nLen > 0 )
		UpdateStockInfoByREPORT( m_CurStock.GetStockInfo(), &(m_CurStock.GetReport().ElementAt(nLen-1)) );
	return TRUE;
}

void CRealTime::SetDrawMode( int nDrawMode, int nTechLine, int nReportWhat )
{
	m_nDrawMode		= nDrawMode;
	m_nTechLine		= nTechLine;
	m_nReportWhat	= nReportWhat;

	m_nCurrentStartPos	= -1;
	m_nCurrentPageCount	= -1;
	m_nCurrentSelectPos	= -1;
}

int CRealTime::GetDrawMode( )
{
	return m_nDrawMode;
}

int CRealTime::GetDrawTechLine( )
{
	return m_nTechLine;
}

int CRealTime::GetReportWhat( )
{
	return m_nReportWhat;
}

LRESULT CRealTime::OnStkReceiverData( WPARAM wParam, LPARAM lParam )
{
	PCOMMPACKET	pCommPacket	= (PCOMMPACKET)lParam;

	switch( wParam )
	{
	case CStock::dataReport:
		if( pCommPacket && CStock::dataReport == pCommPacket->m_dwDataType )
		{
			BOOL	bInv = FALSE;
			for(DWORD i=0; i<pCommPacket->m_dwCount; i++)
			{
				if( m_CurStock.GetStockInfo().IsEqualTo( pCommPacket->m_pReport[i].m_dwMarket, pCommPacket->m_pReport[i].m_szCode ) )
				{
					UpdateStockInfoByREPORT( m_CurStock.GetStockInfo(), &(pCommPacket->m_pReport[i]) );
					if( -1 != m_CurStock.GetReport().InsertReportSort( pCommPacket->m_pReport[i] ) )
					{
						MINUTE	minute;
						if( convert_REPORT_to_MINUTE( &(pCommPacket->m_pReport[i]), &minute ) )
							m_CurStock.GetMinute().InsertMinuteSort( minute );
						m_nCurrentStartPos	= -1;
						bInv = TRUE;
					}
				}
			}
			if( bInv && m_pParent && ::IsWindow(m_pParent->GetSafeHwnd()) )
				m_pParent->Invalidate();
		}
		break;
	case CStock::dataMinute:
		if( pCommPacket && CStock::dataMinute == pCommPacket->m_dwDataType )
		{
			int	nOldSize	= m_CurStock.GetMinute().GetSize();
			for(DWORD i=0; i<pCommPacket->m_dwCount; i++)
			{
				if( m_CurStock.GetStockInfo().IsEqualTo( pCommPacket->m_pMinute[i].m_dwMarket, pCommPacket->m_pMinute[i].m_szCode ) )
					m_CurStock.GetMinute().InsertMinuteSort( pCommPacket->m_pMinute[i] );
			}
			if( nOldSize != m_CurStock.GetMinute().GetSize() && m_pParent && ::IsWindow(m_pParent->GetSafeHwnd()) )
			{
				m_nCurrentStartPos	= -1;
				m_pParent->Invalidate();
			}
		}
		break;
	}
	return 0L;
}

void CRealTime::Redraw( CDC * pDC, CRect rectAll )
{
	ASSERT( m_pParent && ::IsWindow( m_pParent->GetSafeHwnd() ) );
	if( !m_pParent || !::IsWindow(m_pParent->GetSafeHwnd()) )
		return;

	CClientDC	dc(m_pParent);
	if( NULL == pDC )
		pDC		= &dc;

	ResetClient( rectAll );
	pDC->FillSolidRect( &rectAll, AfxGetProfile().GetColor(CColorClass::clrGraphBK) );

	if( CRealTime::modePriceLine == m_nDrawMode )
	{
		DrawPriceVolume( pDC );
		DrawLBDK( pDC );
		DrawMMLD( pDC );
		DrawReportRegion( pDC );
			
		DrawSelectionLine( pDC, TRUE );
		OnIndexCurrentChanged( );
	}
	else if( CRealTime::modeReportDetail == m_nDrawMode )
	{
		DrawReportDetail( pDC );
	}
	else if( CRealTime::modeMinuteDetail == m_nDrawMode )
	{
		DrawMinuteDetail( pDC );
	}
	else if( CRealTime::modeBigTradeDetail == m_nDrawMode )
	{
		DrawBigTradeDetail( pDC );
	}
}

void CRealTime::DrawReportRegion( CDC * pDC )
{
	ASSERT( m_pParent && ::IsWindow( m_pParent->GetSafeHwnd() ) );
	if( !m_pParent || !::IsWindow(m_pParent->GetSafeHwnd()) )
		return;

	CClientDC	dc(m_pParent);
	if( NULL == pDC )
		pDC		= &dc;

	if( CRealTime::modePriceLine == m_nDrawMode )
	{
		switch( m_nReportWhat )
		{
		case CRealTime::reportQuote:		DrawReportQuote( pDC );			break;
		case CRealTime::reportPrice:		DrawReportPrice( pDC );			break;
		case CRealTime::reportMinute:		DrawReportMinute( pDC );		break;
		case CRealTime::reportBuySellEx:	DrawReportBuySellEx( pDC );		break;
		case CRealTime::reportValue:		DrawReportValue( pDC );			break;
		case CRealTime::reportDistribute:	DrawReportDistribute( pDC );	break;
		case CRealTime::reportBigTrade:		DrawReportBigTrade( pDC );		break;
		}
	}
}

//////////////////////////////////////////////////////////////////////////////////////////////////////
// 以下为分时价格线使用 modePriceLine

void CRealTime::MoveLeft( BOOL bShiftPressed )
{
	if( CRealTime::modePriceLine != m_nDrawMode )
		return;
	Move( -1, bShiftPressed, FALSE );
}

void CRealTime::MoveRight( BOOL bShiftPressed )
{
	if( CRealTime::modePriceLine != m_nDrawMode )
		return;
	Move( 1, bShiftPressed, FALSE );
}

void CRealTime::MoveUp( BOOL bShiftPressed )
{
	if( CRealTime::modePriceLine == m_nDrawMode )
	{
		int	nTotalSize = 0;
		if( CRealTime::reportQuote == m_nReportWhat )
			nTotalSize	= m_CurStock.GetReport().GetSize();
//		else if( CRealTime::reportPrice == m_nReportWhat )

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -