请问如何在k线图上画平均线?(50分)

C

cjg1881

Unregistered / Unconfirmed
GUEST, unregistred user!
请问如何在线图上画平均线,线以画出。
 
要算法?均值就是前面几天收盘价的算术平均值。有5日/30日/1年等几种。
 
用何函数画线?
 
请帮忙把代码写一下,我是画出了k线,平均线不知用何画。分不够另送分.谢谢谢谢
 
还是不明白你究竟要什么,要算法的话,你需要一本股票分析基本技术的书,因为还有许多
指标需要画出来,一下子是讲不清楚的。
如果说不是要算法,而是要具体怎么画的代码,这个得根据你现有的数据结构、图形控件等
才能给出,而且这个有了算法之后是很容易的,你既然能画出K线的话,肯定有画平均线的
能力了(我觉得K线比均线复杂)。
 
不是要算法,连一条平均线都画不出不知从何着手,我是用Tpaintbox上画的。DrawLine过程画的,
是乔见行著的项目按列导航书上的,k线搞懂了想继续下去,后面不知如何画指标?请知点
谢谢
 
用DrawLine? 直接用Canvas的Rectangle、LineTo、MoveTo等不好吗?
示例如下:
i:=1;
//由于图形应该能够支持缩放,因此每页显示的天数是不固定的
while i<maxdays do begin // 计算5日均值, sp为收盘价, cd为均值
if i<=5 then
cd := 0
else
cd := (sp+sp[i-1]+sp[i-2]+sp[i-3]+sp[i-4])/5;
end;

// 5日均线,从第5天开始才有数值
// x是横坐标,应该根据缩放因子确定
PaintBox1.Canvas.MoveTo(x[5],cd[5]);
i:=6;
while i<maxdays do begin
PaintBox1.Canvas.LineTo(x,cd);
inc(i);
end;
 
嗬嗬,不好意思,代码里面有错误,更正。。。
 
是有错误,运行后第一句就报错.第一句是否为总天数,请问如何计算?我在painbox上画成交量。
与k线重合下地便可以调整,而上边顶头用topy:=100,上边不变,而k线宽度却变了,原k线
topy:=30,请问如何解决?问题太多不好意思,谢谢谢谢,
 
你得把你的程序贴出来。
 
procedure TFormKXianMain.FormShow(Sender: TObject);
Var ShuJuYuanFile,ZqxxFile:TextFile;
Var TempString:String;
Var I:integer;
begin
try
PaintHeight:=PaintBoxMain.Height;
PaintWidth:=PaintBoxMain.Width;
DefaultWidth:=9;
LeftX:=0;
RightX:=200;
TopY:=30;
BottomY:=220;
DayPathName:='';
DayCount:=-1;
CurrentCode:='';
BeginDate:=0;
EndDate:=0;
LeftDate:=0;
RightDate:=0;


If FileExists('ShuJu.Txt') Then
Begin
AssignFile(ShuJuYuanFile, 'ShuJu.Txt');
FileMode:=0; //Set file access to read only
Reset(ShuJuYuanFile);
Readln(ShuJuYuanFile,TempString);
DayPathName:=TempString;
CloseFile(ShuJuYuanFile);
End;
If FileExists('Zqxx.Txt') Then
Begin
AssignFile(ZqxxFile, 'Zqxx.Txt');
FileMode := 0; //Set file access to read only
Reset(ZqxxFile);
ZqRecordCount:=0;
while not Eof(ZqxxFile) do
Begin
Readln(ZqxxFile,TempString);
Readln(ZqxxFile,TempString);
Readln(ZqxxFile,TempString);
Readln(ZqxxFile,TempString);
Readln(ZqxxFile,TempString);
ZqRecordCount:=ZqRecordCount+1;
End;
SetLength(ZqdmData,ZqRecordCount);
SetLength(ZqjcData,ZqRecordCount);
SetLength(ZqkjmData,ZqRecordCount);
SetLength(ZqzgbData,ZqRecordCount);
SetLength(ZqltgbData,ZqRecordCount);
Reset(ZqxxFile);
I:=0;
while not Eof(ZqxxFile) do
Begin
Readln(ZqxxFile,TempString);
ZqdmData:=TempString;
Readln(ZqxxFile,TempString);
ZqjcData:=TempString;
Readln(ZqxxFile,TempString);
ZqkjmData:=TempString;
Readln(ZqxxFile,TempString);
ZqzgbData:=StrToInt(TempString);
Readln(ZqxxFile,TempString);
ZqltgbData:=StrToInt(TempString);
I:=I+1;
End;
End;
EditCode.Left:=PaintWidth-EditCode.Width-5;
LabelCode.Left:=EditCode.Left-LabelCode.Width-2;
Canvas.Brush.Color:=clblack;
Canvas.Brush.style:=bsSolid;
Canvas.FillRect(Rect(0,0,PaintWidth,PaintHeight));
ActiveControl:=EditCode;
except
MessageDlg('初始化失败,程序退出!', mtInformation,[mbOk], 0);
End;
end;


