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

📄 stock.cpp

📁 MFC 写的股票软件。含注释
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include <afxwin.h>
#include <Windows.h>
#include <afxtempl.h>
#include "Stock.h"
#define WM_IRQSTOCK (WM_USER+1000)
#define WM_DrawDayLine  0x0400 + 100
#define WM_DrawKLine  0x0400 + 101
#define WM_DrawCommon  0x0400 + 102

CMyApp theApp;

BOOL CMyApp::InitInstance()      
{
	m_pMainWnd = new CMyFrame;
    m_pMainWnd->ShowWindow(m_nCmdShow);
    m_pMainWnd->UpdateWindow();
	return TRUE;
}

CMyApp::CMyApp()
{
}

BEGIN_MESSAGE_MAP(CMyFrame, CWnd)
	ON_WM_CREATE()                      
	ON_WM_PAINT()
	ON_WM_KEYDOWN()
	ON_WM_KEYUP()
	ON_WM_LBUTTONDOWN()
	ON_MESSAGE(WM_IRQSTOCK, OnIRQSTOCK)
	ON_MESSAGE(WM_DrawDayLine, OnDrawDayLine)
	ON_MESSAGE(WM_DrawKLine, OnDrawKLine)
	ON_MESSAGE(WM_DrawCommon, OnDrawCommon)
	ON_COMMAND(4001,OnDayLine)
	ON_COMMAND(4002,OnKLine)
END_MESSAGE_MAP()

CMyFrame::CMyFrame()
{
	ReStart();
	bReStart = FALSE;	//默认是今天新打开的
	bKLine = FALSE;		//默认是分时线 
	DWORD size=0,ksize=0,asize=0;
	KBegine = 0;
	bCtrl = FALSE;
	KAmountMax = 1;
	
    CString strWndClass=AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW,
		AfxGetApp()->LoadStandardCursor(IDC_ARROW),
		(HBRUSH) GetStockObject (BLACK_BRUSH),
		AfxGetApp()->LoadStandardIcon(IDI_WINLOGO));
	
	CreateEx(0, strWndClass,_T("MFC股市软件"),
		WS_OVERLAPPED|WS_SYSMENU|WS_CAPTION|WS_MINIMIZEBOX,
		CW_USEDEFAULT,CW_USEDEFAULT,900,620,
		NULL,NULL);
	CMenu menuMain;
	menuMain.CreateMenu();
    menuMain.AppendMenu(MF_STRING,4001,"* 分时线 *");
	menuMain.AppendMenu(MF_POPUP,4002,"* K线 *");   //(UINT)menuPopup.Detach()
	SetMenu(&menuMain);
	menuMain.Detach();
	
	memset(&m_Stock,0, sizeof(m_Stock));//&m_Stock是指向m_Stock结构的指针,此时设定空间是0
	memset(&m_Data,0,sizeof(m_Data));//&m_Data是指向m_Data结构的指针,此时设定空间是0
	
	
	size=ReadDayLine();		//读入分时价格数据,及是否正常退出
	ksize=ReadKLine();		//读入K线价格数据
	asize=ReadKAmount();	//读入K线成交金额数据

	ExchangeK();

	if (size!=0)
	{
		Invalidate();
	}
}

CMyFrame::~CMyFrame()
{
	
}

void CMyFrame::ReStart()	//新一天开始
{
	m=0;
	M=0;
	VolMax=1;
	VolLast=0;
	//VolLastDay=m_Stock.fVolume;		//昨天总成交量
	//KAmountLastDay=m_Stock.fAmount;	//昨日成交金额
	bNExit=FALSE;					//非正常退出

	KHighMax = 0;
	KLowMin = 100;
	KDay  = 60;
	KM = KHighMax - KLowMin;
}

LRESULT CMyFrame::OnIRQSTOCK(WPARAM wParam,LPARAM lParam)//是回调函数自定义消息的实现
{
	(*m_EnableMessage)(0);//停止发送数据,
	long liMsgCounter = (*m_ReceiveInfo)();//返回:接收到的包数
	
	for(int i = 0; i < liMsgCounter; i++)
	{
		(*m_DataAcquisition)(&m_Data, i); 
		ExpandPackage(m_Data);//	拆包并将数据存入相应的结构体中
		SendMessage(WM_DrawCommon,NULL,NULL);

		StoreDayLine();

		if( m>=240 )	//一天结束,存K线数据
		{
			KLine thisKLine;
			thisKLine.fOpen=m_Stock.fOpen;
			thisKLine.fClose=m_Stock.fNew;
			thisKLine.fHigh=m_Stock.fHigh;
			thisKLine.fLow=m_Stock.fLow;
			KLineArray.Add(thisKLine);
			StoreKLine();

			KAmount thisKAmout;
			thisKAmout.Amount = m_Stock.fAmount;
			KAmountArray.Add(thisKAmout);
			StoreKAmount();
			
			bReStart=TRUE;	//新一天开始
			ReStart();
			Invalidate();
		}

		if(bKLine == FALSE)
		SendMessage(WM_DrawDayLine,NULL,NULL); 		
	}
	
	(*m_EnableMessage)(1);		//允许发送数据
	
	return 1;
}

void CMyFrame::ExpandPackage(MAINSTRUCT Data)//---------------拆包
{
	if(Data.Type == 0x10||Data.Type == 0x11||Data.Type == 0x20||Data.Type == 0x21)
	{   
		//将Data的数据存储在m_Stock中
		sprintf(m_Stock.StockCode,"%.8s",Data.AllStruct.IndexAndStock.Code);//股票 代码                      
		sprintf(m_Stock.StockName,"%.10s", Data.AllStruct.IndexAndStock.Name);//股票名称
		m_Stock.fClose = (float)(Data.AllStruct.IndexAndStock.Close)/1000;//收盘价 
		m_Stock.fOpen = (float)(Data.AllStruct.IndexAndStock.Open)/1000;//开盘价
		m_Stock.fNew = (float)(Data.AllStruct.IndexAndStock.New)/1000;// 最新价
		m_Stock.fHigh  = (float)(Data.AllStruct.IndexAndStock.High)/1000;//最高价
		m_Stock.fLow = (float)(Data.AllStruct.IndexAndStock.Low)/1000;//最低价
		m_Stock.fVolume = (Data.AllStruct.IndexAndStock.Volume);// 总成交量  单位:股
		m_Stock.fAmount = (Data.AllStruct.IndexAndStock.Amount)/1000;;//	成交金额  单位:元

		m_Stock.Pbuy1 = (Data.AllStruct.IndexAndStock.Pbuy1);//买一
		m_Stock.Pbuy2 = (Data.AllStruct.IndexAndStock.Pbuy2);//买二
		m_Stock.Pbuy3 = (Data.AllStruct.IndexAndStock.Pbuy3);//买三
		m_Stock.Vbuy1 = (Data.AllStruct.IndexAndStock.Vbuy1);//买一
		m_Stock.Vbuy2 = (Data.AllStruct.IndexAndStock.Vbuy2);//买二
		m_Stock.Vbuy3 = (Data.AllStruct.IndexAndStock.Vbuy3);//买三
		
		m_Stock.Psell1 = (Data.AllStruct.IndexAndStock.Psell1);//卖一
		m_Stock.Psell2 = (Data.AllStruct.IndexAndStock.Psell2);//卖二
		m_Stock.Psell3 = (Data.AllStruct.IndexAndStock.Psell3);//卖三
		m_Stock.Vsell1 = (Data.AllStruct.IndexAndStock.Vsell1);//卖一
		m_Stock.Vsell2 = (Data.AllStruct.IndexAndStock.Vsell2);//卖二
		m_Stock.Vsell3 = (Data.AllStruct.IndexAndStock.Vsell3);//卖三
		
		M = ((m_Stock.fHigh-m_Stock.fClose) > (m_Stock.fClose-m_Stock.fLow)) ? (m_Stock.fHigh-m_Stock.fClose) * 1.1 : (m_Stock.fClose-m_Stock.fLow) * 1.1;
		if ( M < (m_Stock.fClose*0.07) )
		{
			M = m_Stock.fClose*0.07;	
		}
		else
		{
			Invalidate();
		}
		
		Price[m]=m_Stock.fNew;
		
		//if(!bReStart)//不是重新开始
		//{
			if (m==0)
			{
				VolThis = m_Stock.fVolume;
				Vol[m] = VolThis;
				VolMax = VolThis;
			}
			else
			{
				VolThis=m_Stock.fVolume-VolLast;
				Vol[m] = VolThis;
				if( VolThis>VolMax ) 
				{
					VolMax = VolThis;
				}
			}				
			VolLast = m_Stock.fVolume;
		//}
		/*else
		{
			if (m==0)
			{
				VolThis = m_Stock.fVolume-VolLastDay;
				Vol[m] = VolThis;
				VolMax = VolThis;
			}
			else
			{
				VolThis=m_Stock.fVolume-VolLast-VolLastDay;
				Vol[m] = VolThis;
				if( VolThis>VolMax ) 
				{
					VolMax = VolThis;
				}
			}				
			VolLast = m_Stock.fVolume-VolLastDay;
		}*/

		m++;
		
		Exchange();
		ExchangeA(m);
		ExchangeV();
	}
}

