?? stock.cpp
字號:
#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結(jié)構(gòu)的指針,此時設(shè)定空間是0
memset(&m_Data,0,sizeof(m_Data));//&m_Data是指向m_Data結(jié)構(gòu)的指針,此時設(shè)定空間是0
size=ReadDayLine(); //讀入分時價格數(shù)據(jù),及是否正常退出
ksize=ReadKLine(); //讀入K線價格數(shù)據(jù)
asize=ReadKAmount(); //讀入K線成交金額數(shù)據(jù)
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)//是回調(diào)函數(shù)自定義消息的實現(xiàn)
{
(*m_EnableMessage)(0);//停止發(fā)送數(shù)據(jù),
long liMsgCounter = (*m_ReceiveInfo)();//返回:接收到的包數(shù)
for(int i = 0; i < liMsgCounter; i++)
{
(*m_DataAcquisition)(&m_Data, i);
ExpandPackage(m_Data);// 拆包并將數(shù)據(jù)存入相應(yīng)的結(jié)構(gòu)體中
SendMessage(WM_DrawCommon,NULL,NULL);
StoreDayLine();
if( m>=240 ) //一天結(jié)束,存K線數(shù)據(jù)
{
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); //允許發(fā)送數(shù)據(jù)
return 1;
}
void CMyFrame::ExpandPackage(MAINSTRUCT Data)//---------------拆包
{
if(Data.Type == 0x10||Data.Type == 0x11||Data.Type == 0x20||Data.Type == 0x21)
{
//將Data的數(shù)據(jù)存儲在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;
}
//////////////////////////////////////////////////////////////////////////
//轉(zhuǎn)換函數(shù)
//
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:
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -