热门文章
推荐文章
K线图经典图解
双顶 孕十字星 单针探底
双底 锤头线 双针探底
多方炮 倒锤头线 下降插入线
舍子线 仙人指路 底部尽头线
搓揉线 衰竭缺口 高位并排阳线
启明星 中继缺口 低位并排阳线
头肩顶 突破缺口 乌云盖顶
吊颈线 下降三法 墓碑十字线
圆弧底 上升三法 岛型反转

DrawOneKLine如何画单根K线

个股 动态 分析 点评 推荐 股票 行情 新股 权证 港股 数据 内参 学院 理财 外汇 期货 债券 银行 黄金 保险 财经 要闻 评论 观察 公司 基金 净值 估值 排行 评级 情报 公告 分析 大盘 风向 传闻 板块 主力 工具 论坛 股票知识 股票入门 股票技术分析 股票基本面分析 炒股入门 K线图 股票名词 短线交易 股票买卖点 新股申购 创业板
南方财富网学院频道 炒股专题 选股 看盘 解盘 波段 分时图 均线 成交量 底部 顶部 洗盘变盘 抄底技巧 手机炒股 股票公式 看盘技巧
·【天天提供三只涨停黑马】 ·●杨百万用8亿介入该股● ·即将疯狂飙升的3只涨停股 ·港股早知道,港股新闻最先看 ·爆料:每日公开3只必涨股票
·股票知识学习,入门的好帮手 ·每日热点概念股上市公司爆料 ·新股中签号、上市时间抢鲜看 ·天天基金网:每日基金净值查询 ·每日最新最及时的大盘分析
您现在的位置: 南方财富网 >> 股票知识 >> K线图 >> 正文
南方财富搜索
DrawOneKLine如何画单根K线2010-9-2 9:13:06 来源:不详 佚名 南方财富网股票交流群:81519774,78476910,15207290,4781538;期货交流群:82620956 //函数实现画单根K线的功能,坐标为普通坐标,而非对数坐标

void CStockGraph::DrawOneKLine(CDC * pDC, int nIndexPos, int nIndexKD, CKData * pKData, double dMin, double dMax, BOOL bGreyed )
{
DECLARE_COLOR_DEFINATION

// Check Valid

//判断当前位置的序列号是否有效,指的是显示窗口,在当前的m_nIndexStart 和 m_nIndexEnd之间
ASSERT( pDC && nIndexPos >= m_nIndexStart && nIndexPos <= m_nIndexEnd && nIndexPos >= 0 );
if( !(pDC && nIndexPos >= m_nIndexStart && nIndexPos <= m_nIndexEnd && nIndexPos >= 0) )
return;

//判断当前位置的序列号是否有效,序列号是否是小于零或大于当前序列的长度
if( !pKData || nIndexKD < 0 || nIndexKD >= pKData->GetSize() )
return;
if( dMax-dMin < 1e-4 )
return;

// Get Region

//关于GetOneKLineRect请参看下面关于这个函数的分析

//这里需要注意的一个问题就是rectK, rcEntity,是有不同的含义的,rectK是指显示的K线矩形区域,实际的画K线的区域是rcEntity,指的是画K线实体的区域
CRect rectK, rcEntity;
long xMedium = 0;
if( !GetOneKLineRect( nIndexPos, &rectK, &rcEntity.left, &rcEntity.right, &xMedium ) )//参数xMedium 为K线实体的中间位置,对应画K线的图形
return;

int xStart = rectK.left;
int xEnd = rectK.right;
ASSERT( xEnd <= m_rectKLineCenter.right );
if( xEnd > m_rectKLineCenter.right )
return;

KDATA kd = pKData->ElementAt(nIndexKD);

//根据当前最低价格/最高价格/收盘价格/开盘价格的计算出K线实体在当前显示区域中坐标.(等比例的计算)

// Set rcEntity's top and bottom, set yLow, yHigh
int yLow = int( m_rectKLineCenter.bottom - m_rectKLineCenter.Height() * (kd.m_fLow - dMin) / (dMax-dMin) );
int yHigh = int( m_rectKLineCenter.bottom - m_rectKLineCenter.Height() * (kd.m_fHigh - dMin) / (dMax-dMin) );
int yOpen = int( m_rectKLineCenter.bottom - m_rectKLineCenter.Height() * (kd.m_fOpen - dMin) / (dMax-dMin) );
int yClose = int( m_rectKLineCenter.bottom - m_rectKLineCenter.Height() * (kd.m_fClose - dMin) / (dMax-dMin) );

//计算出实体区域的上下坐标,左右坐标已经根据序列位置计算出来了,到这个地方,已经计算出了要画K线的试题区域的具体坐标了.

rcEntity.top = min( yOpen, yClose );
rcEntity.bottom = max( yOpen, yClose ) + 1;

//上面已经计算出了要画的K线的坐标了,下面就开始画K线了

if( CStockGraph::klineCandle == m_nCurKLineMode )
{
// Draw Entity

//画实体区域了
COLORREF clr = clrRise;
if( kd.m_fClose < kd.m_fOpen )
clr = clrFallEntity;
if( kd.m_date > m_dwLatestDate )
clr = clrNewKLine;
if( bGreyed )
clr = clrDJ;
pDC->SetBkColor( clrBK );
if( kd.m_fClose < kd.m_fOpen )
pDC->FillSolidRect( &rcEntity, clr );
else
pDC->Draw3dRect( &rcEntity, clr, clr );

// Draw Line

//画K线上的最高和最低价格的线
CPen pen( PS_SOLID, 1, clr );
CPen *pOldPen = pDC->SelectObject( &pen );
pDC->MoveTo( xMedium, yHigh );
pDC->LineTo( xMedium, rcEntity.top );
pDC->MoveTo( xMedium, rcEntity.bottom );
pDC->LineTo( xMedium, yLow );

pDC->SelectObject( pOldPen );
}
else if( CStockGraph::klineAmerica == m_nCurKLineMode )
{
// Draw Entity
COLORREF clr = clrRise;
if( kd.m_date > m_dwLatestDate )
clr = clrNewKLine;
if( bGreyed )
clr = clrDJ;
pDC->SetBkColor( clrBK );

// Draw Line
CPen pen( PS_SOLID, 1, clr );
CPen *pOldPen = pDC->SelectObject( &pen );
pDC->MoveTo( xStart, yHigh );
pDC->LineTo( xStart, yLow );
pDC->MoveTo( xStart, yClose );
pDC->LineTo( xEnd, yClose );

pDC->SelectObject( pOldPen );
}
else if( CStockGraph::klineTower == m_nCurKLineMode )
{

// Draw Entity
COLORREF clr = clrRise;
if( kd.m_fClose < kd.m_fOpen )
clr = clrFallEntity;
if( kd.m_date > m_dwLatestDate )
clr = clrNewKLine;
if( bGreyed )
clr = clrDJ;
pDC->SetBkColor( clrBK );
if( kd.m_fClose < kd.m_fOpen )
pDC->FillSolidRect( &rcEntity, clr );
else
pDC->Draw3dRect( &rcEntity, clr, clr );

if( nIndexKD > 0 )
{
KDATA kdLast = pKData->ElementAt(nIndexKD-1);
int yOpenLast = int( m_rectKLineCenter.bottom - m_rectKLineCenter.Height() * (kdLast.m_fOpen - dMin) / (dMax-dMin) );
int yCloseLast = int( m_rectKLineCenter.bottom - m_rectKLineCenter.Height() * (kdLast.m_fClose - dMin) / (dMax-dMin) );
if( kdLast.m_fClose > kdLast.m_fOpen && kd.m_fClose < kd.m_fOpen )
{
rcEntity.bottom = min(yOpenLast,rcEntity.bottom);
if( rcEntity.bottom > rcEntity.top )
{
pDC->FillSolidRect( &rcEntity, clrBK );
clr = clrRise;
if( kd.m_date > m_dwLatestDate )
clr = clrNewKLine;
if( bGreyed )
clr = clrDJ;
pDC->Draw3dRect( &rcEntity, clr, clr );
}
}
else if( kdLast.m_fClose < kdLast.m_fOpen && kd.m_fClose > kd.m_fOpen )
{
rcEntity.top = max(yOpenLast,rcEntity.top);
if( rcEntity.bottom > rcEntity.top )
{
clr = clrFallEntity;
if( kd.m_date > m_dwLatestDate )
clr = clrNewKLine;
if( bGreyed )
clr = clrDJ;
pDC->FillSolidRect( &rcEntity, clr );
}
}
}
}
}