void CMyFrame::StoreDayLine()
{
	int i=0;
	try
	{	
		CFile file(_T("dayline.txt"), CFile::modeReadWrite);
		CArchive ar(&file,CArchive::store);
		ar<<bNExit<<m<<M<<VolMax<<m_Stock.fClose;
		for ( i=0; i<m; i++ )
		{
			ar<<Price[i];
			ar<<Vol[i];	
		}		
	}
	catch(CFileException* e)
	{
		e->ReportError();
		e->Delete();
	}
}

DWORD CMyFrame::ReadDayLine()	//返回文件大小
{
	int i=0;
	DWORD size=0;
	try
	{ 
		CFile file(_T("dayline.txt"), CFile::modeReadWrite);
		CArchive ar(&file,CArchive::load);
		
		size = file.GetLength();
		if (size==0)
		{
			return 0;
		}
		
		ar>>bNExit>>m>>M>>VolMax>>m_Stock.fClose;
		for( i=0; i<m; i++ )
		{
			ar>>Price[i];
			ar>>Vol[i];
		}
		
		for( i=0; i<m; i++ )
		{
			ExchangeA(i+1); 
		}
		
		return size;
	}
	catch(CFileException* e)
	{
		e->ReportError();
		e->Delete();
	}
	return size;
}

void CMyFrame::StoreKLine()
{
	int i=0;
	try
	{ 
		CFile file(_T("kline.txt"), CFile::modeReadWrite);
		CArchive ar(&file,CArchive::store);
		for ( i=0; i<KLineArray.GetSize(); i++ )
		{
			ar<<KLineArray[i].fOpen<<KLineArray[i].fClose<<KLineArray[i].fHigh<<KLineArray[i].fLow;
		}
		
	}
	catch(CFileException* e)
	{
		e->ReportError();
		e->Delete();
	}
}

DWORD CMyFrame::ReadKLine()
{
	DWORD size=0;
	int i=0;
	float myArray[1][4];
	KLine aKLine;
	try
	{ 
		CFile file(_T("kline.txt"), CFile::modeReadWrite);
		CArchive ar(&file,CArchive::load);
		
		size=file.GetLength();
		if (size==0)
		{
			return 0;
		}
		int n=size/(4*4);	
		for ( i=0; i<n; i++ )
		{
			ar>>myArray[0][0]>>myArray[0][1]>>myArray[0][2]>>myArray[0][3];
			aKLine.fOpen = myArray[0][0];
			aKLine.fClose = myArray[0][1];
			aKLine.fHigh = myArray[0][2];
			aKLine.fLow = myArray[0][3];
			KLineArray.SetAtGrow(i,aKLine);
		}
		
		return size;		
	}
	catch(CFileException* e)
	{
		e->ReportError();
		e->Delete();
	}
	return size;
}

void CMyFrame::StoreKAmount()
{
	int i=0;
	try
	{ 
		CFile file(_T("kamount.txt"), CFile::modeReadWrite);
		CArchive ar(&file,CArchive::store);
		for ( i=0; i<KAmountArray.GetSize(); i++ )
		{
			ar<<KAmountArray[i].Amount;
		}
	}
	catch(CFileException* e)
	{
		e->ReportError();
		e->Delete();
	}
}

DWORD CMyFrame::ReadKAmount()
{
	DWORD size=0;
	int i=0;
	float Amount=0;
	KAmount aKAmount;
	try
	{ 
		CFile file(_T("kamount.txt"), CFile::modeReadWrite);
		CArchive ar(&file,CArchive::load);
		
		size=file.GetLength();
		if (size==0)
		{
			return 0;
		}
		int n=size/4;	
		for ( i=0; i<n; i++ )
		{
			ar>>Amount;
			aKAmount.Amount=Amount;
			KAmountArray.SetAtGrow(i,aKAmount);
		}
		
		return size;		
	}
	catch(CFileException* e)
	{
		e->ReportError();
		e->Delete();
	}
	return size;
}

//////////////////////////////////////////////////////////////////////////
//转换函数
//
void CMyFrame::Exchange()
{
	int x=0,i=0;
	
	for ( i=0; i<m; i++ )
	{
		x = (int)(150 * ( Price[i] - m_Stock.fClose ) / M );	
		Point[i][0]=80+i*2;
		Point[i][1]=40+150-x;	
	}	
}

void CMyFrame::ExchangeA(int m)
{
	int x=0,i=0;
	float total1;
	float total2;
	float aver=0;
	
    total1=0;
	total2=0;
	
	for (i=0;i<m;i++)
	{	   
		total1=total1+Price[i]*Vol[i];
		total2=total2+Vol[i];
	}
	
	aver=total1/total2; 
	
	x = (int)(150 * ( aver - m_Stock.fClose ) / M );	
	PointAver[m-1][0]=80+i*2;
	PointAver[m-1][1]=40+150-x;
}

void CMyFrame::ExchangeV()
{
	int x=0,i=0;
	
	for ( i=0; i<m; i++ )
	{
		x = (int)(150 * ( Vol[i] ) / VolMax );	
		VPoint[i][0]=80+i*2;
		VPoint[i][1]=40+150*3-x;	
	}	
}

void CMyFrame::ExchangeK()
{
	int x=0,i=0;
	float a=0,b=0,lw=0;
	CRect rect;
	POINT client;
	POINT high,low,open,close;
	KPoint aKPoint;

	GetClientRect(&rect);
	client.x = rect.Width();
	client.y = rect.Height();

	int n = KLineArray.GetSize();
	for ( i=0; i<n; i++ )
	{
		if (KLineArray[i].fHigh > KHighMax)
		{
			KHighMax = KLineArray[i].fHigh;
		}
		if (KLineArray[i].fLow < KLowMin)
		{
			KLowMin = KLineArray[i].fLow;
		}
	}
	KM = KHighMax - KLowMin;

	a = (client.y-120)/2 -20;//垂直高度
	b = client.x - 220 - 80;//水平高度

	lw = b/(KDay*5);//每个K线中每个小格的水平宽度

	for ( i=0; i<n; i++ )
	{
		high.x = 80 + (i*5+3)*lw ;
		high.y = 70+a-(KLineArray[i].fHigh - KLowMin)*a/KM;
		
		low.x = 80 + (i*5+3)*lw ;
		low.y = 70+a-(KLineArray[i].fLow - KLowMin)*a/KM;

		open.x = 80 + (i*5+1)*lw ;
		open.y = 70+a-(KLineArray[i].fOpen - KLowMin)*a/KM;
		
		close.x = 80 + (i*5+5)*lw ;
		close.y = 70+a-(KLineArray[i].fClose - KLowMin)*a/KM;

		aKPoint.high = high;
		aKPoint.low = low;
		aKPoint.open = open;
		aKPoint.close = close;

		KPointArray.SetAtGrow(i,aKPoint);
	}
}

void CMyFrame::ExchangeKAmount()
{
	int		i=0;
	float	c=0,b=0,lw=0;
	CRect	rect;
	POINT	client;
	float	high;
	POINT	top,bottom;
	KAmountPoint aKAmountPoint;
	
	GetClientRect(&rect);
	client.x = rect.Width();
	client.y = rect.Height();
	
	c = (client.y-120)/4  -20;	//垂直高度
	b = client.x - 220 - 80;	//水平宽度
	
	lw = b/(KDay*5);//每个K线中每个小格的水平宽度
	
	int n = KAmountArray.GetSize();
	for ( i=0; i<n; i++ )
	{
		float temp = KAmountArray[i].Amount;
		if (KAmountArray[i].Amount > KAmountMax)
		{
			KAmountMax = KAmountArray[i].Amount;
		}
	}
	
	for ( i=0; i<n; i++ )
	{
		float temp1 = KAmountArray[i].Amount;
		top.x = 80 + (i*5+1)*lw ;
		top.y = 50+(c+20)*3-KAmountArray[i].Amount*c/KAmountMax;
		
		bottom.x = 80 + (i*5+5)*lw ;
		bottom.y = 50+(c+20)*3;
		
		aKAmountPoint.top = top;
		aKAmountPoint.bottom = bottom;
		
		KAmountPointArray.SetAtGrow(i,aKAmountPoint);
	}
}

void CMyFrame::OnKeyDown( UINT nChar, UINT nRepCnt, UINT nFlags )
{
	switch(nChar)
	{
	case VK_F11:
		M=M*0.5;
		Exchange();
		Invalidate();
		break;
	case VK_F12:
		M=M*1.5;
		Exchange();
		Invalidate();
		break;
	case VK_F5:
		bKLine = (bKLine == FALSE) ? TRUE:FALSE;
		Invalidate();
		break;
	case VK_RIGHT:
		if (bCtrl)
		{
			KBegine+=5;
		}
		else
		{
			KBegine++;
		}
		if (bKLine==TRUE)
		{
			Invalidate();
		}
		break;
	case VK_LEFT:

⌨️ 快捷键说明

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