大智慧日K线的数据结构
大智慧日K线的数据结构
大智慧股票行情软件是目前应用广泛的一个炒股工具,有时我们需要自编炒股的算法进行研究,如提取某只股票的收盘价,成交量等,这时候如果能直接读大智慧股票分析系统的数据格式,将对软件的编制带来极大的方便。(注:大智慧用的钱龙数据格式,本文适用于钱龙股票行情软件中的日k线数据)。本文主要描述了在Delphi下大智慧日K线的数据结构,和以动态数组方式提取数据的方法。
一、数据文件和数据结构:
大智慧数据文件和数据结构:(假设大智慧股票行情软件安装在D:dzh目录下)
上海日线存储路径为:D:dzhDATASHaseDay,文件扩展名为:.day
上海周线存储路径为:D:dzhDATASHaseweek,文件扩展名为: .wek
上海月线存储路径为:D:dzhDATASHasemonth,文件扩展名为: .mnt
深圳日线存储路径为:D:dzhDATASZnseDay
深圳周线存储路径为:D:dzhDATASZnseweek
深圳月线存储路径为:D:dzhDATASZnsemonth
周线,月线格式与日线格式一致.
以深发展日线为例:
1A76:0100 D6 CD 2F 01 52 07 01 00-52 07 01 00 52 07 01 00
1A76:0110 52 07 01 00 86 0F 00 00-4D 02 00 00 00 00 00 00
1A76:0120 00 00 00 00 00 00 00 00-D7 CD 2F 01 60 03 01 00
1A76:0130 60 03 01 00 60 03 01 00-60 03 01 00 82 05 00 00
1A76:0140 D4 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
每一条记录的长度为40字节:
1-4字节为日期,D6 CD 2F 01转换为十进制是:19910102
5-8字节=开盘价(元)*1000
9-12字节=最高价(元)*1000
13-16字节=最低价(元)*1000
17-20字节=收盘价(元)*1000
21-24字节=成交金额(元)/1000
25-28字节=成交量(手)
其余12字节未使用
实现步骤:
1、先定义日线数据结构数组
2、再以实际记录数分配动态数组空间
3、然后把数据读入相应数组中
Procedure TFormKXianMain.ReadData(Sender: Tobject);//读取日k线数据文件中的开盘价、最高价、最低价、收盘价、成交金额、成交量
Var I:Integer;
Var FileName:String;//日k线数据文件
Var DataFile:File;
//-----------------定义日线数据结构数组----------
Var DataDate: LongWord;//日期数组
Var DataOpen: LongWord;//开盘价数组
Var DataHigh: LongWord;//最高价数组
Var DataLow: LongWord;//最低价数组
Var DataClose: LongWord;//收盘价数组
Var DataShuLiang: LongWord;//成交量数组
Var DataJinE: LongWord;//成交金额数组
Var DataNoOne: LongWord;
Var DataNoTwo: LongWord;
Var DataNoThree: LongWord;
//----------------------------------------------
Begin
Try
DayCount:=0;
FileName:=‘D:dzhDATASZnseDay001.day‘;//此处根据文件的具体路径填写
If FileExists(FileName) Then
Begin
AssignFile(DataFile, Filename);
Reset(DataFile,1);
//-------以实际记录数分配动态数组空间--------
DayCount:=Round(FileSize(DataFile)/40);
//基本数据
SetLength(DayData,7);
For I := Low(DayData) to High(DayData) do
SetLength(DayData[I],DayCount);
I:=0;
//------------------------------------------
//============把数据读入相应数组中===========
while not Eof(DataFile) do
Begin
BlockRead(DataFile, DataDate, SizeOf(DataDate));
DayData[0][I]:=DataDate;//读取日期数据放入日期数组中
BlockRead(DataFile, DataOpen, SizeOf(DataOpen));
DayData[1][I]:=DataOpen; //读取开盘数据放入开盘数组中
BlockRead(DataFile, DataClose, SizeOf(DataHigh));
DayData[4][I]:=DataClose; //读取收盘数据放入收盘数组中
BlockRead(DataFile, DataHigh, SizeOf(DataLow));
DayData[2][I]:=DataHigh; //读取最高价数据放入最高价数组中
BlockRead(DataFile, DataLow, SizeOf(DataClose));
DayData[3][I]:=DataLow; //读取最低价数据放入最低价数组中
BlockRead(DataFile, DataJinE, SizeOf(DataShuLiang));
DayData[5][I]:=Not DataJinE;//读取成交金额数据放入成交金额数组中
BlockRead(DataFile, DataShuLiang, SizeOf(DataJinE));
DayData[6][I]:=DataShuLiang;//读取成交量数据放入成交量数组中
BlockRead(DataFile, DataNoOne, SizeOf(DataNoOne));
BlockRead(DataFile, DataNoTwo, SizeOf(DataNoTwo));
BlockRead(DataFile, DataNoThree, SizeOf(DataNoThree));
I:=I+1;
End;
//========================================
CloseFile(DataFile);
End//数据文件存在
Else
MessageDlg(‘数据文件不存在,请检查程序中文件路径!‘, mtInformation,[mbOk], 0);
Except
MessageDlg(‘文件读写错误,请检查程序中文件路径!‘, mtInformation,[mbOk], 0);
End;
End;
二、引用日线数据文件中的数据
只要在需要的地方进行调用上述定义的数组即可。部分示例如下:
Procedure TFormKXianMain.DrawLineInIt(Sender: Tobject);
Var I,FlagExit,x1:Integer;
Begin
If DayCount>0 Then
Begin
BeginDate:=0;
EndDate:=DayCount-1;
x1:=LeftX;
FlagExit:=0;
I:=DayCount-1;
While (I>-1) And (FlagExit=0) Do
Begin
x1:=x1+DefaultWidth;
If (x1+DefaultWidth)>(PaintWidth-RightX) Then
FlagExit:=1
Else
I:=I-1;
End;
If (I=-1) Then
LeftDate:=0
Else
LeftDate:=I;
RightDate:=DayCount-1;
CurrentDate:=DayCount-1;
CurrentX:=x1-Round((DefaultWidth+1)/2);
End;
End;
Procedure TFormKXianMain.DrawLine(Sender: Tobject);
Var kpjg,spjg,zgjg,zdjg:Integer;
Var x1,x2,y1,y2,x3,y3,x4,y4:Integer;
Var I,Kheight:Integer;
Var TempString,OutStr:String;
Var TempLen,StrLen:Integer;
Begin
If DayCount>0 Then
Begin
//清空屏幕
Canvas.Brush.Color:=clblack;
Canvas.Brush.style:=bsSolid;
Canvas.FillRect(Rect(0,0,PaintWidth,PaintHeight));
//左边竖直线
Canvas.Pen.Color:=clRed;
Canvas.MoveTo(LeftX-1,0);
Canvas.LineTo(LeftX-1,PaintHeight);
//上边水平线
Canvas.MoveTo(0,TopY);
Canvas.LineTo(PaintWidth,TopY);
//右边竖直线
Canvas.MoveTo(PaintWidth-RightX,TopY);
Canvas.LineTo(PaintWidth-RightX,PaintHeight);
//下边水平线
Canvas.MoveTo(0,PaintHeight-BottomY);
Canvas.LineTo(PaintWidth-RightX,PaintHeight-BottomY);
PageTopY:=PaintHeight-BottomY;
Canvas.Pen.Style:=psDot;
Canvas.Pen.Color:=clMaroon;
Canvas.MoveTo(LeftX-1,Round(PageTopY/3));
Canvas.LineTo(PaintWidth-RightX,Round(PageTopY/3));
Canvas.MoveTo(LeftX-1,Round(2*PageTopY/3));
Canvas.LineTo(PaintWidth-RightX,Round(2*PageTopY/3));
Canvas.Pen.style:=psSolid;
//求价格的最大、最小值
Maxjg:=DayData[2][LeftDate];
MinJg:=DayData[3][LeftDate];
I:=LeftDate;
While (I<RightDate) Or (I=RightDate) Do
Begin
If DayData[2][I]>MaxJg Then
MaxJg:=DayData[2][I];
If DayData[3][I]<MinJg Then
MinJg:=DayData[3][I];
I:=I+1;
End;
//画右侧成交价格坐标数值
OutStr:=‘.‘;
Canvas.Font.Color := clRed;
Canvas.Brush.Color:=clBlack;
Canvas.Font.Size:=11;
Canvas.Font.name:=‘宋体‘;
Canvas.Brush.style:=bsSolid;
Canvas.Pen.color:=clred;
TempString:=IntToStr(Round(MinJg+(MaxJg-MinJg)*2/3));
TempLen:=Length(TempString);
Insert(OutStr,TempString,TempLen-2);
StrLen:=Length(TempString);
If TempString[StrLen]=‘0‘ Then
TempString[StrLen]:=‘ ‘;
Canvas.TextOut(PaintWidth-RightX+2,Round(PageTopY/3)-9,TempString);
TempString:=IntToStr(Round(MinJg+(MaxJg-MinJg)/3));
TempLen:=Length(TempString);
Insert(OutStr,TempString,TempLen-2);
StrLen:=Length(TempString);
If TempString[StrLen]=‘0‘ Then
TempString[StrLen]:=‘ ‘;
Canvas.TextOut(PaintWidth-RightX+2,Round(PageTopY*2/3)-9,TempString);
//画K线图
Kheight:=PageTopY-TopY-10;
HeightXiShu:=(MaxJg-MinJg)/Kheight;
x1:=LeftX-DefaultWidth;
I:=LeftDate;
While (I<RightDate) Or (I=RightDate) Do
Begin
kpjg:=DayData[1][I];
spjg:=DayData[4][I];
zgjg:=DayData[2][I];
zdjg:=DayData[3][I];
x1:=x1+DefaultWidth;
x2:=x1+DefaultWidth-1;
x3:=Round((x1+x2)/2);
x4:=x3;
If spjg<kpjg Then
Begin
Canvas.Pen.Color:=clAqua;
Canvas.Brush.Color:=clAqua;
Canvas.Brush.style:=bsSolid;
y3:=PageTopY-Round((zgjg-MinJg)/HeightXiShu)-2;
y1:=PageTopY-Round((kpjg-MinJg)/HeightXiShu)-2;
y2:=PageTopY-Round((spjg-MinJg)/HeightXiShu)-2;
y4:=PageTopY-Round((zdjg-MinJg)/HeightXiShu)-2;
If (y1=y2) Then
y2:=y2+1;
If (zgjg=kpjg) Then
y3:=y1;
If (zdjg=spjg) Then
y4:=y2;
If (zgjg<>kpjg) And (y1=y3) Then
y3:=y3-1;
If (zdjg<>spjg) And (y2=y4) Then
y4:=y4+1;
Canvas.MoveTo(x3,y3);
Canvas.LineTo(x3,y1);
Canvas.FillRect(Rect(x1,y1,x2,y2));
Canvas.MoveTo(x4,y2);
Canvas.LineTo(x4,y4);
End//收盘价小于开盘价,阴线
Else
Begin
Canvas.Pen.Color:=clred;
x2:=x2-1;
y3:=PageTopY-Round((zgjg-MinJg)/HeightXiShu)-2;
y1:=PageTopY-Round((spjg-MinJg)/HeightXiShu)-2;
y2:=PageTopY-Round((kpjg-MinJg)/HeightXiShu)-2;
y4:=PageTopY-Round((zdjg-MinJg)/HeightXiShu)-2;
If (y1=y2) And (spjg<>kpjg) Then
y2:=y2+1;
If (zdjg=kpjg) Then
y4:=y2;
If (zgjg=spjg) Then
y3:=y1;
If (zdjg<>kpjg) And (y2=y4) Then
y4:=y4+1;
If (zgjg<>spjg) And (y1=y3) Then
y3:=y3-1;
Canvas.MoveTo(x3,y3);
Canvas.LineTo(x3,y1);
Canvas.MoveTo(x1,y1);
Canvas.LineTo(x2,y1);
Canvas.LineTo(x2,y2);
Canvas.LineTo(x1,y2);
Canvas.LineTo(x1,y1);
Canvas.MoveTo(x4,y2);
Canvas.LineTo(x4,y4);
End;//收盘价大于开盘价,阳线
I:=I+1;
End;//画K线图
Canvas.Font.Color := clRed;
Canvas.Brush.Color:=clBlack;
Canvas.Font.Size:=11;
Canvas.Font.name:=‘宋体‘;
//输出证券名称
TempString:=ZqjcData[ZqRecordNo];
Canvas.TextOut(1,1,TempString);
//输出基本信息
TempString:=‘代码 ‘;
TempString:=TempString+ZqdmData[ZqRecordNo]+‘ ‘;
TempString:=TempString+‘流通股本‘;
TempString:=TempString+IntToStr(ZqltgbData[ZqRecordNo])+‘ ‘;
Canvas.TextOut(LeftX+1,1,TempString);
End;//数据集中数据个数大于0
End;
Procedure TFormKXianMain.DrawNowLine(Sender: Tobject);
Var TempStr,OutStr:String;
Var TempLen,StrLen:Integer;
Begin
If DayCount>0 Then
Begin
Canvas.Pen.Color:=clred;
OutStr:=‘.‘;
Canvas.Font.Color := clRed;
Canvas.Brush.Color:=clBlack;
Canvas.Font.Size:=11;
Canvas.Font.name:=‘宋体‘;
//输出日期
TempStr:=‘-‘+IntToStr(DayData[0][CurrentDate])+‘-‘;
Canvas.TextOut(2,PaintHeight-BottomY+1,TempStr);
//输出开盘价
TempStr:=IntToStr(DayData[1][CurrentDate]);
TempLen:=Length(TempStr);
Insert(OutStr,TempStr,TempLen-2);
StrLen:=Length(TempStr);
If TempStr[StrLen]=‘0‘ Then
TempStr[StrLen]:=‘ ‘;
Canvas.TextOut(1,TopY+1,‘开盘‘);
Canvas.TextOut(41,TopY+1,TempStr);
//输出最高价
TempStr:=IntToStr(DayData[2][CurrentDate]);
TempLen:=Length(TempStr);
Insert(OutStr,TempStr,TempLen-2);
StrLen:=Length(TempStr);
If TempStr[StrLen]=‘0‘ Then
TempStr[StrLen]:=‘ ‘;
Canvas.TextOut(1,TopY+21,‘最高‘);
Canvas.TextOut(41,TopY+21,TempStr);
//输出最低价
TempStr:=IntToStr(DayData[3][CurrentDate]);
TempLen:=Length(TempStr);
OutStr:=‘.‘;
Insert(OutStr,TempStr,TempLen-2);
StrLen:=Length(TempStr);
If TempStr[StrLen]=‘0‘ Then
TempStr[StrLen]:=‘ ‘;
Canvas.TextOut(1,TopY+41,‘最低‘);
Canvas.TextOut(41,TopY+41,TempStr);
//输出收盘价
TempStr:=IntToStr(DayData[4][CurrentDate]);
TempLen:=Length(TempStr);
Insert(OutStr,TempStr,TempLen-2);
StrLen:=Length(TempStr);
If TempStr[StrLen]=‘0‘ Then
TempStr[StrLen]:=‘ ‘;
Canvas.TextOut(1,TopY+61,‘收盘‘);
Canvas.TextOut(41,TopY+61,TempStr);
Canvas.MoveTo(LeftX-1,0);
Canvas.LineTo(LeftX-1,PaintHeight);
Canvas.Pen.Color:=clwhite;
Canvas.Brush.style:=bsSolid;
Canvas.MoveTo(CurrentX,TopY);
Canvas.LineTo(CurrentX,PaintHeight-BottomY);
End;//DayCount>1
End;
Procedure TFormKXianMain.MoveLineLeft(Sender: Tobject);
Var CurrentNow:Integer;
Begin
If CurrentDate>BeginDate Then
Begin
CurrentNow:=CurrentX;
If CurrentDate<>LeftDate Then
CurrentNow:=CurrentX-DefaultWidth
Else
Begin
LeftDate:=LeftDate-1;
RightDate:=RightDate-1;
End;
CurrentDate:=CurrentDate-1;
CurrentX:=CurrentNow;
DrawLine(EditCode);
DrawNowLine(EditCode);
End;
End;
Procedure TFormKXianMain.MoveLineRight(Sender: Tobject);
Var CurrentNow:Integer;
Begin
If CurrentDate<EndDate Then
Begin
CurrentNow:=CurrentX;
If CurrentDate<>RightDate Then
CurrentNow:=CurrentX+DefaultWidth
Else
Begin
LeftDate:=LeftDate+1;
RightDate:=RightDate+1;
End;
CurrentDate:=CurrentDate+1;
CurrentX:=CurrentNow;
DrawLine(EditCode);
DrawNowLine(EditCode);
End;
End;
Procedure TFormKXianMain.MoveLineHome(Sender: Tobject);
Begin
If CurrentDate<>BeginDate Then
Begin
CurrentDate:=LeftDate;
CurrentX:=LeftX+Round(DefaultWidth/2);
DrawLine(EditCode);
DrawNowLine(EditCode);
End;
End;
Procedure TFormKXianMain.MoveLineEnd(Sender: Tobject);
Var CurrentNow:Integer;
Begin
If CurrentDate<>EndDate Then
Begin
CurrentNow:=CurrentX;
While (CurrentDate<>RightDate) Do
Begin
CurrentNow:=CurrentNow+DefaultWidth;
CurrentDate:=CurrentDate+1;
End;
CurrentX:=CurrentNow;
DrawLine(EditCode);
DrawNowLine(EditCode);
End;
End;
procedure TFormKXianMain.EditCodeKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
If (key=VK_RETURN) And (EditCode.Text<>CurrentCode) Then
Begin
CurrentCode:=‘‘;
If ZqdmFind(EditCode.Text)<>-1 Then
CurrentCode:=ZqdmData[ZqRecordNo]
Else If ZqkjmFind(EditCode.Text)<>-1 Then
CurrentCode:=ZqdmData[ZqRecordNo]
Else
MessageDlg(‘证券代码不存在,请重新输入!‘, mtInformation,[mbOk], 0);
EditCode.Text:=‘‘;
If CurrentCode<>‘‘ Then
Begin
ReadData(EditCode);
DrawLineInit(EditCode);
DrawLine(EditCode);
DrawNowLine(EditCode);
End;
End;
If (Key=VK_PRIOR) Then//Page Up key
Begin
If (ZqRecordNo=0) Then
ZqRecordNo:=ZqRecordCount-1;
ZqRecordNo:=ZqRecordNo-1;
CurrentCode:=ZqdmData[ZqRecordNo];
ReadData(EditCode);
DrawLineInit(EditCode);
DrawLine(EditCode);
DrawNowLine(EditCode);
End;
If (Key=VK_NEXT) Then//Page Down key
Begin
If (ZqRecordNo=(ZqRecordCount-1)) Then
ZqRecordNo:=0;
ZqRecordNo:=ZqRecordNo+1;
CurrentCode:=ZqdmData[ZqRecordNo];
ReadData(EditCode);
DrawLineInit(EditCode);
DrawLine(EditCode);
DrawNowLine(EditCode);
End;
If (Key=VK_DOWN) And (DefaultWidth>3) Then//Virtual key codes
Begin
DefaultWidth:=DefaultWidth-2;
ReadData(EditCode);
DrawLineInit(EditCode);
DrawLine(EditCode);
DrawNowLine(EditCode);
End;
If (Key=VK_UP) And (DefaultWidth<50) Then
Begin
DefaultWidth:=DefaultWidth+2;
ReadData(EditCode);
DrawLineInit(EditCode);
DrawLine(EditCode);
DrawNowLine(EditCode);
End;
If (Key=VK_HOME) Then
MoveLineHome(EditCode);
If (Key=VK_END) Then
MoveLineEnd(EditCode);
If (Key=VK_LEFT) Then
MoveLineLeft(EditCode);
If (Key=VK_RIGHT) Then
MoveLineRight(EditCode);
end;
procedure TFormKXianMain.PaintBoxMainPaint(Sender: TObject);
Begin
If CurrentCode<>‘‘ Then
Begin
ReadData(EditCode);
DrawLineInit(EditCode);
DrawLine(EditCode);
DrawNowLine(EditCode);
End;
end;
procedure TFormKXianMain.NTuiChuClick(Sender: TObject);
begin
FormKXianMain.Close;
end;
procedure TFormKXianMain.NShuJuYuanSheZhiClick(Sender: TObject);
begin
FormShuJuYuanSheZhi.ShowModal;
end;
procedure TFormKXianMain.PaintBoxMainMouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
Var DayNumber:Integer;
begin
MouseX:=X;
MouseY:=Y;
If CurrentCode<>‘‘ Then
Begin
If (X>CurrentX) Then
Begin
DayNumber:=Trunc((X-CurrentX)/DefaultWidth+0.5);
If DayNumber>(RightDate-CurrentDate) Then
DayNumber:=RightDate-CurrentDate;
CurrentDate:=CurrentDate+DayNumber;
CurrentX:=CurrentX+DayNumber*DefaultWidth;
DrawLine(EditCode);
DrawNowLine(EditCode);
End
Else If (X<CurrentX) Then
Begin
DayNumber:=Trunc((CurrentX-X)/DefaultWidth+0.5);
If DayNumber>(CurrentDate-LeftDate) Then
DayNumber:=CurrentDate-LeftDate;
CurrentDate:=CurrentDate-DayNumber;
CurrentX:=CurrentX-DayNumber*DefaultWidth;
DrawLine(EditCode);
DrawNowLine(EditCode);
End;
End;
end;
大智慧股票行情软件是目前应用广泛的一个炒股工具,有时我们需要自编炒股的算法进行研究,如提取某只股票的收盘价,成交量等,这时候如果能直接读大智慧股票分析系统的数据格式,将对软件的编制带来极大的方便。(注:大智慧用的钱龙数据格式,本文适用于钱龙股票行情软件中的日k线数据)。本文主要描述了在Delphi下大智慧日K线的数据结构,和以动态数组方式提取数据的方法。
一、数据文件和数据结构:
大智慧数据文件和数据结构:(假设大智慧股票行情软件安装在D:dzh目录下)
上海日线存储路径为:D:dzhDATASHaseDay,文件扩展名为:.day
上海周线存储路径为:D:dzhDATASHaseweek,文件扩展名为: .wek
上海月线存储路径为:D:dzhDATASHasemonth,文件扩展名为: .mnt
深圳日线存储路径为:D:dzhDATASZnseDay
深圳周线存储路径为:D:dzhDATASZnseweek
深圳月线存储路径为:D:dzhDATASZnsemonth
周线,月线格式与日线格式一致.
以深发展日线为例:
1A76:0100 D6 CD 2F 01 52 07 01 00-52 07 01 00 52 07 01 00
1A76:0110 52 07 01 00 86 0F 00 00-4D 02 00 00 00 00 00 00
1A76:0120 00 00 00 00 00 00 00 00-D7 CD 2F 01 60 03 01 00
1A76:0130 60 03 01 00 60 03 01 00-60 03 01 00 82 05 00 00
1A76:0140 D4 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00
每一条记录的长度为40字节:
1-4字节为日期,D6 CD 2F 01转换为十进制是:19910102
5-8字节=开盘价(元)*1000
9-12字节=最高价(元)*1000
13-16字节=最低价(元)*1000
17-20字节=收盘价(元)*1000
21-24字节=成交金额(元)/1000
25-28字节=成交量(手)
其余12字节未使用
实现步骤:
1、先定义日线数据结构数组
2、再以实际记录数分配动态数组空间
3、然后把数据读入相应数组中
Procedure TFormKXianMain.ReadData(Sender: Tobject);//读取日k线数据文件中的开盘价、最高价、最低价、收盘价、成交金额、成交量
Var I:Integer;
Var FileName:String;//日k线数据文件
Var DataFile:File;
//-----------------定义日线数据结构数组----------
Var DataDate: LongWord;//日期数组
Var DataOpen: LongWord;//开盘价数组
Var DataHigh: LongWord;//最高价数组
Var DataLow: LongWord;//最低价数组
Var DataClose: LongWord;//收盘价数组
Var DataShuLiang: LongWord;//成交量数组
Var DataJinE: LongWord;//成交金额数组
Var DataNoOne: LongWord;
Var DataNoTwo: LongWord;
Var DataNoThree: LongWord;
//----------------------------------------------
Begin
Try
DayCount:=0;
FileName:=‘D:dzhDATASZnseDay001.day‘;//此处根据文件的具体路径填写
If FileExists(FileName) Then
Begin
AssignFile(DataFile, Filename);
Reset(DataFile,1);
//-------以实际记录数分配动态数组空间--------
DayCount:=Round(FileSize(DataFile)/40);
//基本数据
SetLength(DayData,7);
For I := Low(DayData) to High(DayData) do
SetLength(DayData[I],DayCount);
I:=0;
//------------------------------------------
//============把数据读入相应数组中===========
while not Eof(DataFile) do
Begin
BlockRead(DataFile, DataDate, SizeOf(DataDate));
DayData[0][I]:=DataDate;//读取日期数据放入日期数组中
BlockRead(DataFile, DataOpen, SizeOf(DataOpen));
DayData[1][I]:=DataOpen; //读取开盘数据放入开盘数组中
BlockRead(DataFile, DataClose, SizeOf(DataHigh));
DayData[4][I]:=DataClose; //读取收盘数据放入收盘数组中
BlockRead(DataFile, DataHigh, SizeOf(DataLow));
DayData[2][I]:=DataHigh; //读取最高价数据放入最高价数组中
BlockRead(DataFile, DataLow, SizeOf(DataClose));
DayData[3][I]:=DataLow; //读取最低价数据放入最低价数组中
BlockRead(DataFile, DataJinE, SizeOf(DataShuLiang));
DayData[5][I]:=Not DataJinE;//读取成交金额数据放入成交金额数组中
BlockRead(DataFile, DataShuLiang, SizeOf(DataJinE));
DayData[6][I]:=DataShuLiang;//读取成交量数据放入成交量数组中
BlockRead(DataFile, DataNoOne, SizeOf(DataNoOne));
BlockRead(DataFile, DataNoTwo, SizeOf(DataNoTwo));
BlockRead(DataFile, DataNoThree, SizeOf(DataNoThree));
I:=I+1;
End;
//========================================
CloseFile(DataFile);
End//数据文件存在
Else
MessageDlg(‘数据文件不存在,请检查程序中文件路径!‘, mtInformation,[mbOk], 0);
Except
MessageDlg(‘文件读写错误,请检查程序中文件路径!‘, mtInformation,[mbOk], 0);
End;
End;
二、引用日线数据文件中的数据
只要在需要的地方进行调用上述定义的数组即可。部分示例如下:
Procedure TFormKXianMain.DrawLineInIt(Sender: Tobject);
Var I,FlagExit,x1:Integer;
Begin
If DayCount>0 Then
Begin
BeginDate:=0;
EndDate:=DayCount-1;
x1:=LeftX;
FlagExit:=0;
I:=DayCount-1;
While (I>-1) And (FlagExit=0) Do
Begin
x1:=x1+DefaultWidth;
If (x1+DefaultWidth)>(PaintWidth-RightX) Then
FlagExit:=1
Else
I:=I-1;
End;
If (I=-1) Then
LeftDate:=0
Else
LeftDate:=I;
RightDate:=DayCount-1;
CurrentDate:=DayCount-1;
CurrentX:=x1-Round((DefaultWidth+1)/2);
End;
End;
Procedure TFormKXianMain.DrawLine(Sender: Tobject);
Var kpjg,spjg,zgjg,zdjg:Integer;
Var x1,x2,y1,y2,x3,y3,x4,y4:Integer;
Var I,Kheight:Integer;
Var TempString,OutStr:String;
Var TempLen,StrLen:Integer;
Begin
If DayCount>0 Then
Begin
//清空屏幕
Canvas.Brush.Color:=clblack;
Canvas.Brush.style:=bsSolid;
Canvas.FillRect(Rect(0,0,PaintWidth,PaintHeight));
//左边竖直线
Canvas.Pen.Color:=clRed;
Canvas.MoveTo(LeftX-1,0);
Canvas.LineTo(LeftX-1,PaintHeight);
//上边水平线
Canvas.MoveTo(0,TopY);
Canvas.LineTo(PaintWidth,TopY);
//右边竖直线
Canvas.MoveTo(PaintWidth-RightX,TopY);
Canvas.LineTo(PaintWidth-RightX,PaintHeight);
//下边水平线
Canvas.MoveTo(0,PaintHeight-BottomY);
Canvas.LineTo(PaintWidth-RightX,PaintHeight-BottomY);
PageTopY:=PaintHeight-BottomY;
Canvas.Pen.Style:=psDot;
Canvas.Pen.Color:=clMaroon;
Canvas.MoveTo(LeftX-1,Round(PageTopY/3));
Canvas.LineTo(PaintWidth-RightX,Round(PageTopY/3));
Canvas.MoveTo(LeftX-1,Round(2*PageTopY/3));
Canvas.LineTo(PaintWidth-RightX,Round(2*PageTopY/3));
Canvas.Pen.style:=psSolid;
//求价格的最大、最小值
Maxjg:=DayData[2][LeftDate];
MinJg:=DayData[3][LeftDate];
I:=LeftDate;
While (I<RightDate) Or (I=RightDate) Do
Begin
If DayData[2][I]>MaxJg Then
MaxJg:=DayData[2][I];
If DayData[3][I]<MinJg Then
MinJg:=DayData[3][I];
I:=I+1;
End;
//画右侧成交价格坐标数值
OutStr:=‘.‘;
Canvas.Font.Color := clRed;
Canvas.Brush.Color:=clBlack;
Canvas.Font.Size:=11;
Canvas.Font.name:=‘宋体‘;
Canvas.Brush.style:=bsSolid;
Canvas.Pen.color:=clred;
TempString:=IntToStr(Round(MinJg+(MaxJg-MinJg)*2/3));
TempLen:=Length(TempString);
Insert(OutStr,TempString,TempLen-2);
StrLen:=Length(TempString);
If TempString[StrLen]=‘0‘ Then
TempString[StrLen]:=‘ ‘;
Canvas.TextOut(PaintWidth-RightX+2,Round(PageTopY/3)-9,TempString);
TempString:=IntToStr(Round(MinJg+(MaxJg-MinJg)/3));
TempLen:=Length(TempString);
Insert(OutStr,TempString,TempLen-2);
StrLen:=Length(TempString);
If TempString[StrLen]=‘0‘ Then
TempString[StrLen]:=‘ ‘;
Canvas.TextOut(PaintWidth-RightX+2,Round(PageTopY*2/3)-9,TempString);
//画K线图
Kheight:=PageTopY-TopY-10;
HeightXiShu:=(MaxJg-MinJg)/Kheight;
x1:=LeftX-DefaultWidth;
I:=LeftDate;
While (I<RightDate) Or (I=RightDate) Do
Begin
kpjg:=DayData[1][I];
spjg:=DayData[4][I];
zgjg:=DayData[2][I];
zdjg:=DayData[3][I];
x1:=x1+DefaultWidth;
x2:=x1+DefaultWidth-1;
x3:=Round((x1+x2)/2);
x4:=x3;
If spjg<kpjg Then
Begin
Canvas.Pen.Color:=clAqua;
Canvas.Brush.Color:=clAqua;
Canvas.Brush.style:=bsSolid;
y3:=PageTopY-Round((zgjg-MinJg)/HeightXiShu)-2;
y1:=PageTopY-Round((kpjg-MinJg)/HeightXiShu)-2;
y2:=PageTopY-Round((spjg-MinJg)/HeightXiShu)-2;
y4:=PageTopY-Round((zdjg-MinJg)/HeightXiShu)-2;
If (y1=y2) Then
y2:=y2+1;
If (zgjg=kpjg) Then
y3:=y1;
If (zdjg=spjg) Then
y4:=y2;
If (zgjg<>kpjg) And (y1=y3) Then
y3:=y3-1;
If (zdjg<>spjg) And (y2=y4) Then
y4:=y4+1;
Canvas.MoveTo(x3,y3);
Canvas.LineTo(x3,y1);
Canvas.FillRect(Rect(x1,y1,x2,y2));
Canvas.MoveTo(x4,y2);
Canvas.LineTo(x4,y4);
End//收盘价小于开盘价,阴线
Else
Begin
Canvas.Pen.Color:=clred;
x2:=x2-1;
y3:=PageTopY-Round((zgjg-MinJg)/HeightXiShu)-2;
y1:=PageTopY-Round((spjg-MinJg)/HeightXiShu)-2;
y2:=PageTopY-Round((kpjg-MinJg)/HeightXiShu)-2;
y4:=PageTopY-Round((zdjg-MinJg)/HeightXiShu)-2;
If (y1=y2) And (spjg<>kpjg) Then
y2:=y2+1;
If (zdjg=kpjg) Then
y4:=y2;
If (zgjg=spjg) Then
y3:=y1;
If (zdjg<>kpjg) And (y2=y4) Then
y4:=y4+1;
If (zgjg<>spjg) And (y1=y3) Then
y3:=y3-1;
Canvas.MoveTo(x3,y3);
Canvas.LineTo(x3,y1);
Canvas.MoveTo(x1,y1);
Canvas.LineTo(x2,y1);
Canvas.LineTo(x2,y2);
Canvas.LineTo(x1,y2);
Canvas.LineTo(x1,y1);
Canvas.MoveTo(x4,y2);
Canvas.LineTo(x4,y4);
End;//收盘价大于开盘价,阳线
I:=I+1;
End;//画K线图
Canvas.Font.Color := clRed;
Canvas.Brush.Color:=clBlack;
Canvas.Font.Size:=11;
Canvas.Font.name:=‘宋体‘;
//输出证券名称
TempString:=ZqjcData[ZqRecordNo];
Canvas.TextOut(1,1,TempString);
//输出基本信息
TempString:=‘代码 ‘;
TempString:=TempString+ZqdmData[ZqRecordNo]+‘ ‘;
TempString:=TempString+‘流通股本‘;
TempString:=TempString+IntToStr(ZqltgbData[ZqRecordNo])+‘ ‘;
Canvas.TextOut(LeftX+1,1,TempString);
End;//数据集中数据个数大于0
End;
Procedure TFormKXianMain.DrawNowLine(Sender: Tobject);
Var TempStr,OutStr:String;
Var TempLen,StrLen:Integer;
Begin
If DayCount>0 Then
Begin
Canvas.Pen.Color:=clred;
OutStr:=‘.‘;
Canvas.Font.Color := clRed;
Canvas.Brush.Color:=clBlack;
Canvas.Font.Size:=11;
Canvas.Font.name:=‘宋体‘;
//输出日期
TempStr:=‘-‘+IntToStr(DayData[0][CurrentDate])+‘-‘;
Canvas.TextOut(2,PaintHeight-BottomY+1,TempStr);
//输出开盘价
TempStr:=IntToStr(DayData[1][CurrentDate]);
TempLen:=Length(TempStr);
Insert(OutStr,TempStr,TempLen-2);
StrLen:=Length(TempStr);
If TempStr[StrLen]=‘0‘ Then
TempStr[StrLen]:=‘ ‘;
Canvas.TextOut(1,TopY+1,‘开盘‘);
Canvas.TextOut(41,TopY+1,TempStr);
//输出最高价
TempStr:=IntToStr(DayData[2][CurrentDate]);
TempLen:=Length(TempStr);
Insert(OutStr,TempStr,TempLen-2);
StrLen:=Length(TempStr);
If TempStr[StrLen]=‘0‘ Then
TempStr[StrLen]:=‘ ‘;
Canvas.TextOut(1,TopY+21,‘最高‘);
Canvas.TextOut(41,TopY+21,TempStr);
//输出最低价
TempStr:=IntToStr(DayData[3][CurrentDate]);
TempLen:=Length(TempStr);
OutStr:=‘.‘;
Insert(OutStr,TempStr,TempLen-2);
StrLen:=Length(TempStr);
If TempStr[StrLen]=‘0‘ Then
TempStr[StrLen]:=‘ ‘;
Canvas.TextOut(1,TopY+41,‘最低‘);
Canvas.TextOut(41,TopY+41,TempStr);
//输出收盘价
TempStr:=IntToStr(DayData[4][CurrentDate]);
TempLen:=Length(TempStr);
Insert(OutStr,TempStr,TempLen-2);
StrLen:=Length(TempStr);
If TempStr[StrLen]=‘0‘ Then
TempStr[StrLen]:=‘ ‘;
Canvas.TextOut(1,TopY+61,‘收盘‘);
Canvas.TextOut(41,TopY+61,TempStr);
Canvas.MoveTo(LeftX-1,0);
Canvas.LineTo(LeftX-1,PaintHeight);
Canvas.Pen.Color:=clwhite;
Canvas.Brush.style:=bsSolid;
Canvas.MoveTo(CurrentX,TopY);
Canvas.LineTo(CurrentX,PaintHeight-BottomY);
End;//DayCount>1
End;
Procedure TFormKXianMain.MoveLineLeft(Sender: Tobject);
Var CurrentNow:Integer;
Begin
If CurrentDate>BeginDate Then
Begin
CurrentNow:=CurrentX;
If CurrentDate<>LeftDate Then
CurrentNow:=CurrentX-DefaultWidth
Else
Begin
LeftDate:=LeftDate-1;
RightDate:=RightDate-1;
End;
CurrentDate:=CurrentDate-1;
CurrentX:=CurrentNow;
DrawLine(EditCode);
DrawNowLine(EditCode);
End;
End;
Procedure TFormKXianMain.MoveLineRight(Sender: Tobject);
Var CurrentNow:Integer;
Begin
If CurrentDate<EndDate Then
Begin
CurrentNow:=CurrentX;
If CurrentDate<>RightDate Then
CurrentNow:=CurrentX+DefaultWidth
Else
Begin
LeftDate:=LeftDate+1;
RightDate:=RightDate+1;
End;
CurrentDate:=CurrentDate+1;
CurrentX:=CurrentNow;
DrawLine(EditCode);
DrawNowLine(EditCode);
End;
End;
Procedure TFormKXianMain.MoveLineHome(Sender: Tobject);
Begin
If CurrentDate<>BeginDate Then
Begin
CurrentDate:=LeftDate;
CurrentX:=LeftX+Round(DefaultWidth/2);
DrawLine(EditCode);
DrawNowLine(EditCode);
End;
End;
Procedure TFormKXianMain.MoveLineEnd(Sender: Tobject);
Var CurrentNow:Integer;
Begin
If CurrentDate<>EndDate Then
Begin
CurrentNow:=CurrentX;
While (CurrentDate<>RightDate) Do
Begin
CurrentNow:=CurrentNow+DefaultWidth;
CurrentDate:=CurrentDate+1;
End;
CurrentX:=CurrentNow;
DrawLine(EditCode);
DrawNowLine(EditCode);
End;
End;
procedure TFormKXianMain.EditCodeKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
If (key=VK_RETURN) And (EditCode.Text<>CurrentCode) Then
Begin
CurrentCode:=‘‘;
If ZqdmFind(EditCode.Text)<>-1 Then
CurrentCode:=ZqdmData[ZqRecordNo]
Else If ZqkjmFind(EditCode.Text)<>-1 Then
CurrentCode:=ZqdmData[ZqRecordNo]
Else
MessageDlg(‘证券代码不存在,请重新输入!‘, mtInformation,[mbOk], 0);
EditCode.Text:=‘‘;
If CurrentCode<>‘‘ Then
Begin
ReadData(EditCode);
DrawLineInit(EditCode);
DrawLine(EditCode);
DrawNowLine(EditCode);
End;
End;
If (Key=VK_PRIOR) Then//Page Up key
Begin
If (ZqRecordNo=0) Then
ZqRecordNo:=ZqRecordCount-1;
ZqRecordNo:=ZqRecordNo-1;
CurrentCode:=ZqdmData[ZqRecordNo];
ReadData(EditCode);
DrawLineInit(EditCode);
DrawLine(EditCode);
DrawNowLine(EditCode);
End;
If (Key=VK_NEXT) Then//Page Down key
Begin
If (ZqRecordNo=(ZqRecordCount-1)) Then
ZqRecordNo:=0;
ZqRecordNo:=ZqRecordNo+1;
CurrentCode:=ZqdmData[ZqRecordNo];
ReadData(EditCode);
DrawLineInit(EditCode);
DrawLine(EditCode);
DrawNowLine(EditCode);
End;
If (Key=VK_DOWN) And (DefaultWidth>3) Then//Virtual key codes
Begin
DefaultWidth:=DefaultWidth-2;
ReadData(EditCode);
DrawLineInit(EditCode);
DrawLine(EditCode);
DrawNowLine(EditCode);
End;
If (Key=VK_UP) And (DefaultWidth<50) Then
Begin
DefaultWidth:=DefaultWidth+2;
ReadData(EditCode);
DrawLineInit(EditCode);
DrawLine(EditCode);
DrawNowLine(EditCode);
End;
If (Key=VK_HOME) Then
MoveLineHome(EditCode);
If (Key=VK_END) Then
MoveLineEnd(EditCode);
If (Key=VK_LEFT) Then
MoveLineLeft(EditCode);
If (Key=VK_RIGHT) Then
MoveLineRight(EditCode);
end;
procedure TFormKXianMain.PaintBoxMainPaint(Sender: TObject);
Begin
If CurrentCode<>‘‘ Then
Begin
ReadData(EditCode);
DrawLineInit(EditCode);
DrawLine(EditCode);
DrawNowLine(EditCode);
End;
end;
procedure TFormKXianMain.NTuiChuClick(Sender: TObject);
begin
FormKXianMain.Close;
end;
procedure TFormKXianMain.NShuJuYuanSheZhiClick(Sender: TObject);
begin
FormShuJuYuanSheZhi.ShowModal;
end;
procedure TFormKXianMain.PaintBoxMainMouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
Var DayNumber:Integer;
begin
MouseX:=X;
MouseY:=Y;
If CurrentCode<>‘‘ Then
Begin
If (X>CurrentX) Then
Begin
DayNumber:=Trunc((X-CurrentX)/DefaultWidth+0.5);
If DayNumber>(RightDate-CurrentDate) Then
DayNumber:=RightDate-CurrentDate;
CurrentDate:=CurrentDate+DayNumber;
CurrentX:=CurrentX+DayNumber*DefaultWidth;
DrawLine(EditCode);
DrawNowLine(EditCode);
End
Else If (X<CurrentX) Then
Begin
DayNumber:=Trunc((CurrentX-X)/DefaultWidth+0.5);
If DayNumber>(CurrentDate-LeftDate) Then
DayNumber:=CurrentDate-LeftDate;
CurrentDate:=CurrentDate-DayNumber;
CurrentX:=CurrentX-DayNumber*DefaultWidth;
DrawLine(EditCode);
DrawNowLine(EditCode);
End;
End;
end;
http://www.winu.cn/thread-51497-1-1.html