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

📄 realtime.cpp

📁 股票软件
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	CClientDC	dc(m_pParent);
	if( NULL == pDC )
		pDC		= &dc;

	CPen	penVLine( PS_SOLID, 1, AfxGetProfile().GetColor( CColorClass::clrLine1 ) );
	CPen * pOldPen = pDC->SelectObject( &penVLine );
	int nOldDrawMode = pDC->SetROP2( R2_XORPEN );

	DWORD	dwSeconds	= CSPTime::GetTradeSecondsOfOneDay();

	if( m_nIndexCurrent >= 0 && m_nIndexCurrent < m_CurStock.GetMinute().GetSize() )
	{
		DWORD sec = CSPTime(m_CurStock.GetMinute()[m_nIndexCurrent].m_time).ToStockTimeSecOrder();
		long	xMedium = m_rectPrice.left+m_rectPrice.Width()*sec/dwSeconds;
		pDC->MoveTo( xMedium, m_rectPrice.top );
		pDC->LineTo( xMedium, m_rectAll.bottom - m_nMarginBottom );
	}

	for( int k=0; k<m_anIndexCurrent.GetSize(); k++ )
	{
		int	nIndex = m_anIndexCurrent[k];
		if( nIndex == m_nIndexCurrent )
			continue;
		if( nIndex >= 0 && nIndex < m_CurStock.GetMinute().GetSize() )
		{
			DWORD sec = CSPTime(m_CurStock.GetMinute()[nIndex].m_time).ToStockTimeSecOrder();
			long	xMedium = m_rectPrice.left+m_rectPrice.Width()*sec/dwSeconds;
			pDC->MoveTo( xMedium, m_rectPrice.top );
			pDC->LineTo( xMedium, m_rectAll.bottom - m_nMarginBottom );
		}
	}

	pDC->SetROP2( nOldDrawMode );
	pDC->SelectObject( pOldPen );
}

void CRealTime::ResetClient( CRect rectAll )
{
	static long lCount = 0;
	TRACE(_T("CRealTime::ResetClient RECT %d %d %d %d %d"), rectAll.left, rectAll.top, rectAll.right, rectAll.bottom, lCount++);

	if( rectAll.IsRectEmpty() )
		return;
	m_rectAll	= rectAll;

	// 买卖信息Rect
	m_rectReport.top	= m_rectAll.top + m_nMarginTop + 7;
	m_rectReport.left	= m_rectAll.right - m_nWidthReport;
	m_rectReport.bottom	= m_rectAll.bottom - m_nMarginBottom;
	m_rectReport.right	= m_rectAll.right;
	if( CRealTime::modePriceLine != m_nDrawMode )
		m_rectReport.SetRectEmpty();
	if( CRealTime::reportNone == m_nReportWhat )
		m_rectReport.SetRectEmpty();

	// 价格Rect
	m_rectPrice.top		= m_rectAll.top + m_nMarginTop;
	m_rectPrice.left	= m_rectAll.left + m_nMarginLeft;
	m_rectPrice.bottom	= m_rectAll.top + (m_rectAll.Height() - m_nMarginTop - m_nMarginBottom)*7/10;
	m_rectPrice.right	= m_rectAll.right - m_rectReport.Width() - m_nMarginCenter;

	// 成交量Rect
	m_rectVolume.top	= m_rectPrice.bottom + 2;
	m_rectVolume.left	= m_rectPrice.left;
	m_rectVolume.bottom	= m_rectAll.bottom - m_nMarginBottom;
	m_rectVolume.right	= m_rectPrice.right;

	// 量比多空指标
	m_rectLBDK.top		= m_rectAll.bottom - m_nMarginBottom;
	m_rectLBDK.left		= m_rectPrice.left;
	m_rectLBDK.bottom	= m_rectAll.bottom - m_nMarginBottom;
	m_rectLBDK.right	= m_rectPrice.right;

	// 买卖力道
	m_rectMMLD.top		= m_rectAll.bottom - m_nMarginBottom;
	m_rectMMLD.left		= m_rectPrice.left;
	m_rectMMLD.bottom	= m_rectAll.bottom - m_nMarginBottom;
	m_rectMMLD.right	= m_rectPrice.right;

	if( CRealTime::techLBDK == m_nTechLine )// 如果显示量比多空
	{
		m_rectPrice.bottom	= m_rectAll.top + (m_rectAll.Height() - m_nMarginTop - m_nMarginBottom)*5/10;
		m_rectVolume.top	= m_rectPrice.bottom + 2;
		m_rectVolume.bottom	= m_rectVolume.top + m_rectVolume.Height()/2;
		m_rectLBDK.top		= m_rectVolume.bottom + 1;
	}
	else if( CRealTime::techMMLD == m_nTechLine )// 如果显示买卖力道
	{
		m_rectPrice.bottom	= m_rectAll.top + (m_rectAll.Height() - m_nMarginTop - m_nMarginBottom)*5/10;
		m_rectVolume.top	= m_rectPrice.bottom + 2;
		m_rectVolume.bottom	= m_rectVolume.top + m_rectVolume.Height()/2;
		m_rectMMLD.top		= m_rectVolume.bottom + 1;
	}
}

void CRealTime::DrawDateAxis( CDC * pDC )
{
	DECLARE_COLOR_DEFINATION

	CRect	rect( m_rectAll.left, m_rectAll.bottom-m_nMarginBottom+1, m_rectPrice.right, m_rectAll.bottom );
	pDC->FillSolidRect( &rect, clrBK );
	pDC->SetBkColor( clrBK );
	pDC->SetTextColor( clrDJ );

	CFont	* pOldFont	= AfxSelectDCFont( pDC, 12 );

	UINT nAlignOld = pDC->SetTextAlign( TA_TOP | TA_CENTER );
	rect.left	= m_rectPrice.left;
	int	nStep = rect.Width()/4;
	pDC->TextOut( rect.left, rect.top, "09:30" );
	pDC->TextOut( rect.left+nStep, rect.top, "10:30" );
	pDC->TextOut( rect.left+nStep*2, rect.top, "11:30" );
	pDC->TextOut( rect.left+nStep*3, rect.top, "14:00" );
	pDC->TextOut( rect.right, rect.top, "15:00" );

	pDC->SetTextAlign( nAlignOld );
	pDC->SelectObject( pOldFont );
}

BOOL CRealTime::GetMinMaxInfo( double *pdLastClose, double *pdMin, double *pdMax, double *pdMaxVolume, BOOL bUptoAxis )
{
	double	dLastClose	= 0;
	if( pdLastClose )
		dLastClose	= *pdLastClose;
	double	dMin = dLastClose, dMax = dLastClose, dMaxVolume = 10;
	BOOL	bPriceOK	= FALSE;
	REPORT	report;
	if( m_CurStock.GetReport().GetSize() > 0 )
	{
		report	= m_CurStock.GetReport().ElementAt( m_CurStock.GetReport().GetSize()-1 );
		if( report.m_fNew > 1e-4 && report.m_fHigh > 1e-4 && report.m_fLow > 1e-4 )
		{
			dMin	= report.m_fLow;
			dMax	= report.m_fHigh;
			bPriceOK	= TRUE;
		}
	}

	for( int i=0; i<m_CurStock.GetMinute().GetSize(); i++ )
	{
		MINUTE & m = m_CurStock.GetMinute().ElementAt(i);
		if( !bPriceOK && dMin < 1e-4 )
			dMin	= m.m_fNew;

		if( !bPriceOK && m.m_fNew < dMin )
			dMin	= m.m_fNew;
		if( !bPriceOK && m.m_fNew > dMax )
			dMax	= m.m_fNew;
		
		double	dVolume = (i > 0 ? m_CurStock.GetMinute()[i].m_fVolume-m_CurStock.GetMinute()[i-1].m_fVolume : m_CurStock.GetMinute()[i].m_fVolume);
		if( dVolume > dMaxVolume )
			dMaxVolume	= dVolume;
	}

	if( dLastClose < 1e-4 )
		dLastClose	= (dMin+dMax)/2;

	if( bUptoAxis )
	{
		double dABS = 1.00 * max(fabs(dMax-dLastClose),fabs(dMin-dLastClose));
		if( dABS < dLastClose * 0.001 )
			dABS	= dLastClose * 0.001;

		dMin = dLastClose-dABS;
		dMax = dLastClose+dABS;
	}
	
	if( pdLastClose )
		*pdLastClose	= dLastClose;
	if( pdMin )
		*pdMin	= dMin;
	if( pdMax )
		*pdMax	= dMax;
	if( pdMaxVolume )
		*pdMaxVolume	= dMaxVolume;
	return TRUE;
}

