📄 realtime.cpp
字号:
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 + -