开一贴讨论用teechart控件做股票K线图(0分)

  • 主题发起人 主题发起人 scxxf
  • 开始时间 开始时间
S

scxxf

Unregistered / Unconfirmed
GUEST, unregistred user!
在teechart pro 5.2 中如何用自己的库数据来告诉teechart哪个是开盘价,哪个是收盘价等...
以便系统用我们自己的数据来画K线呢?
 
TeeChart来画股票图不好用,不如自已开发一个,或者找一个控件的;
有这样的例子,坐标系之类,光标停还弹出Hint窗口显示该点的相关信息;
以前我看了一下,不过市面有这样多好用的股票分析系统,所以我没有怎么继续下去;
 
关注是否有更好的控件,
如果有的话,通知我一声,谢谢,我高分相赠,
意想不到的高分哦.
 
青侠能不能继续下去,教我们一下如何做?已有程序并不重要,我们主要是在学习。
如果你是想做商业程序,也可以继续下去啊,如果比人家更好,一样可以卖钱。
据说“智超”股票软件可以提供早期源代码画K线的,
我向智超作者的信箱:zhichao2000@email.com.cn
写信无法传递到他的信箱,哪位朋友有他的信箱或是早期的源代码请来一份学习。

请高手续贴讨论

 
找一个teechar专业版,里面提供了K线图,你只需要把四个价格告诉它即可
我在三年前做股票系统就用的它
 
找几个CHART控件的源码读一读,你就可以自己做了。
 
写段小儿科给你参考参考

//定义类
type
TPointArray=Array of TPoint; //为绘制曲线定义的点集

TLogGraph=class;
TCurve=class;

TCurves=class(TCollection) //曲线集
private
FLogGraph:TLogGraph; //所指向的GraphicControl
function GetItem(index: Integer): TCurve;
procedure SetItem(index: Integer; const Value: TCurve);
protected
procedure Update(Item:TCollectionItem);override;
public
constructor Create(ALogGraph:TLogGraph);
function Add:TCurve; //添加曲线
function Insert(Index: Integer):TCurve; //插入曲线
procedure Clear; //清空
procedure Delete(Index: Integer); //删除曲线
property Item[index:Integer]:TCurve read GetItem write SetItem;default; //得到某一条
end;

TCurve=class(TCollectionItem)
private
FPointArray: TPointArray;
FCaption: String;
FBrush: TBrush;
FFont: TFont;
FPen: TPen;
procedure SetBrush(const Value: TBrush);
procedure SetCaption(const Value: String);
procedure SetFont(const Value: TFont);
procedure SetPen(const Value: TPen);
procedure SetPointArray(const Value: TPointArray);
public
property PointArray:TPointArray read FPointArray write SetPointArray; //对应的点集
published
property Pen:TPen read FPen write SetPen;
property Brush:TBrush read FBrush write SetBrush;
property Caption:String read FCaption write SetCaption;
property Font:TFont read FFont write SetFont;
procedure Paint(ACanvas:TCanvas);
procedure Assign(pt:TPersistent);override;
constructor Create(Collection: TCollection);override;
destructor Destroy; override;
end;


TLogGraph=class(TGraphicControl)
private
FCaption: String;
FBorderStyle: TBorderStyle;
FBrush: TBrush;
FCurves: TCurves;
FPen: TPen;
procedure SetBorderStyle(const Value: TBorderStyle);
procedure SetBrush(const Value: TBrush);
procedure SetCaption(const Value: String);
procedure SetPen(const Value: TPen);
Protected
public
constructor Create(Owner:TComponent);override;
destructor Destroy;override;
procedure Paint;override;
property Canvas;
published
property Pen:TPen read FPen write SetPen;
property Brush:TBrush read FBrush write SetBrush;
property Caption:String read FCaption write SetCaption;
property Font;
property BorderStyle:TBorderStyle read FBorderStyle write SetBorderStyle default bsNone;
property Curves:TCurves read FCurves write Fcurves;
//property Marks:TMarks read FMarks write SetMarks;

end;



implementation

{ TCurves }

function TCurves.Add: TCurve;
begin
result:=TCurve(inherited Add);
end;

procedure TCurves.Clear;
begin
inherited Clear;
end;

constructor TCurves.Create(ALogGraph: TLogGraph);
begin
inherited Create(TCurve);
FLogGraph:=ALogGraph;
end;

procedure TCurves.Delete(Index: Integer);
begin
inherited Delete(Index);
end;

function TCurves.GetItem(index: Integer): TCurve;
begin
result:=TCurve(inherited GetItem(Index));
end;

function TCurves.Insert(Index: Integer): TCurve;
begin
result:=TCurve(inherited Insert(Index));
end;

procedure TCurves.SetItem(index: Integer; const Value: TCurve);
begin
inherited SetItem(Index,Value);
end;

procedure TCurves.Update(Item: TCollectionItem);
begin
//inherited;
if Item<>nil then
FLogGraph.Invalidate;
end;

{ TCurve }

procedure TCurve.Assign(pt: TPersistent);
begin
inherited;

end;

constructor TCurve.Create(Collection: TCollection);
//APointArray: TPointArray);
begin
inherited Create(Collection);
FPen:=TPen.Create;
FBrush:=TBrush.Create;
FFont:=TFont.Create ;

// if Assigned(APointArray) then
// FPointOfArray:=@APointArray;
end;

destructor TCurve.Destroy;
begin
FPen.Free;
FBrush.Free;
FFont.Free;
inherited;
end;

procedure TCurve.Paint(ACanvas: TCanvas);
var
i:Integer;
begin
with Acanvas do
begin
Pen:=FPen;
Brush:=FBrush;
Font:=FFont;
end;
ACanvas.MoveTo(FPointArray[0].x,FPointArray[0].y);
for I:=Low(FPointArray)+1 to High(FPointArray) do
ACanvas.LineTo(FPointArray.x,FPointArray.y);

end;

procedure TCurve.SetBrush(const Value: TBrush);
begin
FBrush := Value;
end;

procedure TCurve.SetCaption(const Value: String);
begin
FCaption := Value;
end;

procedure TCurve.SetFont(const Value: TFont);
begin
FFont := Value;
end;



procedure TCurve.SetPen(const Value: TPen);
begin
FPen := Value;
end;

procedure TCurve.SetPointArray(const Value: TPointArray);
begin
FPointArray := Value;
end;

{ TLogGraph }

constructor TLogGraph.Create(Owner: TComponent);
begin
inherited;
FCurves:=TCurves.Create(self);
FBorderStyle:=bsNone;
FPen:=TPen.Create;
FBrush:=TBrush.Create;
end;

destructor TLogGraph.Destroy;
begin
FPen.Free;
FBrush.Free;
inherited;
end;

procedure TLogGraph.Paint;
var
i:Integer;
begin
inherited;
with Canvas do
begin
Pen:=FPen;
Brush:=FBrush;
end;
case FBorderStyle of
bsSingle:Canvas.Rectangle(0,0,width,Height);
end;
for I:=0 to FCurves.Count-1 do
FCurves.Item.Paint(Canvas);

end;

procedure TLogGraph.SetBorderStyle(const Value: TBorderStyle);
begin
FBorderStyle := Value;
end;

procedure TLogGraph.SetBrush(const Value: TBrush);
begin
FBrush := Value;
end;

procedure TLogGraph.SetCaption(const Value: String);
begin
FCaption := Value;
end;

procedure TLogGraph.SetPen(const Value: TPen);
begin
FPen := Value;
end;

//结束类的定义,单元名LogGraph,以上为单元中有用的部分,copy即可

使用例子
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,LogGraph{定义的单元},
StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}


procedure TForm1.Button1Click(Sender: TObject);
var
Log:TLogGraph;
ACurve:TCurve;
s,s1:TPointArray;
I:Integer;
begin
Log:=TLogGraph.Create(Form1);
Log.Parent:=Form1;
Log.Left:=10;
Log.Top:=10;
Log.Width :=500;
Log.Height:=500;

SetLength(s,100);
for i:=0 to 99 do
begin
s.x:=i;
s.y:=i*2;
end;
SetLength(s1,100);
for i:=0 to 99 do
begin
s1.x:=i;
s1.y:=trunc(abs(sin(i))*50)+50;
end;
ACurve:=TCurve.Create(Log.Curves);
Log.Curves[0].PointArray:=S;
Log.Curves.Add ;
Log.Curves[1].PointArray :=s1 ;
Log.BorderStyle:=bsSingle;
Log.Paint;
end;

end.


 
好小伙,居然0分的贴
 
好家伙,居然看出来是0分的贴... ^o^。我很想给高分,可惜我只有5分了,我很想给5分
但一想:居然只跟5分,太有辱高手了嘛!仅凭这么长的程序给我等初学者,给500分也不够啊
。所以只有给0分。wk_knife不要见怪啊!后来的高手不要没分就不发帖哟!

看完贴后请提前一下,让更多的高手参与进来!
新时代的活雷锋都来参加讨论啊!
 
teechar专业版,里面提供了K线图,你只需要把四个价格告诉它即可,但如何告诉teechart
,我没学会?指点一下!谢谢!
 
{**********************************************************************}
{*程序描述: 如何用Delphi读钱龙数据画股票k线图范例 *}
{* 程序 : 战晓冬 *}
{* 编译器 : Borland Delphi Enterprise 5.0 (Build5.62)*}
{* Copyright(C) : 战晓冬 2000 *}
{**********************************************************************}
unit StockUn;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ComCtrls, ToolWin, Menus, ExtCtrls, TeeProcs, TeEngine, Chart, mxgraph,
Series, StdCtrls, ArrowCha, Buttons;
type
TStockRec = packed record {定义一个记录,保存股票信息。}
Date: Longint; {时间}
Open:longint; {开盘}
High:longint; {最高价}
Low:longint; {最低价}
Close:longint; {收盘}
Amount:longint; {成交额}
Volume:longint; {成交量}
Topiece:longint;
X1:longint;
X2:longint;
end;

TRecordStream = class(TFileStream)
private
function GetNumRecs: Longint;
function GetCurRec: Longint;
procedure SetCurRec(RecNo: Longint);
protected
function GetRecSize: Longint; virtual;
public
function SeekRec(RecNo: Longint; Origin: Word): Longint;
function WriteRec(const Rec): Longint;
function AppendRec(const Rec): Longint;
function ReadRec(var Rec): Longint;
procedure First;
procedure Last;
procedure NextRec;
procedure PreviousRec;
property NumRecs: Longint read GetNumRecs;
property CurRec: Longint read GetCurRec write SetCurRec;
end;

TStockForm = class(TForm)
StatusBar1: TStatusBar;
Chart1: TChart;
Series1: TLineSeries;
Series2: TFastLineSeries;
Series3: TFastLineSeries;
Series4: TFastLineSeries;
SpeedButton1: TSpeedButton;
Label1: TLabel;
Label2: TLabel;
procedure Chart1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormActivate(Sender: TObject);
procedure Series1AfterDrawValues(Sender: TObject);
procedure SpeedButton1Click(Sender: TObject);
procedure Chart1AfterDraw(Sender: TObject);

private
{ Private declarations }
public
{ Public declarations }
OldX,OldY:Longint;
CrossHairColor:TColor;
CrossHairStyle:TPenStyle;
stockRec: TstockRec;
RecordStream: TRecordStream;
DayFile:File of TStockRec;
Fname:String;
procedure ChartADDData;
procedure DrawCross(AX,AY:Integer);
end;


var
StockForm: TStockForm;

implementation

function TRecordStream.GetRecSize:Longint; {返回记录长度}
begin
Result := SizeOf(TStockRec);
end;

function TRecordStream.GetNumRecs: Longint; {返回记录个数}
begin
Result := Size div GetRecSize;
end;

{返回当前记录位置,文件指针通常在记录的开始,而非Position div GetRecSize处。}
function TRecordStream.GetCurRec: Longint;
begin
Result := (Position div GetRecSize) + 1;
end;

procedure TRecordStream.SetCurRec(RecNo: Longint); {通过RecNo将记录定位}
begin
if RecNo > 0 then
Position := (RecNo - 1) * GetRecSize
else
Raise Exception.Create('Cannot go beyond beginning of file.');
end;

{通过RecNo将文件指针定位}
function TRecordStream.SeekRec(RecNo: Longint; Origin: Word): Longint;
begin
Result := Seek(RecNo * GetRecSize, Origin);
end;

function TRecordStream.WriteRec(Const Rec): Longint; {将记录Rec写入流中}
begin
Result := Write(Rec, GetRecSize);
end;

function TRecordStream.AppendRec(Const Rec): Longint; {将记录Rec写入流中}
begin
Seek(0, 2);
Result := Write(Rec, GetRecSize);
end;

function TRecordStream.ReadRec(var Rec): Longint; {从流中读取记录并将指针返回记录开始}
begin
Result := Read(Rec, GetRecSize);
Seek(-GetRecSize, 1);
end;

procedure TRecordStream.First; {将指针返回流的开始}
begin
Seek(0, 0);
end;

procedure TRecordStream.Last; {将指针返回流的末尾}
begin
Seek(0, 2);
Seek(-GetRecSize, 1);
end;

procedure TRecordStream.NextRec; {只要未到文件末尾,就将文件指针定在下一记录处}
begin
if ((Position + GetRecSize) div GetRecSize) = GetNumRecs then
raise Exception.Create('Cannot read beyond end of file')
else
Seek(GetRecSize, 1);
end;

procedure TRecordStream.PreviousRec;{只要未到文件开始,就将文件指针定在前一记录处}
begin
if (Position - GetRecSize >= 0) then
Seek(-GetRecSize, 1)
else
Raise Exception.Create('Cannot read beyond beginning of the file.');
end;


{$R *.DFM}

procedure TStockForm.Chart1MouseMove(Sender: TObject; Shift: TShiftState;
X, Y: Integer);
var
tmpX,tmpY:Double;
begin
if (OldX<>-1) then
begin
DrawCross(OldX,OldY); {画小十字鼠标}
OldX:=-1;
end;
{检查鼠标是否在图表区}
if PtInRect( Chart1.ChartRect, Point(X-Chart1.Width3D,Y+Chart1.Height3D)) then
begin
DrawCross(x,y); {在当前位置画十字准线}
OldX:=x; {保存旧位置}
OldY:=y;
With Series1 do {设置标签文本}
begin
GetCursorValues(tmpX,tmpY); {获取鼠标位置数据}
Label1.Caption:=GetVertAxis.LabelValue(tmpY)+' '+
GetHorizAxis.LabelValue(tmpX);
end;
end;
end;


procedure TStockForm.FormCreate(Sender: TObject);
begin
OldX:=-1; {初始化变量}
CrossHairColor:=clRed; {颜色}
CrossHairStyle:=psSolid; {线形}
Fname:='600734.Day';
if FileExists(FName) then
RecordStream := TRecordStream.Create(FName, fmOpenReadWrite)
else
RecordStream := TRecordStream.Create(FName, fmCreate);
end;

procedure TStockForm.FormDestroy(Sender: TObject);
begin
RecordStream.Free;
end;

procedure TStockForm.FormActivate(Sender: TObject);
begin
RecordStream.Last;
ChartADDData;
while (((RecordStream.Position + 40) div 40) > RecordStream.NumRecs-9) do
begin
RecordStream.PreviousRec;
ChartADDData;
end;
end;

procedure TStockForm.ChartADDData;
var
FormatDayLineDateYear,FormatDayLineDateMonth,
FormatDayLineDateDay,FormatDayLineDate,DayLineDate:string;
begin
RecordStream.ReadRec(stockRec);
DayLineDate:=IntToStr(StockRec.Date);{将日期数转化成字符串}
FormatDayLineDateYear:=Copy(DayLineDate,2,2);{分离出年}
FormatDayLineDateMonth:=Copy(DayLineDate,5,2);{分离处月}
FormatDayLineDateDay:=Copy(DayLineDate,7,2); {分离出日}
FormatDayLineDate:=Concat(FormatDayLineDateYear,'-',FormatDayLineDateMonth,'-',FormatDayLineDateDay);

Series1.Add((stockRec.open / 1000),FormatDayLineDate,clBlack);
Series2.Add((stockRec.close / 1000),FormatDayLineDate,clTeeColor);
Series3.Add((stockRec.Low / 1000),FormatDayLineDate,clTeeColor);
Series4.Add((stockRec.High / 1000),FormatDayLineDate,clTeeColor);
end;

procedure TStockForm.DrawCross(AX,AY:Integer); {画十字线鼠标}
begin
With Chart1,Canvas do
begin
Pen.Color:=CrossHairColor; {画笔颜色}
Pen.Style:=CrossHairStyle; {画笔类型}
Pen.Mode:=pmXor; {如何画线}
Pen.Width:=1; {画笔宽度}
MoveTo(ax,ChartRect.Top-Height3D);
LineTo(ax,ChartRect.Bottom-Height3D);
MoveTo(ChartRect.Left+Width3D,ay);
LineTo(ChartRect.Right+Width3D,ay);
end;
end;

procedure TStockForm.Series1AfterDrawValues(Sender: TObject);
begin
OldX:=-1; {重置鼠标原来位置}
end;

procedure TStockForm.SpeedButton1Click(Sender: TObject);
begin
Series1.Clear;
RecordStream.First;
ChartADDData;
while ((RecordStream.Position + 40) div 40) < RecordStream.NumRecs do
begin
RecordStream.NextRec;
ChartADDData;
end;
RecordStream.last;
ChartADDData;
end;

procedure TStockForm.Chart1AfterDraw(Sender: TObject); {画阴阳线}
var
XValueNO:integer; {X轴点}
begin
With Chart1,Canvas do
begin
for XValueNO:=0 to Series1.LastValueIndex do
begin
begin
if (Series1.CalcyPos(XValueNO) < Series2.CalcyPos(XValueNO)) then
begin
Brush.Color:=clWhite;
Pen.Color:=clWhite; {画笔颜色}
end
else
begin
Brush.Color:=clRed;
Pen.Color:=clRed;
end;
end;
Pen.Style:=pssolid; {画笔类型}
Pen.Width:=1;
begin
MoveTo(Series3.CalcXPos(XValueNO) ,Series3.CalcyPos(XValueNO));
LineTo(Series4.CalcXPos(XValueNO) ,Series4.CalcyPos(XValueNO));
Rectangle(Series1.CalcXPos(XValueNO)-5,Series1.CalcyPos(xValueNO),
Series1.CalcXPos(XValueNO)+5,Series2.CalcyPos(xValueNO));
end;
end;
end;
end;

end.
 
战晓冬老师的文章我已拜读,我等初学者读来还有点费力,恐怕花费时间较长,
能不能麻烦一下将注释做多点?这个要求可能有点过份。但我想高手在此指定
一下,注释做详细点,我花的时间就少些,进步快一些。我想这是每个初学者
的愿望,望高手成全。谢谢!再谢谢![:D]
 
有没有呀....
 
why_119,有没有什么?你把意思说明白!
 
用自己的库向teechart提供数据的方法我已解决:
1、要用Data Controls 中的Tdbchart控件。
2、加入一个Table控件。
3、在Tdbchart中的series中的data source中的dataset指定用Table,将Table中active
属性改为true;将dataset中close、open之类的属性和自己库的字段相对应。
4、在Tdchart中的tool栏中加入cursor,并将follow mouse前选中。就可以实现十字线。

还没有解决的问题有如下:
1、如何指定一个屏幕显示指定数目的K线数量,按左箭头和右箭头实现K线图左、右移动。
2、将光标移动某天的K线柱上显示相关的一些注释。
 
你说的两点我去年都做过了,等下我找找看不家没有。
 
好,期待你的答案出现
 
我放在这儿了,拉吧。
应该全在这里面,都快半年了快忘记了,没重新打开看。
http://cst.mine.nu/stock.rar
 
wxws兄:
您的程序编译时出现:
error reading series_vol.linepen.endstyle:property endstyle does not exist.
以下这一点做到了:
将光标移动某天的K线柱上显示相关的一些注释。
但以下一点没做到,应该怎么做?请指教:
1、如何指定一个屏幕显示指定数目的K线数量,按左箭头和右箭头实现K线图左、右移动。
2、按下箭头和上箭头进行K线图的放大和缩小。
3、禁止按住鼠标右键不动移动图形,按住鼠标左键不动后可转动图形。
 

Similar threads

D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
1K
DelphiTeacher的专栏
D
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
后退
顶部