📄 drawtech.cpp
字号:
else
return;
// GetMinMaxInfo
double dMinDJ = 0, dMaxDJ = 0;
CKLine kline( pKData );
int nStartDJ = pKData->GetIndexByDate( kdata.ElementAt(m_nIndexStart).m_date );
int nEndDJ = pKData->GetIndexByDate( kdata.ElementAt(m_nIndexEnd).m_date );
if( -1 == nStartDJ ) nStartDJ = 0;
if( -1 == nEndDJ ) nEndDJ = pKData->GetSize()-1;
if( nStartDJ < 0 || nEndDJ < 0 || !kline.GetMinMaxInfo( nStartDJ, nEndDJ, &dMinDJ, &dMaxDJ ) )
return;
// Draw
for( int nIndex=m_nIndexStart; nIndex<=m_nIndexEnd; nIndex++ )
{
DWORD date = kdata.ElementAt(nIndex).m_date;
int nIndexDJ = pKData->GetIndexByDate( date );
if( nIndexDJ >= 0 && nIndexDJ < pKData->GetSize() )
{
DrawOneKLine( pDC, nIndex, nIndexDJ, pKData, dMinDJ, dMaxDJ, TRUE );
}
}
}
void CStockGraph::DrawTechCW( CDC * pDC, CRect rect, BOOL bDrawTitle, double dMin, double dMax )
{
CHECK_NODATATODRAW
DECLARE_COLOR_DEFINATION
if( bDrawTitle )
return;
CKData & kdata = m_CurStock.GetKData(m_nCurKType);
m_techparam.cw.AttachParameters( AfxGetProfile().GetTechParameters().cw );
double dStep = (dMax-dMin)*0.003;
CSPDWordArray adwPrice, adwVolume;
double dMinVolume = 0, dMaxVolume = 0;
int nEnd = -1;
if( !m_techparam.cw.CalculatePastCW(nEnd, 0, m_CurStock.GetStockInfo(), dStep, adwPrice, adwVolume, &dMinVolume, &dMaxVolume, NULL, NULL )
|| dMinVolume < 0 || dMaxVolume < 1e-4 )
return;
CPen pen( PS_SOLID, 3, clrCW );
CPen * pOldPen = pDC->SelectObject( &pen );
double dVolume = 0, dPrice = 0;
for( int k=0; k<adwPrice.GetSize() && k<adwVolume.GetSize(); k++ )
{
dPrice = double(adwPrice[k]) * 0.001;
dVolume = adwVolume[k];
int yPrice = int( rect.bottom - (rect.Height()-m_nHeightSubtitle) * (dPrice - dMin) / (dMax-dMin) );
int xVolume = int( rect.right - (rect.Width()*dVolume/(3*dMaxVolume)) );
if( yPrice > rect.top+m_nHeightSubtitle+1 && yPrice < rect.bottom-2 )
{
pDC->MoveTo( xVolume, yPrice );
pDC->LineTo( rect.right-1, yPrice );
}
}
pDC->SelectObject( pOldPen );
}
////////////////////////////////////////////////////////////
// Technical Lines
void CStockGraph::DrawTechMACD( CDC * pDC, CRect rect, BOOL bDrawTitle, int nTech, CMACD * pmacd )
{
CHECK_NODATATODRAW
DECLARE_COLOR_DEFINATION
COLORREF clrLine1 = AfxGetProfile().GetColor(CColorClass::clrLine1);
COLORREF clrLine2 = AfxGetProfile().GetColor(CColorClass::clrLine2);
// Prepare
CKData & kdata = m_CurStock.GetKData(m_nCurKType);
m_techparam.macd.AttachParameters( AfxGetProfile().GetTechParameters().macd );
if( NULL == pmacd )
{
pmacd = &(m_techparam.macd);
nTech = STT_MACD;
}
double dMin = 0, dMax = 1;
if( !pmacd->GetMinMaxInfo( m_nIndexStart, m_nIndexEnd, &dMin, &dMax )
|| !DrawAxis( pDC, rect, m_nHeightSubtitle, 5, dMin, dMax, FALSE, TRUE, 2 ) )
return;
// Draw Title
if( bDrawTitle )
DrawTechTitle( pDC, rect.left+5, rect.top+1,AfxGetSTTShortName(nTech), TA_LEFT | TA_TOP, 14, clrBK, clrTitle );
// Draw
double dEMA1 = 0, dEMA2 = 0, dDIF = 0, dDEA = 0;
int yDIFLast = (int)dMin, yDIFNow, yDEALast = (int)dMin, yDEANow;
BOOL bHasLast = FALSE;
for( int nIndex=m_nIndexStart; nIndex<=m_nIndexEnd; nIndex++ )
{
// Prepare Rect
CRect rectK;
long xMedium = 0;
if( !GetOneKLineRect( nIndex, &rectK, NULL, NULL, &xMedium ) )
continue;
// Draw
if( pmacd->Calculate( &dEMA1, &dEMA2, &dDIF, &dDEA, nIndex, bHasLast ) )
{
yDIFNow = int( rect.bottom - (rect.Height()-m_nHeightSubtitle) * (dDIF - dMin) / (dMax-dMin) );
yDEANow = int( rect.bottom - (rect.Height()-m_nHeightSubtitle) * (dDEA - dMin) / (dMax-dMin) );
int yZero = int( rect.bottom - (rect.Height()-m_nHeightSubtitle) * (0-dMin) / (dMax-dMin) );
int yGap = int( rect.bottom - (rect.Height()-m_nHeightSubtitle) * (2*dDIF-2*dDEA-dMin) / (dMax-dMin) );
if( bHasLast )
{
CPen penDiff( PS_SOLID, 1, (dDIF-dDEA)>0 ? clrRise : clrFall );
CPen * pOldPen = pDC->SelectObject( &penDiff );
pDC->MoveTo( xMedium, yZero );
pDC->LineTo( xMedium, yGap );
pDC->SelectObject( pOldPen );
if( nIndex > m_nIndexStart )
{
if( yDIFLast > rect.bottom || yDIFLast < rect.top+m_nHeightSubtitle || yDIFNow > rect.bottom || yDIFNow < rect.top+m_nHeightSubtitle
|| yDEALast > rect.bottom || yDEALast < rect.top+m_nHeightSubtitle || yDEANow > rect.bottom || yDEANow < rect.top+m_nHeightSubtitle )
continue;
CPen penDIF( PS_SOLID, 1, clrLine1 );
pOldPen = pDC->SelectObject( &penDIF );
pDC->MoveTo( xMedium-m_nThickness, yDIFLast );
pDC->LineTo( xMedium, yDIFNow );
CPen penDEA( PS_SOLID, 1, clrLine2 );
pDC->SelectObject( &penDEA );
pDC->MoveTo( xMedium-m_nThickness, yDEALast );
pDC->LineTo( xMedium, yDEANow );
pDC->SelectObject( pOldPen );
}
}
bHasLast = TRUE;
yDIFLast = yDIFNow;
yDEALast = yDEANow;
// Draw Sub Title, Param Value
int nIndexParam = ( m_nIndexCurrent >= 0 ? m_nIndexCurrent : kdata.GetSize()-1 );
if( bDrawTitle && nIndex == nIndexParam )
{
if( rect.left+300 <= rect.right )
{
CFont * pOldFont = AfxSelectDCFont( pDC, 12 );
pDC->SetBkColor( clrBK );
CString strText;
strText.Format( "EMA(%d) EMA(%d) DIF %.2f ", pmacd->m_nEMA1Days, pmacd->m_nEMA2Days, dDIF );
pDC->SetTextColor( clrLine1 );
pDC->TextOut( rect.left+m_nWidthSubtitle, rect.top+1, strText );
strText.Format( "DEA(%d) %.2f", pmacd->m_nDIFDays, dDEA );
pDC->SetTextColor( clrLine2 );
pDC->TextOut( rect.left+m_nWidthSubtitle+m_nWidthParameter*2, rect.top+1, strText );
pDC->SelectObject( pOldFont );
}
}
}
}
}
void CStockGraph::DrawTechMIKE( CDC * pDC, CRect rect, BOOL bDrawTitle )
{
CHECK_NODATATODRAW
DECLARE_COLOR_DEFINATION
// Prepare
CKData & kdata = m_CurStock.GetKData(m_nCurKType);
m_techparam.mike.AttachParameters( AfxGetProfile().GetTechParameters().mike );
// Draw Title
if( bDrawTitle )
DrawTechTitle( pDC, rect.left+5, rect.top+1,AfxGetSTTShortName(STT_MIKE), TA_LEFT | TA_TOP, 14, clrBK, clrTitle );
// Draw
double dWR = 0, dMR = 0, dSR = 0, dWS = 0, dMS = 0, dSS = 0;
int nIndexParam = m_nIndexCurrent >= 0 ? m_nIndexCurrent : kdata.GetSize()-1;
if( nIndexParam < 0 || nIndexParam >= kdata.GetSize() )
return;
CFont * pOldFont = AfxSelectDCFont( pDC, 14 );
pDC->SetBkColor( clrBK );
if( m_techparam.mike.CalculateMIKE( &dWR, &dMR, &dSR, &dWS, &dMS, &dSS, nIndexParam ) )
{
CSize szUnit = CSize( max(35,rect.Width()/6), max(18,rect.Height()/5) );
int xStart = rect.left+szUnit.cx;
int yStart = rect.top+szUnit.cy;
double dC = kdata.ElementAt(nIndexParam).m_fClose;
CString strTemp;
DrawTextWithRect( pDC, xStart, yStart, xStart+szUnit.cx+1, yStart+szUnit.cy+1, "项目", clrBorder, clrTitle, clrBK, &rect );
DrawTextWithRect( pDC, xStart+szUnit.cx, yStart, xStart+szUnit.cx*2+1, yStart+szUnit.cy+1, "初级", clrBorder, clrTitle, clrBK, &rect );
DrawTextWithRect( pDC, xStart+szUnit.cx*2, yStart, xStart+szUnit.cx*3+1, yStart+szUnit.cy+1, "中级", clrBorder, clrTitle, clrBK, &rect );
DrawTextWithRect( pDC, xStart+szUnit.cx*3, yStart, xStart+szUnit.cx*4+1, yStart+szUnit.cy+1, "强力", clrBorder, clrTitle, clrBK, &rect );
DrawTextWithRect( pDC, xStart, yStart+szUnit.cy, xStart+szUnit.cx+1, yStart+szUnit.cy*2+1, "压力", clrBorder, clrTitle, clrBK, &rect );
strTemp.Format( "%.2f", dWR );
DrawTextWithRect( pDC, xStart+szUnit.cx, yStart+szUnit.cy, xStart+szUnit.cx*2+1, yStart+szUnit.cy*2+1, strTemp, clrBorder, dWR > dC ? clrRise : clrFall, clrBK, &rect );
strTemp.Format( "%.2f", dMR );
DrawTextWithRect( pDC, xStart+szUnit.cx*2, yStart+szUnit.cy, xStart+szUnit.cx*3+1, yStart+szUnit.cy*2+1, strTemp, clrBorder, dMR > dC ? clrRise : clrFall, clrBK, &rect );
strTemp.Format( "%.2f", dSR );
DrawTextWithRect( pDC, xStart+szUnit.cx*3, yStart+szUnit.cy, xStart+szUnit.cx*4+1, yStart+szUnit.cy*2+1, strTemp, clrBorder, dSR > dC ? clrRise : clrFall, clrBK, &rect );
DrawTextWithRect( pDC, xStart, yStart+szUnit.cy*2, xStart+szUnit.cx+1, yStart+szUnit.cy*3+1, "支撑", clrBorder, clrTitle, clrBK, &rect );
strTemp.Format( "%.2f", dWS );
DrawTextWithRect( pDC, xStart+szUnit.cx, yStart+szUnit.cy*2, xStart+szUnit.cx*2+1, yStart+szUnit.cy*3+1, strTemp, clrBorder, dWS > dC ? clrRise : clrFall, clrBK, &rect );
strTemp.Format( "%.2f", dMS );
DrawTextWithRect( pDC, xStart+szUnit.cx*2, yStart+szUnit.cy*2, xStart+szUnit.cx*3+1, yStart+szUnit.cy*3+1, strTemp, clrBorder, dMS > dC ? clrRise : clrFall, clrBK, &rect );
strTemp.Format( "%.2f", dSS );
DrawTextWithRect( pDC, xStart+szUnit.cx*3, yStart+szUnit.cy*2, xStart+szUnit.cx*4+1, yStart+szUnit.cy*3+1, strTemp, clrBorder, dSS > dC ? clrRise : clrFall, clrBK, &rect );
}
pDC->SelectObject( pOldFont );
}
void CStockGraph::DrawTechPSY( CDC * pDC, CRect rect, BOOL bDrawTitle )
{
CKData & kdata = m_CurStock.GetKData(m_nCurKType);
m_techparam.psy.AttachParameters( AfxGetProfile().GetTechParameters().psy );
double dMin = 0, dMax = 0;
if( !m_techparam.psy.GetMinMaxInfo( m_nIndexStart, m_nIndexEnd, &dMin, &dMax )
|| !DrawAxis( pDC, rect, m_nHeightSubtitle, 5, dMin, dMax, FALSE, TRUE, 0 ) )
return;
DrawTechUtil1( pDC, rect, bDrawTitle, dMin, dMax, STT_PSY, &(m_techparam.psy), &kdata,
AfxGetProfile().GetColor(CColorClass::clrLine1), drawtechtype_line );
}
void CStockGraph::DrawTechVOLUME( CDC * pDC, CRect rect, BOOL bDrawTitle )
{
CHECK_NODATATODRAW
DECLARE_COLOR_DEFINATION
// Prepare
CKData & kdata = m_CurStock.GetKData(m_nCurKType);
m_techparam.volume.AttachParameters( AfxGetProfile().GetTechParameters().volume );
double dMin = 0, dMax = 1;
if( !m_techparam.volume.GetMinMaxInfo( m_nIndexStart, m_nIndexEnd, &dMin, &dMax )
|| !DrawAxis( pDC, rect, m_nHeightSubtitle, 3, dMin*0.01, dMax*0.01, FALSE, TRUE, 0 ) )
return;
// Draw Title
if( bDrawTitle )
{
DrawTechTitle( pDC, rect.left+5, rect.top+1, AfxGetSTTShortName(STT_VOLUME), TA_LEFT | TA_TOP, 14, clrBK, clrTitle );
CFont * pOldFont = AfxSelectDCFont( pDC, 12 );
pDC->SetBkColor( clrBK );
int nIndexParam = ( m_nIndexCurrent >= 0 ? m_nIndexCurrent : kdata.GetSize()-1 );
double dParam;
CString strText;
for( int k=0; k<m_techparam.volume.m_adwMADays.GetSize(); k++ )
{
if( m_techparam.volume.Calculate( &dParam, nIndexParam, m_techparam.volume.m_adwMADays[k], FALSE ) )
{
strText.Format( "%dMV %.0f", m_techparam.volume.m_adwMADays[k], dParam );
pDC->SetTextColor( GetLineColor( k ) );
if( rect.left+m_nWidthSubtitle+(k+1)*m_nWidthParameter > rect.right )
break;
pDC->TextOut( rect.left+m_nWidthSubtitle+k*m_nWidthParameter, rect.top+1, strText );
}
}
pDC->SelectObject( pOldFont );
}
// Draw
for( int k=0; k<m_techparam.volume.m_adwMADays.GetSize(); k++ )
{
int yLast, yNow;
BOOL bHasLast = FALSE;
double dNow;
for( int nIndex=m_nIndexStart; nIndex<=m_nIndexEnd; nIndex++ )
{
// Prepare Rect
CRect rectK, rcEntity;
long xMedium = 0;
if( !GetOneKLineRect( nIndex, &rectK, &rcEntity.left, &rcEntity.right, &xMedium ) )
continue;
// Draw Entity
if( 0 == k )
{
// Calculate rcEntity.top and rcEntity.bottom
KDATA kd = kdata.ElementAt(nIndex);
rcEntity.top = int( rect.bottom - (rect.Height()-m_nHeightSubtitle) * (kd.m_fVolume - dMin) / (dMax-dMin) );
rcEntity.bottom = rect.bottom-1;
COLORREF clr = clrRise;
if( kd.m_fClose < kd.m_fOpen )
clr = clrFallEntity;
if( kd.m_date > m_dwLatestDate )
clr = clrNewKLine;
pDC->SetBkColor( clrBK );
if( kd.m_fClose < kd.m_fOpen )
pDC->FillSolidRect( &rcEntity, clr );
else
pDC->Draw3dRect( &rcEntity, clr, clr );
}
// Draw MV
if( m_techparam.volume.Calculate( &dNow, nIndex, m_techparam.volume.m_adwMADays[k], bHasLast ) )
{
yNow = int( rect.bottom - (rect.Height()-m_nHeightSubtitle) * (dNow - dMin) / (dMax-dMin) );
if( bHasLast )
{
if( yLast > rect.bottom || yLast < rect.top+m_nHeightSubtitle
|| yNow > rect.bottom || yNow < rect.top+m_nHeightSubtitle )
continue;
CPen penLocal( PS_SOLID, 1, GetLineColor(k) );
CPen * pOldPen = pDC->SelectObject( &penLocal );
pDC->MoveTo( xMedium-m_nThickness, yLast );
pDC->LineTo( xMedium, yNow );
pDC->SelectObject( pOldPen );
}
bHasLast = TRUE;
yLast = yNow;
}
}
}
}
void CStockGraph::DrawTechNVI( CDC * pDC, CRect rect, BOOL bDrawTitle )
{
CKData & kdata = m_CurStock.GetKData(m_nCurKType);
m_techparam.nvi.AttachParameters( AfxGetProfile().GetTechParameters().nvi );
double dMin = 0, dMax = 0;
if( !m_techparam.nvi.GetMinMaxInfo( m_nIndexStart, m_nIndexEnd, &dMin, &dMax )
|| !DrawAxis( pDC, rect, m_nHeightSubtitle, 5, dMin, dMax, FALSE, TRUE, 0 ) )
return;
DrawTechUtil2( pDC, rect, bDrawTitle, dMin, dMax, STT_NVI, &(m_techparam.nvi), &kdata,
AfxGetProfile().GetColor(CColorClass::clrLine1),
AfxGetProfile().GetColor(CColorClass::clrLine2),
"NVI", "MA");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -