📄 singleview.cpp
字号:
// SingleView.cpp : implementation file
//
#include "stdafx.h"
#include "MyStock.h"
#include "SingleView.h"
#include "MyStockDoc.h"
#include "math.h"
#include "fstream.h" //文件操作
#include "MainFrm.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CSingleView
IMPLEMENT_DYNCREATE(CSingleView, CView)
CSingleView::CSingleView()
{
jan=0;
Save_am=0;
m_x=0;//K线X坐标
pp=0;
an=0;
m_KWidth=4;
zx=m_KWidth/2/2; //1/2 or 1/4?
m_paintnum=3;
m_Line1Color=RGB(0,32,255);
m_Line2Color=RGB(22,171,18);
m_Line3Color=RGB(255,0,255);
// TODO: add construction code here
}
CSingleView::~CSingleView()
{
}
BEGIN_MESSAGE_MAP(CSingleView, CView)
//{{AFX_MSG_MAP(CSingleView)
ON_WM_DESTROY()
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_COMMAND(ID_KLINE, OnKline)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CSingleView drawing
void CSingleView::OnDraw(CDC* pDC)
{
CMyStockDoc* pDoc =(CMyStockDoc*)GetDocument();
CString str=pDoc->m_FileName;
BOOL iskline=((CMyStockApp*)AfxGetApp())->m_bIsKLine;
if(iskline)
{
MyKLine(pDC,3); //myline2
KLine(); //dataradey
KDJ(9);
MACD(26,12,9);
}
else
{
Myline(pDC);
}
}
/////////////////////////////////////////////////////////////////////////////
// CSingleView diagnostics
#ifdef _DEBUG
void CSingleView::AssertValid() const
{
CView::AssertValid();
}
void CSingleView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CSingleView message handlers
void CSingleView::OnDestroy()
{
CView::OnDestroy();
CMainFrame::bChilcCreated=FALSE;
}
void CSingleView::Myline(CDC *pDC)
{
CMyStockDoc* pDoc =(CMyStockDoc*)GetDocument();
pDC->TextOut(5,2,pDoc->m_FileName);
RECT rect;
GetClientRect(&rect);
int bj=(rect.right/4)*3;
int aa=(rect.bottom-40)/25;
int aa1=(rect.bottom-40)%25;
if(25-aa1<5)
{
aa+=1;
}
int bb=(rect.right/4)*3;
pDC->MoveTo(50,(aa/3)*2*25+21);
pDC->LineTo(bb-50,(aa/3)*2*25+21);//成交量和走势线的分界
pDC->MoveTo(50,(aa/3)*25+21);
pDC->LineTo(bb-50,(aa/3)*25+21);//昨收盘线
pDC->MoveTo(bb,0);
pDC->LineTo(bb,rect.bottom);
pDC->MoveTo(bb-50,0);
pDC->LineTo(bb-50,rect.bottom);
for(int i=0;i<=aa;i++)
{
pDC->MoveTo(50,25*i+20);
pDC->LineTo(bb-50,25*i+20);
}
int cc=(bb-100)/4;
for(int j=0;j<4;j++)
{
pDC->MoveTo(50+cc*j,20);
pDC->LineTo(50+cc*j,20+25*aa);
}
CPen pen(PS_DOT,1,RGB(128,128,128));
CPen* pPen=pDC->SelectObject(&pen);
int mm=(bb-100)/8;
for(int d=0;d<4;d++)
{
pDC->MoveTo(50+mm*(2*d+1),20);
pDC->LineTo(50+mm*(2*d+1),20+25*aa);
}
pDC->SelectObject(pPen);
CString str=pDoc->m_FileName;
pDC->TextOut(bj+10,2,str+" 股票名称(序号)");
pDC->MoveTo(bj,21);
pDC->LineTo(rect.right,21);
pDC->TextOut(bj+3,22,"委比 委差");
pDC->MoveTo(bj,41);
pDC->LineTo(rect.right,41);
pDC->TextOut(bj+3,42,"卖四");
pDC->TextOut(bj+3,62,"卖三");
pDC->TextOut(bj+3,82,"卖二");
pDC->TextOut(bj+3,102,"卖一");
pDC->MoveTo(bj,121);
pDC->LineTo(rect.right,121);
pDC->TextOut(bj+3,122,"买一");
pDC->TextOut(bj+3,142,"买二");
pDC->TextOut(bj+3,162,"买三");
pDC->TextOut(bj+3,182,"买四");
pDC->MoveTo(bj,201);
pDC->LineTo(rect.right,201);
pDC->TextOut(bj+3,202,"最新");
pDC->TextOut(bj+3,222,"涨跌");
pDC->TextOut(bj+3,242,"幅度");
pDC->TextOut(bj+3,262,"总手");
pDC->TextOut(bj+3,282,"现手");
pDC->TextOut(bj+3,302,"金额");
pDC->MoveTo(bj,321);
pDC->LineTo(rect.right,321);
//m_edit->SetWindowPos(&wndBottom,bj+1,322,rect.right,rect.bottom,SWP_DRAWFRAME);
//m_edit->SetWindowText("amcbefg")
}
int CSingleView::MyKLine(CDC *pDC, int Num)
{
RECT rect;
GetClientRect(&rect);
int bj=(rect.right/4)*3;
if(pp==0)
{
SetPointY(Num);
}
CPen mypen(PS_SOLID,1,RGB(128,128,128));
CPen* myoldpen=pDC->SelectObject(&mypen);
for(int k=0;k<=Num-1;k++)
{
pDC->MoveTo(1,m_pointY[k]);
pDC->LineTo(bj,m_pointY[k]);
char str[4];
gcvt(k,2,str);
pDC->SetTextColor(RGB(255,0,255));
pDC->TextOut(100,m_pointY[k]-18,str);
}
pDC->SetTextColor(RGB(0,0,0));
pDC->MoveTo(bj,0);
pDC->LineTo(bj,rect.bottom);
pDC->MoveTo(bj-50,0);
pDC->LineTo(bj-50,rect.bottom);
CMyStockDoc* pDoc = (CMyStockDoc*)GetDocument();
CString str=pDoc->m_FileName;
pDC->TextOut(bj+10,2,str+" 股票名称(序号)");
pDC->MoveTo(bj,21);
pDC->LineTo(rect.right,21);
pDC->TextOut(bj+3,22,"委比"/* 委差"*/);
pDC->MoveTo(bj,41);
pDC->LineTo(rect.right,41);
pDC->TextOut(bj+3,42,"卖四");
pDC->TextOut(bj+3,62,"卖三");
pDC->TextOut(bj+3,82,"卖二");
pDC->TextOut(bj+3,102,"卖一");
pDC->MoveTo(bj,121);
pDC->LineTo(rect.right,121);
pDC->TextOut(bj+3,122,"买一");
pDC->TextOut(bj+3,142,"买二");
pDC->TextOut(bj+3,162,"买三");
pDC->TextOut(bj+3,182,"买四");
pDC->MoveTo(bj,201);
pDC->LineTo(rect.right,201);
pDC->TextOut(bj+3,202,"最新");
pDC->TextOut(bj+3,222,"涨跌");
pDC->TextOut(bj+3,242,"幅度");
pDC->TextOut(bj+3,262,"总手");
pDC->TextOut(bj+3,282,"现手");
pDC->TextOut(bj+3,302,"金额");
pDC->MoveTo(bj,321);
pDC->LineTo(rect.right,321);
pDC->SelectObject(myoldpen);
return 0;
}
void CSingleView::SetPointY(int Num)
{
RECT rect;
GetClientRect(&rect);
for(int i=0;i<Num;i++)
{
m_pointY[i]=(rect.bottom/(Num+5))*(6+i);
}
m_pointY[Num-1]=rect.bottom;
}
void CSingleView::KLine()
{
CDC* pDC=GetDC();
RECT rect;
GetClientRect(&rect);
int mmx=(rect.right/4)*3;
m_days=(mmx-50)/(m_KWidth+1);//得到画面的周期数
Save_am=m_days;
CMyStockDoc* pDoc=(CMyStockDoc*)GetDocument();
CString filename=pDoc->m_FileName;
filename=".\\DAY\\"+filename;
filename+=".day";
ifstream infile(filename,ios::binary);
infile.seekg(0,ios::end);
int fsize=infile.tellg();
if(fsize==0)
return;
pDC->TextOut(5,2,pDoc->m_FileName);
an=fsize/sizeof(RCV_HISTORY_STRUCTEx);//得到股票数据的天数
//RCV_HISTORY_STRUCTEx* rx= new RCV_HISTORY_STRUCTEx[an];//定义数组
CArray<RCV_HISTORY_STRUCTEx,RCV_HISTORY_STRUCTEx> rx;
rx.SetSize(10,5);
infile.seekg(0,ios::beg);
for(int nn=0;nn<an;nn++)//给数祖赋值
{
infile.read((char*)&m_rx,sizeof(RCV_HISTORY_STRUCTEx));
rx.SetAtGrow(nn,m_rx);
}
infile.close();
//delete infile;//加上这一句,在debug版本中很容易出错
/////////////////////////////////////////////////////
int ppH=0;
int ppL=10000000;
if(an>=m_days && an-m_days-jan>=0)
{
for (int mm=an-m_days-jan;mm<an-jan;mm++)
{
if(ppH<=rx.GetAt(mm).m_fHigh)//rx[mm].m_fHigh)
{
ppH=rx.GetAt(mm).m_fHigh;//rx[mm].m_fHigh;//找到画面周期数的最高价
}
if(ppL>=rx.GetAt(mm).m_fLow)//rx[mm].m_fLow)
{
ppL=rx.GetAt(mm).m_fLow;//rx[mm].m_fLow;//找到画面周期数的最低价
}
}
}
else
{
for (int mm=0;mm<an;mm++)
{
if(ppH<=rx.GetAt(mm).m_fHigh)//rx[mm].m_fHigh)
{
ppH=rx.GetAt(mm).m_fHigh;//rx[mm].m_fHigh;//找到画面周期数的最高价
}
if(ppL>=rx.GetAt(mm).m_fLow)//rx[mm].m_fLow)
{
ppL=rx.GetAt(mm).m_fLow;//rx[mm].m_fLow;//找到画面周期数的最低价
}
}
}
/////////////////////////////////////////////////
if(an>=m_days)
{
int aaa=0;
int bbb=0;
if(an-m_days-jan>=0)
{
aaa=an-jan;
bbb=an-m_days-jan;
}
else
{
aaa=m_days;
bbb=0;
}
for(int i=bbb;i<aaa;i++)
{
KLine2(pDC,rx.GetAt(i)/*rx[i]*/,ppH,ppL,m_pointY[0]);//画K线
}
}
else
{
for(int ii=0;ii<an;ii++)
{
KLine2(pDC,rx.GetAt(ii)/*rx[ii]*/,ppH,ppL,m_pointY[0]);//画K线
}
}
m_x=0;//K线X坐标回0(全局变量)
ReleaseDC(pDC); //Add in
//////////////////////////////////////////////////
//RCV_HISTORY_STRUCTEx m_my_rx=rx.GetAt(mm);
HisLine(1,&rx,5,ppL,ppH,RGB(0,32,255));//画5日均线
HisLine(2,&rx,10,ppL,ppH,RGB(22,171,18));//画10日均线
HisLine(3,&rx,20,ppL,ppH,RGB(255,0,255));//画20日均线
}
void CSingleView::KLine2(CDC* pDC /*mpDC*/,RCV_HISTORY_STRUCTEx m_rx,int H,int L,int Y)
{
// CDC* pDC=mpDC;
//使Y的值改变可以使图放大或缩小
int m=Y;
//pDC->TextOut(50,100,"时间");
//pDC->TextOut(50,200,"开盘");
//pDC->TextOut(50,300,"收盘");
//int nn=0;//计数器,记录此股数据有多少天
//char str[20];
//char str1[20];
//char str2[20];
time_t tt=m_rx.m_time;
int aa=m_rx.m_time;
int cc=m_rx.m_fOpen;
int bb=m_rx.m_fClose;
int ee=m_rx.m_fHigh;
int ff=m_rx.m_fLow;
int eee=ee/10;
int fff=ff/10;
int ccc=cc/10;
int bbb=bb/10;
double gc=H/10-L/10;
double n=(m-20)/gc;//得到单位价格的像素点数
//gcvt(aa,8,str);
//gcvt(bb,8,str1);
//gcvt(cc,8,str2);
//MessageBox(str);//测试时使用
//pDC->TextOut(100,100,str);
//pDC->TextOut(100,200,str1);
//pDC->TextOut(100,300,str2);
if(ccc==bbb)
{
bbb+=1;
}
if(bb>=cc)//收盘价大于开盘价阳线
{
// MessageBox("阳线");
CPen pen(PS_SOLID,1,RGB(255,0,0));
CPen* Oldpen=pDC->SelectObject(&pen);
int m1=m-ccc*n+L/10*n-10;//开
int m2=m-bbb*n+L/10*n-10;//收
int m3=(m-eee*n+L/10*n-10);//高
int m4=(m-fff*n+L/10*n-10);//低
if(m1==m2)
{
// MessageBox("相等");
m2=m1+1;
}
pDC->Rectangle(m_x,m1,m_x+m_KWidth-1,m2);
pDC->MoveTo(m_x+zx,m2);
pDC->LineTo(m_x+zx,m3);//画上影线
pDC->MoveTo(m_x+zx,m1);
pDC->LineTo(m_x+zx,m4);//画下影线
pDC->SelectObject(Oldpen);//恢复系统笔
}
else//阴线
{
CPen pen1(PS_SOLID,1,RGB(0,128,64));
CPen* Oldpen=pDC->SelectObject(&pen1);
CBrush* pbrush;
CBrush brush(RGB(0,128,64));
pbrush=pDC->SelectObject(&brush);
int m1=m-ccc*n+L/10*n-10;//开
int m2=m-bbb*n+L/10*n-10;//收
int m3=(m-eee*n+L/10*n-10);//高
int m4=(m-fff*n+L/10*n-10);//低
if(m1==m2)
{
m2=m1-1;
}
pDC->Rectangle(m_x,m1,m_x+m_KWidth-1,m2);
pDC->FillRect(CRect(m_x,m1,m_x+m_KWidth-1,m2),&brush);//填充实体
pDC->SelectObject(pbrush);
pDC->MoveTo(m_x+zx,m3);
pDC->LineTo(m_x+zx,m4);//一次完成上下影线
pDC->SelectObject(Oldpen);//恢复系统笔
}
m_x +=(m_KWidth+1);//K线移位
//pDC->SelectObject(Oldpen);//恢复系统笔
// ReleaseDC(pDC);
}
void CSingleView::HisLine(int number,CArray<RCV_HISTORY_STRUCTEx,RCV_HISTORY_STRUCTEx>/*RCV_HISTORY_STRUCTEx*/ *rx,int nPj,int ppL,int ppH,COLORREF crColor)
{
CDC* pDC=GetDC();
CPen pen(PS_SOLID,1,crColor);
CPen* oldpen=pDC->SelectObject(&pen);
int pj=0;
int xz=1;
RECT rect;
GetClientRect(&rect);
int mmx=(rect.right/4)*3;
int mx=(mmx-50)/(m_KWidth+1);//得到画面的周期数
//////////////////////////
int* bbbb=new int[an-(nPj-1)];//定义一个均线数组
for(int ii=0;ii<an-(nPj-1);ii++)
{
for(int jj=0;jj<nPj;jj++)
{
pj=pj+rx->GetAt(ii+jj).m_fClose;
}
bbbb[ii]=pj/nPj;//给均线数组赋值
pj=0;
}
double bb=bbbb[an-nPj];
double aaa=bbbb[an-nPj-1];
CString str0;
CString str;
str0.Format("%d",nPj);
str0="ma"+str0;
str0=str0+":";
str.Format("%6.2f",bbbb[an-nPj-1]/1000.00);
pDC->TextOut(number*90,1,str0+str);
double km1=ppH/10-ppL/10;
double km2=(m_pointY[0]-20)/km1;//得到单位价格的像素点数
if(an-mx>=nPj-1 && an-(nPj-1)-mx-jan>=0)//总周期数-画面周期数>=(均线周期-1),从第一个画
{
int amb1=(bbbb[an-(nPj-1)-mx-jan]/10*km2);
int amb2=ppL/10*km2;
int amb0=m_pointY[0]-amb1+amb2-10;
pDC->MoveTo(zx,amb0);
int poi=zx+m_KWidth+1;
for(int kk=0;kk<mx-1;kk++)//因为有moveto一次,所以这里mx-1
{
int a1=(bbbb[an-(nPj-1)-mx+1+kk-jan]/10*km2);
int a2=ppL/10*km2;
int a3=m_pointY[0]-a1+a2-10;
pDC->LineTo(poi,a3);
poi+=(m_KWidth+1);
}
delete bbbb;
}
else if(an-mx>=0 && an-mx<(nPj-1))//从公式算起点
{
int amb1=(bbbb[an-(nPj-1)-mx+(nPj-(an-mx))-jan]/10*km2);//(5-(an-mx))是均线周期-总周期和画面周期的差
int amb2=ppL/10*km2;
int amb0=m_pointY[0]-amb1+amb2-10;
pDC->MoveTo(zx+(m_KWidth+1)*((nPj-1)-(an-mx)-jan),amb0);
int poi=zx+(m_KWidth+1)*((nPj-1)-(an-mx)+1);//4-(an-mx)是均线周期减1再减总周期和画面周期的差
for(int kk=0;kk<mx-((nPj-1)-(an-mx))-1-1-jan;kk++)//mx-4是画面周期数-均线周期数有去掉moveto一次
{
int a1=(bbbb[an-(nPj-1)-mx+(nPj-(an-mx)-jan)+1+kk]/10*km2);
int a2=ppL/10*km2;
int a3=m_pointY[0]-a1+a2-10;
pDC->LineTo(poi+(m_KWidth+1),a3);
poi+=(m_KWidth+1);
}
delete bbbb;
}
else //从第五个开始
{
//jan=0;
int amb1=(bbbb[0]/10*km2);
int amb2=ppL/10*km2;
int amb0=m_pointY[0]-amb1+amb2-10;
pDC->MoveTo(zx+(m_KWidth+1)*(nPj),amb0);//4是均线周期数减1
int poi=zx+(m_KWidth+1)*(nPj-1)+(m_KWidth+1);
for(int kk=0;kk<an-(nPj-1)-jan;kk++)//有去掉moveto一次
{
int a1=(bbbb[kk]/10*km2);
int a2=ppL/10*km2;
int a3=m_pointY[0]-a1+a2-10;
pDC->LineTo(poi,a3);
poi+=(m_KWidth+1);
}
delete bbbb;
}
pDC->SelectObject(oldpen);
ReleaseDC(pDC);
}
void CSingleView::MACD(int L, int S, int V)
{
CDC* pDC=GetDC();
CString s1,s2,s3;
s1.Format("%d",L);
s2.Format("%d",S);
s3.Format("%d",V);
pDC->TextOut(1,m_pointY[1]+1,"MACD("+s1+","+s2+","+s3+")");
RECT rect;
GetClientRect(&rect);
int bj=(rect.right)/4*3;
m_days=(bj-50)/(m_KWidth+1);//画面周期
double pH=-99999999999999.99;
double pL=999999999999999.99;
CMyStockDoc* pDoc=(CMyStockDoc*)GetDocument();
CString filename=".\\DAY\\"+pDoc->m_FileName;
filename+=".day";
an=0;
double LongV=0.00;//长周期移动平均
double shortV=0.00;//短周期移动平均
ifstream file(filename,ios::binary);
file.seekg(0,ios::end);
int filesize=file.tellg();
an=filesize/sizeof(tagRCV_HISTORY_STRUCTEx);//得到数据天数
tagRCV_HISTORY_STRUCTEx* rx=new tagRCV_HISTORY_STRUCTEx[an];
file.seekg(0,ios::beg);
for(int m=0;m<an;m++)
{
file.read((char*)&rx[m],sizeof(tagRCV_HISTORY_STRUCTEx));
}
file.close;
int m3=rx[an-1].m_fClose;//最后一组有效
time_t t4=rx[an].m_time;//无效
//上面完成读数据
///////////////////////////////////
//下面给dif赋值:
double* shortv=new double[an];
double sum=0.00;
for(int i=0;i<an;i++)
{
if(i==0) shortv[i]=rx[i].m_fClose;
if(i<S && i>0)
{
for(int m=0;m<i;m++)
{
sum+=rx[i-m].m_fClose;
}
shortv[i]=sum/i;
sum=0.00;
}
if(i>=S)
{
for(int j=0;j<S;j++)
{
sum+=rx[i-j].m_fClose;
}
shortv[i]=sum/S;
sum=0.00;
}
}
double* longv=new double[an];
sum=0.00;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -