策略为王源代码扩展系列-分时图(5)-为实时行情分时图、历史行情分时图、行情回放窗口增加叠加指数功能

Published

思路:

1.新增一个画线函数,该函数直接读取指数的数据,然后比照分时图画出来。

2.先算指数涨幅,Y价格=股票昨日收盘价*指数涨幅。

一、实时行情

//custom extend by freeman叠加指数分时线
void CHistoryRealTime::DrawPriceVolume2(CDC* pDC)
{
	DECLARE_COLOR_DEFINATION

	//获取股票的最大、最小值
	double	dMin = 0, dMax = 0, dMaxVolume = 0;
	double	dLastClose = m_CurStock.GetStockInfo().m_fLast;
	if (!GetMinMaxInfo(&dLastClose, &dMin, &dMax, &dMaxVolume, TRUE))//画分时线,获取昨天收盘价,当天最低价、最高价、最大量
		return;

	//读取指数数据
	CStockInfo	info;
	AfxGetStockContainer().GetStockInfo("399001", &info);

	CStock		m_CurStock2;
	m_CurStock2.SetStockInfo(&info);

	// Prepare Data
	// 读取本地文件
	m_CurStock2.SetDatabase(&AfxGetDB());

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


	// Draw Price 
	//CStockInfo& info = m_CurStock2.GetStockInfo();
	CMinute& aMinute = m_CurStock2.GetMinute();
	DWORD	secNow = CSPTime::GetCurrentTime().ToStockTimeSecOrder();//获取当前时间
	DWORD	secStep = 60;

	//x Axis
	int	ptr = 0;
	int	xPos = m_rectPrice.left;

	int	yPosMid = m_rectPrice.top + m_rectPrice.Height() / 2;
	int yPos = yPosMid;

	int	yPosLast = yPos; //y 指向中间线
	//画线颜色
	COLORREF	clrLine5 = AfxGetProfile().GetColor(CColorClass::clrCW);

	DWORD	dwSeconds = CSPTime::GetTradeSecondsOfOneDay();
	//以60秒为步进,开始画指数分时线
	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_CurStock2.GetStockInfo().m_fLast;//昨日收盘价

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

			// Draw Price Line
			CPen	pen1(PS_SOLID, 1, clrLine5);
			CPen* pOldPen = pDC->SelectObject(&pen1);
			pDC->MoveTo(xPos, yPos);

			//根据价格算Y抽
			double	dPriceNew = aMinute[ptr].m_fNew;
			//计算指数涨幅
			double  indexDiffPercent = (dPriceNew - m_CurStock2.GetStockInfo().m_fLast) / m_CurStock2.GetStockInfo().m_fLast;

			//换算成股票价格
			dPriceNew = m_CurStock.GetStockInfo().m_fLast * (1 + indexDiffPercent);

			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);
			}

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


	}




}

 

二、历史行情

实现思路

1.备份m_CurStock 到 m_CurStockBackup

2.添加1个定时器CHistoryRealTime::OnTimer(),负责从备份的m_CurStockBackup依次填入_CurStock

3.新增一个画线函数DrawPriceVolume2(CDC* pDC);   叠加指数,该函数直接读取指数的数据,然后比照分时图画出来。

 

 

/custom extend by freeman叠加指数分时线
void CHistoryRealTime::DrawPriceVolume2(CDC* pDC)
{
	DECLARE_COLOR_DEFINATION

	//获取股票的最大、最小值
	double	dMin = 0, dMax = 0, dMaxVolume = 0;
	double	dLastClose = m_CurStock.GetStockInfo().m_fLast;
	if (!GetMinMaxInfo(&dLastClose, &dMin, &dMax, &dMaxVolume, TRUE))//画分时线,获取昨天收盘价,当天最低价、最高价、最大量
		return;

	//从股票中获取选择的日K线日期
	DWORD date = 0;
	date = m_CurStock.GetStockInfo().m_dateHistoryReport;


	//读取指数数据
	CStockInfo	info;
	AfxGetStockContainer().GetStockInfo("399001", &info);

	CStock		m_CurStock2;

	//设置选择的日期,会读出历史分笔数据
	info.m_dateHistoryReport = date;
	m_CurStock2.SetStockInfo(&info);

	// Prepare Data
	// 读取本地文件
	m_CurStock2.SetDatabase(&AfxGetDB());

	//修改指数昨日收盘价

	m_CurStock2.PrepareData(CStock::dataK, CKData::ktypeDay, TRUE);
	CKData& kdata = m_CurStock2.GetKData(CKData::ktypeDay);

	//根据日期获取索引号
	int nIndexCurrent = kdata.GetIndexByDate(date);

	//取前一日索引
	nIndexCurrent -= 1;

	if (nIndexCurrent < 0)
		nIndexCurrent = 0;

	KDATA	kd;
	memset(&kd, 0, sizeof(kd));

	//根据索引获取日K线数据,再获取收盘价
	kd.m_fClose = kdata.ElementAt(nIndexCurrent).m_fClose;

	info.m_fLast = kd.m_fClose;

	//设置这只股票的昨日收盘价信息
	m_CurStock2.SetStockInfo(&info);


	// 从磁盘读取历史分笔数据
	m_CurStock2.PrepareData(CStock::dataReport, CKData::ktypeDay, TRUE);
	m_CurStock2.PrepareData(CStock::dataMinute, CKData::ktypeDay, TRUE);


	// Draw Price 
	//CStockInfo& info = m_CurStock2.GetStockInfo();
	CMinute& aMinute = m_CurStock2.GetMinute();
	DWORD	secNow = CSPTime::GetCurrentTime().ToStockTimeSecOrder();//获取当前时间
	DWORD	secStep = 60;

	//x Axis
	int	ptr = 0;
	int	xPos = m_rectPrice.left;

	int	yPosMid = m_rectPrice.top + m_rectPrice.Height() / 2;
	int yPos = yPosMid;

	int	yPosLast = yPos; //y 指向中间线
	//画线颜色
	COLORREF	clrLine5 = AfxGetProfile().GetColor(CColorClass::clrCW);

	DWORD	dwSeconds = CSPTime::GetTradeSecondsOfOneDay();
	//以60秒为步进,开始画指数分时线
	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_CurStock2.GetStockInfo().m_fLast;//昨日收盘价

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

			// Draw Price Line
			CPen	pen1(PS_SOLID, 1, clrLine5);
			CPen* pOldPen = pDC->SelectObject(&pen1);
			pDC->MoveTo(xPos, yPos);

			//根据价格算Y抽
			double	dPriceNew = aMinute[ptr].m_fNew;
			//计算指数涨幅
			double  indexDiffPercent = (dPriceNew - m_CurStock2.GetStockInfo().m_fLast) / m_CurStock2.GetStockInfo().m_fLast;

			//换算成股票价格
			dPriceNew = m_CurStock.GetStockInfo().m_fLast * (1 + indexDiffPercent);

			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);
			}

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


	}




}