//函数GetOneKLineRect的分析,得到当前序列位置处要画K线的区域

BOOL CStockGraph::GetOneKLineRect( int nIndex, LPRECT lpRect, long *pxEntityLeft, long *pxEntityRight, long *pxMedium )
{

//判断当前的序列位置是在当前显示的窗口区域中
if( nIndex == -1 || nIndex < m_nIndexStart || nIndex > m_nIndexEnd )
return FALSE;

//初始化画K线的位置的矩形区域

CRect rectK = m_rectCenter;

//计算出K线位置的左右宽度的坐标,上下的坐标没有给出,只是初始化为m_rectCenter中的参数

//左边的起誓位置为,从K线显示区域的左边开始m_rectKLineCenter.left,加上已经显示了nIndex-m_nIndexStart点的距离就是当前序列处的坐标
rectK.left = m_rectKLineCenter.left + (nIndex-m_nIndexStart) * m_nThickness;

//右边的坐标最简单,就是左边左边加上宽度就可以了.
rectK.right = rectK.left + m_nThickness;

if( rectK.Width() <= 0 || rectK.Height() <= 0 )
return FALSE;

//传出参数lpRect
if( lpRect )
*lpRect = rectK;

int xStart = rectK.left;

CRect rcEntity;

//根据当前的K线的宽度计算出序列的右边的坐标点,并传出参数
switch( m_nThickness )
{
case 1:
case 2:
rcEntity.left = xStart;
rcEntity.right = xStart + 1;
break;
case 4:
case 5:
rcEntity.left = xStart;
rcEntity.right = xStart + 3;
break;
case 6:
case 7:
rcEntity.left = xStart;
rcEntity.right = xStart + 5;
break;
case 9:
case 10:
rcEntity.left = xStart;
rcEntity.right = xStart + 7;
break;
case 13:
case 15:
rcEntity.left = xStart;
rcEntity.right = xStart + 11;
break;
default:
ASSERT( FALSE );
rcEntity.left = xStart;
rcEntity.right = xStart + 3;
return FALSE;
}
if( pxEntityLeft )
*pxEntityLeft = rcEntity.left;
if( pxEntityRight )
*pxEntityRight = rcEntity.right;
if( pxMedium )
*pxMedium = rcEntity.left + rcEntity.Width() / 2;

return TRUE;
}


股票k线图 http://kxian.xinwen666.com