void CRealTime::DrawPriceVolume( CDC * pDC )
{
	DECLARE_COLOR_DEFINATION

	// Draw Time Axis String
	DrawDateAxis( pDC );

	// Draw Title
	CString	strTitle;
	pDC->SetTextColor( clrTitle );
	pDC->SetBkColor( clrBK );
	strTitle = "分时行情";
	if( CRealTime::modePriceLine != m_nDrawMode )
		strTitle	= m_CurStock.GetStockCode();
	pDC->TextOut( m_rectPrice.left+1, m_rectAll.top+2, strTitle );

	double	dMin = 0, dMax = 0, dMaxVolume = 0;
	double	dLastClose = m_CurStock.GetStockInfo().m_fLast;
	if( ! GetMinMaxInfo( &dLastClose, &dMin, &dMax, &dMaxVolume, TRUE ) )
		return;

	// Draw Price Axis
	DrawPriceVolumeAxis(	pDC, m_rectPrice, m_rectVolume, m_nGapYAxis,
							dLastClose, &dMin, &dMax, dMaxVolume, m_CurStock.GetStockInfo().DigitBit() );
	m_dMaxPrice	= dMax;
	m_dMinPrice	= dMin;

	// Draw Price and Volume Line
	CStockInfo & info	= m_CurStock.GetStockInfo();
	CMinute	& aMinute	= m_CurStock.GetMinute();
	DWORD	secNow	= CSPTime::GetCurrentTime().ToStockTimeSecOrder();
	DWORD	secStep = 60;
	double	dPriceMA= dLastClose;
	int	ptr = 0;
	int	xPos = m_rectPrice.left;
	int	yPosMid = m_rectPrice.top+m_rectPrice.Height()/2;
	int yPos = yPosMid;
	int	yPosMA = yPos;
	int	yPosLast = yPos;
	COLORREF	clrLine1	= AfxGetProfile().GetColor(CColorClass::clrLine1);
	COLORREF	clrLine2	= AfxGetProfile().GetColor(CColorClass::clrLine3);
	COLORREF	clrWave		= clrRise;
	COLORREF	clrVolume	= clrRise;

	DWORD	dwSeconds	= CSPTime::GetTradeSecondsOfOneDay();
	for( DWORD sec=0; sec<=dwSeconds; sec+=secStep )
	{
		BOOL bDrawed = FALSE;
		for( ; ptr<aMinute.GetSize(); ptr++ )
		{
			DWORD secTemp = CSPTime(aMinute[ptr].m_time).ToStockTimeSecOrder();
			if( secTemp > sec )
				break;
			if( (long)secTemp <= (long)sec-(long)secStep )
				continue;
			if( aMinute[ptr].m_fNew < 1e-4 )
				aMinute[ptr].m_fNew	= m_CurStock.GetStockInfo().m_fLast;

			int	xPosNew	= m_rectPrice.left+m_rectPrice.Width()*secTemp/dwSeconds;
			yPosLast	= yPos;

			// Draw Price Line
			CPen	pen1( PS_SOLID, 1, clrLine1 );
			CPen * pOldPen = pDC->SelectObject( &pen1 );
			pDC->MoveTo( xPos, yPos );
			double	dPriceNew	= aMinute[ptr].m_fNew;
			if( dPriceNew <= dMax && dPriceNew >= dMin && dMax-dMin > 1e-4 )
			{
				yPos	= (int)( m_rectPrice.top+m_rectPrice.Height()*(dMax-dPriceNew)/(dMax-dMin) );
				if( yPos <= m_rectPrice.top )		yPos = m_rectPrice.top+1;
				if( yPos >= m_rectPrice.bottom )	yPos = m_rectPrice.bottom-1;
				pDC->LineTo( xPosNew, yPos );
			}

			// Draw Price MA Lime
			CPen	pen2( PS_SOLID, 1, clrLine2 );
			pDC->SelectObject( &pen2 );
			pDC->MoveTo( xPos, yPosMA );
			dPriceMA	= (dPriceNew + ptr*dPriceMA)/(ptr+1);
			if( dPriceMA <= dMax && dPriceMA >= dMin
				&& dPriceNew <= dMax && dPriceNew >= dMin && dMax-dMin > 1e-4 )
			{
				yPosMA	= (int)( m_rectPrice.top+m_rectPrice.Height()*(dMax-dPriceMA)/(dMax-dMin) );
				if( yPosMA <= m_rectPrice.top )		yPosMA = m_rectPrice.top+1;
				if( yPosMA >= m_rectPrice.bottom )	yPosMA = m_rectPrice.bottom-1;
				pDC->LineTo( xPosNew, yPosMA );
			}

			// Draw Wave Line
			double	dWave = 0;
			if( info.IsIndex() && aMinute.GetIndexWave( &dWave, ptr ) )
			{
				if( dWave > 0 )	clrWave	= clrRise;
				if( dWave < 0 )	clrWave	= clrFall;
				CPen	pen3( PS_SOLID, 1, clrWave );
				pDC->SelectObject( &pen3 );
				pDC->MoveTo( xPosNew, yPosMid );
				if( fabs(dWave) < (dMax-dMin)*0.5
					&& dPriceNew <= dMax && dPriceNew >= dMin && dMax-dMin > 1e-4)
					pDC->LineTo( xPosNew, yPosMid + m_rectPrice.Height() * 0.5 * dWave /(dMax-dMin) );
			}

			// Draw Volume Line
			if( yPos < yPosLast )	clrVolume	= clrRise;
			if( yPos > yPosLast )	clrVolume	= clrFall;
			CPen	pen4( PS_SOLID, 1, clrVolume );
			pDC->SelectObject( &pen4 );
			pDC->MoveTo( xPosNew, m_rectVolume.bottom-1 );
			double	dVolume = 0;
			if( ptr > 0 )
				dVolume	= aMinute[ptr].m_fVolume-aMinute[ptr-1].m_fVolume;
			else if( sec <= secStep )
				dVolume	= aMinute[ptr].m_fVolume;
			if( dVolume >= 0 && dVolume <= dMaxVolume && dMaxVolume > 1e-4
				&& dPriceNew <= dMax && dPriceNew >= dMin && dMax-dMin > 1e-4)
				pDC->LineTo( xPosNew, (int)( m_rectVolume.bottom-m_rectVolume.Height()*dVolume/dMaxVolume ) );

			pDC->SelectObject( pOldPen );
			xPos	= xPosNew;
			bDrawed	= TRUE;
		}

		if( !bDrawed && sec <= secNow )
		{
			int	xPosNew	= m_rectPrice.left+m_rectPrice.Width()*sec/dwSeconds;

			// Draw Price Line
			CPen	pen1( PS_SOLID, 1, clrLine1 );
			CPen * pOldPen = pDC->SelectObject( &pen1 );
			pDC->MoveTo( xPos, yPos );
			pDC->LineTo( xPosNew, yPos );
			
			// Draw Price MA Line
			CPen	pen2( PS_SOLID, 1, clrLine2 );
			pDC->SelectObject( &pen2 );
			pDC->MoveTo( xPos, yPosMA );
			pDC->LineTo( xPosNew, yPosMA );

			pDC->SelectObject( pOldPen );
			xPos	= xPosNew;
		}
	}
}

