這是一個解題範例的小程式
主要是讀取股票資料與指標計算方法之封裝
謹提供給有興趣的新手作為練習之用(內含測試資料檔)
整理其中有幾個學習重點:
(1)union record 的宣告方式
TStockRec = packed record
(2)預先宣告的方式與使用時機
ICalculator = interface; //pre-declaration of ICalculator
TCalculator = class; //pre-declaration of TCalculator
(3)物件之繼承關係
TStock = class(TPersistent)
TCalculator = class(TInterfacedObject, ICalculator)
TForm1 = class(TForm)
(4)以物件來作為資料之封裝
以一個 TStock 來封裝股票資料檔, 透過
Count(), 取得資料筆數
Rec[Index], 來存取特定資料錄(record)
Index(), 作為特定日期資料之搜尋
(5) 函式之覆載方式(overload)
function IndexOf(Date: Single; L, H: Integer): Integer; overload;
function IndexOf(Date: Single; var Index: Integer): Boolean; overload;
(6) 資料搜尋方法(使用遞迴方式)
function TStock.IndexOf(Date: Single; var Index: Integer): Boolean;
begin
Index := IndexOf(Int(Date), 0, Count-1);
Result := Index <> -1;
end;
function TStock.IndexOf(Date: Single; L, H: Integer): Integer;
var
M: Integer;
D: Single;
begin
Result := -1;
if L <= H then
begin
M := (L + H) shr 1;
D := PSingle(Rec[M])^;
if Date = D then Result := M
else if Date < D then Result := IndexOf(Date,L,M-1)
else Result := IndexOf(Date,M+1,H);
end;
end;
(7)物件方法與介面方法
ICalculator = interface(IUnknown)
function UDPer(Date: Single; Default: Single=0): Single;
function MA(Date: Single; MAC: Integer; Default: Single=0): Single;
end;
TCalculator = class(TInterfacedObject, ICalculator)
private
FStock: TStock;
public
constructor Create(Stock: TStock);
function UDPer(Date: Single; Default: Single=0): Single;
function MA(Date: Single; MAC: Integer; Default: Single=0): Single;
property Stock: TStock read FStock;
end;
(8)事件處理成序之共用, 及來源之辨別( 使用 TComponent.Tag)
procedure TForm1.FormCreate(Sender: TObject);
begin
Button1.Tag := 0;
Button2.Tag := 1;
Button3.Tag := 2;
Button1.forbidden := Button1Click;
Button2.forbidden := Button1Click;
Button3.forbidden := Button1Click;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
(略)
if Sender is TButton then
case TButton(Sender).Tag of
0: IterateStock(StringGrid1, Stock); //Button1
1: FindRec_With_Object_Function(Stock); //Button2(使用物件函式)
2: FindRec_With_Interface_Function(Stock);//Button3(使用介面函式)
end;
end;
(9)
TStringGrid.Rows與TStrings以及
TStrings與CommaText之間的運用
procedure TForm1.IterateStock(g: TStringGrid; Stock: TStock);
const
DATA_FORMAT: string = '%s,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f';
COLHEADER: string = '日期,開盤價,最高價,最低價,收盤價,漲跌,成交量';
var
I, Count: Integer;
sDate: string;
begin
g.Rows[0].CommaText := COLHEADER;
Count := Stock.Count;
g.RowCount := Count + 1;
for I := 0 to Count-1 do
with g.Rows[I+1], Stock[I]^ do
begin
sDate := FormatDateTime('YYYY-MM-DD', Date);
CommaText := Format(DATA_FORMAT,[sDate,OP,HP,LP,CP,UD,VOL]);
end;
end;
原帖地址:http://delphi.ktop.com.tw/board.php?cid=31&fid=97&tid=91548
相关程序下载:http://delphi.ktop.com.tw/download.php?download=upload%2F475385b4cdd0d_Test037.zip
主要是讀取股票資料與指標計算方法之封裝
謹提供給有興趣的新手作為練習之用(內含測試資料檔)
整理其中有幾個學習重點:
(1)union record 的宣告方式
TStockRec = packed record
(2)預先宣告的方式與使用時機
ICalculator = interface; //pre-declaration of ICalculator
TCalculator = class; //pre-declaration of TCalculator
(3)物件之繼承關係
TStock = class(TPersistent)
TCalculator = class(TInterfacedObject, ICalculator)
TForm1 = class(TForm)
(4)以物件來作為資料之封裝
以一個 TStock 來封裝股票資料檔, 透過
Count(), 取得資料筆數
Rec[Index], 來存取特定資料錄(record)
Index(), 作為特定日期資料之搜尋
(5) 函式之覆載方式(overload)
function IndexOf(Date: Single; L, H: Integer): Integer; overload;
function IndexOf(Date: Single; var Index: Integer): Boolean; overload;
(6) 資料搜尋方法(使用遞迴方式)
function TStock.IndexOf(Date: Single; var Index: Integer): Boolean;
begin
Index := IndexOf(Int(Date), 0, Count-1);
Result := Index <> -1;
end;
function TStock.IndexOf(Date: Single; L, H: Integer): Integer;
var
M: Integer;
D: Single;
begin
Result := -1;
if L <= H then
begin
M := (L + H) shr 1;
D := PSingle(Rec[M])^;
if Date = D then Result := M
else if Date < D then Result := IndexOf(Date,L,M-1)
else Result := IndexOf(Date,M+1,H);
end;
end;
(7)物件方法與介面方法
ICalculator = interface(IUnknown)
function UDPer(Date: Single; Default: Single=0): Single;
function MA(Date: Single; MAC: Integer; Default: Single=0): Single;
end;
TCalculator = class(TInterfacedObject, ICalculator)
private
FStock: TStock;
public
constructor Create(Stock: TStock);
function UDPer(Date: Single; Default: Single=0): Single;
function MA(Date: Single; MAC: Integer; Default: Single=0): Single;
property Stock: TStock read FStock;
end;
(8)事件處理成序之共用, 及來源之辨別( 使用 TComponent.Tag)
procedure TForm1.FormCreate(Sender: TObject);
begin
Button1.Tag := 0;
Button2.Tag := 1;
Button3.Tag := 2;
Button1.forbidden := Button1Click;
Button2.forbidden := Button1Click;
Button3.forbidden := Button1Click;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
(略)
if Sender is TButton then
case TButton(Sender).Tag of
0: IterateStock(StringGrid1, Stock); //Button1
1: FindRec_With_Object_Function(Stock); //Button2(使用物件函式)
2: FindRec_With_Interface_Function(Stock);//Button3(使用介面函式)
end;
end;
(9)
TStringGrid.Rows與TStrings以及
TStrings與CommaText之間的運用
procedure TForm1.IterateStock(g: TStringGrid; Stock: TStock);
const
DATA_FORMAT: string = '%s,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f';
COLHEADER: string = '日期,開盤價,最高價,最低價,收盤價,漲跌,成交量';
var
I, Count: Integer;
sDate: string;
begin
g.Rows[0].CommaText := COLHEADER;
Count := Stock.Count;
g.RowCount := Count + 1;
for I := 0 to Count-1 do
with g.Rows[I+1], Stock[I]^ do
begin
sDate := FormatDateTime('YYYY-MM-DD', Date);
CommaText := Format(DATA_FORMAT,[sDate,OP,HP,LP,CP,UD,VOL]);
end;
end;
原帖地址:http://delphi.ktop.com.tw/board.php?cid=31&fid=97&tid=91548
相关程序下载:http://delphi.ktop.com.tw/download.php?download=upload%2F475385b4cdd0d_Test037.zip