讀取股票資料檔與指標計算方法之封裝

這是一個解題範例的小程式
主要是讀取股票資料與指標計算方法之封裝
謹提供給有興趣的新手作為練習之用(內含測試資料檔)

整理其中有幾個學習重點:
(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
posted @ 2009-03-23 12:35  撞上安全岛  阅读(231)  评论(0编辑  收藏  举报