// 量比(多空)指标
void CRealTime::DrawLBDK( CDC * pDC )
{
	if( CRealTime::techLBDK != m_nTechLine )
		return;

	DECLARE_COLOR_DEFINATION

	// Draw Rect
	pDC->FillSolidRect( &m_rectLBDK, clrBK );
	pDC->Draw3dRect( &m_rectLBDK, clrBorder, clrBorder );

	// Draw Title
	CString	strLBDK;
	strLBDK = "量比(多空)";
	DrawTechTitle( pDC, m_rectLBDK.left+5, m_rectLBDK.top+1, strLBDK, TA_LEFT | TA_TOP, 14, clrBK, clrTitle );

	// Prepare Calculate
	CStockInfo & info	= m_CurStock.GetStockInfo();
	CMinute	& aMinute	= m_CurStock.GetMinute();

	double	dVolRatio = 0;
	if( !info.GetRatioVolume( &dVolRatio, info.m_datetech, 5 ) || dVolRatio < 1e-4 )
		return;
	double	dVolAverage	= (info.m_fVolume / dVolRatio);

	// Draw Axis
	double	dMin = 0, dMax = 0;
	if( !aMinute.GetLBDKMinMaxInfo( dVolAverage, &dMin, &dMax )
		|| !DrawAxis( pDC, m_rectLBDK, 0, 5, dMin, dMax, FALSE, FALSE, 2 ) )
		return;

	// Draw
	DWORD	secNow	= CSPTime::GetCurrentTime().ToStockTimeSecOrder();
	DWORD	secStep = 60;
	int	ptr = 0;
	int	xPos = m_rectLBDK.left;
	int	yPos = m_rectLBDK.top+m_rectLBDK.Height()/2;
	COLORREF	clrLine1	= AfxGetProfile().GetColor(CColorClass::clrLine1);

	DWORD	dwSeconds	= CSPTime::GetTradeSecondsOfOneDay();
	for( DWORD sec=0; sec<=dwSeconds; sec+=secStep )
	{
		BOOL bDrawed = FALSE;
		for( ; ptr<aMinute.GetSize(); ptr++ )
		{
			DWORD secTemp = CSPTime(aMinute[ptr].m_time).ToStockTimeSecOrder();
			if( secTemp > sec )
				break;
			if( (long)secTemp <= (long)sec-(long)secStep )
				continue;

			int	xPosNew	= m_rectLBDK.left+m_rectLBDK.Width()*secTemp/dwSeconds;

			// Draw LBDK Line
			CPen	pen1( PS_SOLID, 1, clrLine1 );
			CPen * pOldPen = pDC->SelectObject( &pen1 );
			pDC->MoveTo( xPos, yPos );
			double	dVolRatioNew	= aMinute[ptr].m_fVolume/dVolAverage;
			if( secTemp > 0 )
				dVolRatioNew	= dVolRatioNew * dwSeconds / secTemp;
			if( dVolRatioNew <= dMax && dVolRatioNew >= dMin && dMax-dMin > 1e-4)
			{
				yPos	= (int)( m_rectLBDK.top+m_rectLBDK.Height()*(dMax-dVolRatioNew)/(dMax-dMin) );
				if( yPos <= m_rectLBDK.top )		yPos = m_rectLBDK.top+1;
				if( yPos >= m_rectLBDK.bottom )		yPos = m_rectLBDK.bottom-1;
				pDC->LineTo( xPosNew, yPos );
			}
			
			pDC->SelectObject( pOldPen );
			xPos	= xPosNew;
			bDrawed	= TRUE;
		}

		if( !bDrawed && sec <= secNow )
		{
			int	xPosNew	= m_rectLBDK.left+m_rectLBDK.Width()*sec/dwSeconds;

			// Draw LBDK Line
			CPen	pen1( PS_SOLID, 1, clrLine1 );
			CPen * pOldPen = pDC->SelectObject( &pen1 );
			pDC->MoveTo( xPos, yPos );
			pDC->LineTo( xPosNew, yPos );
			
			pDC->SelectObject( pOldPen );
			xPos	= xPosNew;
		}
	}
}

// 买卖力道指标
void CRealTime::DrawMMLD( CDC * pDC )
{
	if( CRealTime::techMMLD != m_nTechLine )
		return;

	DECLARE_COLOR_DEFINATION

	// Draw Rect

⌨️ 快捷键说明

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