Procedure TFormKXianMain.ReadData(Sender: Tobject);
Var I:Integer;
Var FileName:String;
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:=DayPathName+'/'+CurrentCode+'.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,DayCount);
I:=0;

while not Eof(DataFile) do
Begin
BlockRead(DataFile, DataDate, SizeOf(DataDate));
DayData[0]:=NOT DataDate;
BlockRead(DataFile, DataOpen, SizeOf(DataOpen));
DayData[1]:= DataOpen; //Open
BlockRead(DataFile, DataClose, SizeOf(DataHigh));
DayData[2]:= DataClose; //Close
BlockRead(DataFile, DataHigh, SizeOf(DataLow));
DayData[3]:= DataHigh; //High
BlockRead(DataFile, DataLow, SizeOf(DataClose));
DayData[4]:= DataLow; //Low
BlockRead(DataFile, DataJinE, SizeOf(DataShuLiang));
DayData[5]:=Not DataJinE;//Jin E
BlockRead(DataFile, DataShuLiang, SizeOf(DataJinE));
DayData[6]:=Not DataShuLiang;//Shu Liang
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,cjl,cd,Majg:Integer;
Var x1,x2,y1,y2,x3,y3,x4,y4,x5,x6,y5,y6:Integer;
Var I,Kheight,HeightXi:Integer;
Var TempString,OutStr:String;
Var TempLen,StrLen:Integer;
Begin
If DayCount>0 Then
Begin
//清空屏幕
Canvas.Brush.Color:=clblack;
Canvas.Brush.style:=bsSolid;
Canvas.Pen.Style:=pssolid;
Canvas.FillRect(Rect(0,0,PaintWidth,PaintHeight));

//左边竖直线
Canvas.Pen.Color:=clred;
Canvas.MoveTo(LeftX-1,0);
Canvas.LineTo(LeftX-1,PaintHeight);
//上边水平线
Canvas.Pen.Style:=psDot;
Canvas.Pen.Color:=clMaroon;
Canvas.MoveTo(0,topy);
Canvas.LineTo(PaintWidth-200,topy);
//右边竖直线
Canvas.Pen.Style:=pssolid;
Canvas.Pen.Color:=clred;
Canvas.MoveTo(PaintWidth-RightX,0);
Canvas.LineTo(PaintWidth-RightX,PaintHeight);

Canvas.MoveTo(PaintWidth-160,0);
Canvas.LineTo(PaintWidth-160,PaintHeight);
//下边水平线
Canvas.MoveTo(0,PaintHeight-BottomY);
Canvas.LineTo(PaintWidth-160,PaintHeight-BottomY);



Canvas.MoveTo(0,PaintHeight-13);
Canvas.LineTo(PaintWidth-160,PaintHeight-13);
PageTopY:=PaintHeight-BottomY;

//求价格的最大、最小值
Maxjg:=DayData[2][LeftDate];
MinJg:=DayData[3][LeftDate];

I:=LeftDate;
While (I<RightDate) Or (I=RightDate) Do
Begin
If DayData[2]>MaxJg Then
MaxJg:=DayData[2];
If DayData[3]<MinJg Then
MinJg:=DayData[3];
I:=I+1;

End;







//画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];
spjg:=DayData[4];
zgjg:=DayData[2];
zdjg:=DayData[3];
cjl:=not DayData[6];
x1:=x1+DefaultWidth;
x2:=x1+DefaultWidth-1;
x3:=Round((x1+x2)/2);
x4:=x3;




//画成交量,这里有错,与k线重合,是否在k线下面再放一画布paintbox或其他?






Canvas.Pen.Color:=clred;

y5:=(PageTopY-100+topy)-Round((cjl)/200);
y6:=(PageTopY-100+topy)-Round((50-cjl)/200);
Canvas.MoveTo(x4,y6);
Canvas.LineTo(x4,y5);

Canvas.MoveTo(x3,y5);
Canvas.LineTo(x3,y6);




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(700,30,TempString);



//输出基本信息
TempString:='代码 ';
TempString:=TempString+ZqdmData[ZqRecordNo]+' ';

Canvas.TextOut(700,TopY+60,TempString) ;

一下如何画平均线,请指教,谢谢。


End;//数据集中数据个数大于0
End;
 
觉得代码太乱、没有结构化,程序和数据结构都不清晰,看了半天看不清楚,还不如重新
写一段来得快些。。。 [:(]
先回答程序中的问题:成交量和K线应该放在两个PaintBox中,或者在Form.canvas中严格
控制边界。 均线和K线是重叠的。

我考虑一下,做一个通用的东西出来看看。
 
请问如何在Form.canvas控制边界?谢谢。我在PaintBox中是否无法分界?
 
没人回答吗?
 

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);
我已作出一系列的点,上图k线,画完一条i:=i+1循环,请指教谢谢。
 
接受答案了.
 
顶部