📄 chartma.cpp
字号:
// ChartMA.cpp: implementation of the CChartMA class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "LastProject.h"
#include "ChartMA.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CChartMA::CChartMA(CRecords *pRecords,CDirectFace * pFace,int P1,int P2,int P3)
{
int nWidth = pFace->m_rect.Width() - 60;
int nHeight = pFace->m_rect.Height() - 50;
int Zero = pFace->m_rect.Height() - 20;
double max = 0,min = 9999;
//*******************
CDatabase db;
CRecordset rs;
CString VAL,SQL;
SQL.Format("SELECT * FROM ExchangeType WHERE ETypeCode='%s' ",pRecords->ExCode);
try
{
db.OpenEx(DEFAULTDSN,CDatabase::noOdbcDialog);
rs.m_pDatabase = &db;
rs.Open(AFX_DB_USE_DEFAULT_TYPE,SQL);
//读取分析数据
while(!rs.IsEOF())
{
rs.GetFieldValue("ChineseName",VAL);
rs.MoveNext();
}
}catch(CDBException *e)
{
e->ReportError();
}
if(rs.IsOpen()) rs.Close();
if(db.IsOpen()) db.Close();
//*******************
//计算所画区域中的最大最小值
for(int i = pRecords->m_records.size()-1;i>=0;i--)
{
if(nWidth<8) break;
if(pRecords->m_records.at(i).max>max) max = pRecords->m_records.at(i).max;
if(pRecords->m_records.at(i).min<min) min = pRecords->m_records.at(i).min;
nWidth -= 10;
}
nWidth = pFace->m_rect.Width() - 60;
if(max==min)
{
max = min * 1.4;
min = min * 0.8;
}
double delta = max - min;
CString st;
st.Format ("nHeight=%d,nWidth=%d,delta=%4.4f",nHeight,nWidth,delta);
//AfxMessageBox(st);
CString fmt,str;
HDC layer = NULL;
pFace->m_lpLayer[1]->GetDC(&layer);
CDC *pDC = CDC::FromHandle(layer);
pDC->SetBkColor(RGB(0,0,0));
pDC->SetTextColor(RGB(0,170,0));
//刷清图层
pDC->SelectObject(::GetStockObject(BLACK_BRUSH));
pDC->SelectObject(&pFace->m_FramePen);
pDC->Rectangle(0,0,pFace->m_rect.Width(),pFace->m_rect.Height());
//画题头部分
pDC->SelectObject(&pFace->m_TitleFont);
//pDC->TextOut(5,8,CodeToName(pRecords->ExCode));
pDC->TextOut(5,8,VAL);
pDC->TextOut(100,8,pRecords->TableName);
pDC->SetTextColor(RGB(255,0,0));
str.Format("MA%3d",P1);
if(P1==0) pDC->TextOut(140,8,"MA");else pDC->TextOut(140,8,str);
pDC->SetTextColor(RGB(0,255,0));
str.Format("MA%3d",P2);
if(P1==0) pDC->TextOut(180,8,"MA");else pDC->TextOut(180,8,str);
pDC->SetTextColor(RGB(255,255,0));
str.Format("MA%3d",P3);
if(P1==0) pDC->TextOut(220,8,"MA");else pDC->TextOut(220,8,str);
pDC->SetTextColor(RGB(0,170,0));
//画坐标轴
pDC->SelectObject(&pFace->m_WhitePen);
pDC->MoveTo(3,Zero);
pDC->LineTo(nWidth+5,Zero);
pDC->LineTo(nWidth+5,30);
int lab = 0;
//画平行于X轴网格
pDC->SelectObject(&pFace->m_GrayPen);
pDC->SelectObject(&pFace->m_YFont);
if(pRecords->ExCode.Find("27")==-1) fmt = "%.4lf";else fmt = "%.2lf";
for(i = 0;i<=8;i++)
{
int y = (int)(nHeight * i / 8);
str.Format(fmt,min + delta * i / 8);
pDC->TextOut(nWidth+8,Zero-y-6,str);
if(i==0) continue;
pDC->MoveTo(3,Zero - y);
pDC->LineTo(nWidth+5,Zero - y);
}
//画柱状图
pDC->SelectObject(&pFace->m_XFont);
for(i = pRecords->m_records.size()-1;i>=0;i--)
{
if(nWidth<8) break;
double close = Zero - (pRecords->m_records.at(i).close-min) * nHeight / (delta);//Zero - (pRecords->m_records.at(i).close-min) * nHeight / (delta);
double open = Zero - (pRecords->m_records.at(i).open-min) * nHeight /(delta);
double top = Zero - (pRecords->m_records.at(i).max-min) * nHeight /(delta);
double bottom = Zero - (pRecords->m_records.at(i).min-min) * nHeight /(delta);
//st.Format ("pRecords->m_records.at(i).close-min=%4.4f,pRecords->m_records.at(i).open-min=%4.4f,pRecords->m_records.at(i).max-min=%4.4f,pRecords->m_records.at(i).min-min=%4.4f",pRecords->m_records.at(i).close-min,pRecords->m_records.at(i).open-min,pRecords->m_records.at(i).max-min,pRecords->m_records.at(i).min-min);
//AfxMessageBox(st);
st.Format("close=%4.4f,open =%4.4f,top=%4.4f,bottom=%4.4f",close,open,top,bottom);
//AfxMessageBox(st);
if(lab++%6 == 0)
{
if(pRecords->TableName=="五分钟" || pRecords->TableName == "三十分钟") fmt = "%d %H:%M";
if(pRecords->TableName=="小时") fmt = "%d日%H点";
if(pRecords->TableName=="日" || pRecords->TableName=="周") fmt = "%m月%d日";
if(pRecords->TableName=="月") fmt = "%y年%m月";
pDC->TextOut(nWidth-25,Zero+5,pRecords->m_records.at(i).DateTime.Format(fmt));
pDC->SelectObject(&pFace->m_GrayPen);
pDC->MoveTo(nWidth,Zero);
pDC->LineTo(nWidth,30);
}
//close与open的比较与坐标系有关,大的值其坐标值反而小
if(close<open)
{
pDC->SelectObject(&pFace->m_RedBarPen);
pDC->SelectObject(&pFace->m_RedBarBrush);
}else
if(close>open)
{
pDC->SelectObject(&pFace->m_GreenBarPen);
pDC->SelectObject(&pFace->m_GreenBarBrush);
}else
{
pDC->SelectObject(&pFace->m_YellowBarPen);
pDC->SelectObject(&pFace->m_YellowBarBrush);
pDC->MoveTo(nWidth-2,open);
pDC->LineTo(nWidth+3,close);
}
pDC->Rectangle(nWidth-2,open,nWidth+3,close);
pDC->MoveTo(nWidth,top);
pDC->LineTo(nWidth,bottom);
nWidth -= 10;
}
//画移动平均线1
nWidth = pFace->m_rect.Width() - 60;
if(P1>0)
{
pDC->SelectObject(&pFace->m_RedPen);
double avg1=0,avg2=0;
for(int i = pRecords->m_records.size()-1;i>pRecords->m_records.size()-1-P1;i--)
{
int n = i<0? 0:i;
avg1 += pRecords->m_records.at(n).close;
}
avg1 /= P1;
nWidth -= 10;
for(i = pRecords->m_records.size()-2;i>=0;i--)
{
if(nWidth<3) break;
for(int j = 0;j<P1;j++)
{
int n = i-1-j<0? 0:i-1-j;
avg2 += pRecords->m_records.at(n).close;
}
avg2 /= P1;
int y1 = Zero - (avg1-min) * nHeight / delta;
int y2 = Zero - (avg2-min) * nHeight / delta;
int x1 = nWidth+10;
int x2 = nWidth;
if(y1<30 && y2<30 || y1>Zero && y2>Zero)
{
avg1 = avg2;
avg2 = 0;
nWidth -= 10;
continue;
}
if(y2<30)
{
x2 = (y1-30) * 10 / (y2 - y1) + nWidth + 10;
y2 = 30;
}
if(y1<30)
{
x1 = (30-y2) * 10 / (y1 - y2) + nWidth;
y1 = 30;
}
if(y2>Zero)
{
x2 = (y1-Zero) * 10 / (y2 - y1) + nWidth + 10;
y2 = Zero;
}
if(y1>Zero)
{
x1 = (Zero-y2) * 10 / (y1 - y2) + nWidth;
y1 = Zero;
}
pDC->MoveTo(x1,y1);
pDC->LineTo(x2,y2);
avg1 = avg2;
avg2 = 0;
nWidth -= 10;
}
}
//画移动平均线2
nWidth = pFace->m_rect.Width() - 60;
if(P2>0)
{
pDC->SelectObject(&pFace->m_GreenPen);
double avg1=0,avg2=0;
for(int i = pRecords->m_records.size()-1;i>pRecords->m_records.size()-1-P2;i--)
{
int n = i<0? 0:i;
avg1 += pRecords->m_records.at(n).close;
}
avg1 /= P2;
nWidth -= 10;
for(i = pRecords->m_records.size()-2;i>=0;i--)
{
if(nWidth<3) break;
for(int j = 0;j<P2;j++)
{
int n = i-1-j<0? 0:i-1-j;
double s = pRecords->m_records.at(n).close;
CString t = pRecords->m_records.at(n).DateTime.Format("%y-%m-%d %H:%M:%S");
avg2 += pRecords->m_records.at(n).close;
}
avg2 /= P2;
int y1 = Zero - (avg1-min) * nHeight / delta;
int y2 = Zero - (avg2-min) * nHeight / delta;
int x1 = nWidth+10;
int x2 = nWidth;
if(y1<30 && y2<30 || y1>Zero && y2>Zero)
{
avg1 = avg2;
avg2 = 0;
nWidth -= 10;
continue;
}
if(y2<30)
{
x2 = (y1-30) * 10 / (y2 - y1) + nWidth + 10;
y2 = 30;
}
if(y1<30)
{
x1 = (30-y2) * 10 / (y1 - y2) + nWidth;
y1 = 30;
}
if(y2>Zero)
{
x2 = (y1-Zero) * 10 / (y2 - y1) + nWidth + 10;
y2 = Zero;
}
if(y1>Zero)
{
x1 = (Zero-y2) * 10 / (y1 - y2) + nWidth;
y1 = Zero;
}
pDC->MoveTo(x1,y1);
pDC->LineTo(x2,y2);
avg1 = avg2;
avg2 = 0;
nWidth -= 10;
}
}
//画移动平均线3
nWidth = pFace->m_rect.Width() - 60;
if(P3>0)
{
pDC->SelectObject(&pFace->m_YellowPen);
double avg1=0,avg2=0;
for(int i = pRecords->m_records.size()-1;i>pRecords->m_records.size()-1-P3;i--)
{
int n = i<0? 0:i;
avg1 += pRecords->m_records.at(n).close;
}
avg1 /= P3;
nWidth -= 10;
for(i = pRecords->m_records.size()-2;i>=0;i--)
{
if(nWidth<3) break;
for(int j = 0;j<P3;j++)
{
int n = i-1-j<0? 0:i-1-j;
avg2 += pRecords->m_records.at(n).close;
}
avg2 /= P3;
int y1 = Zero - (avg1-min) * nHeight / delta;
int y2 = Zero - (avg2-min) * nHeight / delta;
int x1 = nWidth+10;
int x2 = nWidth;
if(y1<30 && y2<30 || y1>Zero && y2>Zero)
{
avg1 = avg2;
avg2 = 0;
nWidth -= 10;
continue;
}
if(y2<30)
{
x2 = (y1-30) * 10 / (y2 - y1) + nWidth + 10;
y2 = 30;
}
if(y1<30)
{
x1 = (30-y2) * 10 / (y1 - y2) + nWidth;
y1 = 30;
}
if(y2>Zero)
{
x2 = (y1-Zero) * 10 / (y2 - y1) + nWidth + 10;
y2 = Zero;
}
if(y1>Zero)
{
x1 = (Zero-y2) * 10 / (y1 - y2) + nWidth;
y1 = Zero;
}
pDC->MoveTo(x1,y1);
pDC->LineTo(x2,y2);
avg1 = avg2;
avg2 = 0;
nWidth -= 10;
}
}
pFace->m_lpLayer[1]->ReleaseDC(layer);
pFace->m_lpLayer[0]->BltFast(0,0,pFace->m_lpLayer[1],CRect(0,0,pFace->m_rect.Width(),pFace->m_rect.Height()),DDBLTFAST_WAIT);
pFace->m_lpPSur->BltFast(pFace->m_rect.left,pFace->m_rect.top,pFace->m_lpLayer[0],CRect(0,0,pFace->m_rect.Width(),pFace->m_rect.Height()),DDBLTFAST_WAIT);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -