Delphi 計算火幣網KDJ指標數值

感謝七爺的無私幫助和糾正。
爲了儘可能地提高數據複用,可能給多個指標運算。所以獲取的週期K線數據保存到了一個數組。定義如下:

  //存儲K線數據的結構
  TKline=record
    Open  :Extended;
    High  :Extended;
    Low   :Extended;
    Close :Extended;
    Amount:Extended;
  end;
  TKlineArray = array of TKline;
  //一些拖沓的常量
const
  KLINE_PERIOD_1MINUTE_CODE  = '001';
  KLINE_PERIOD_5MINUTE_CODE  = '005';
  KLINE_PERIOD_15MINUTE_CODE = '015';
  KLINE_PERIOD_30MINUTE_CODE = '030';
  KLINE_PERIOD_1HOUR_CODE    = '060';
  KLINE_PERIOD_1DAY_CODE     = '100';
  KLINE_PERIOD_1MONTH_CODE   = '200';
  KLINE_PERIOD_1YEAR_CODE    = '300';
  KLINE_PERIOD_1MINUTE       = 1;
  KLINE_PERIOD_5MINUTE       = 2;
  KLINE_PERIOD_15MINUTE      = 3;
  KLINE_PERIOD_30MINUTE      = 4;
  KLINE_PERIOD_1HOUR         = 5;
  KLINE_PERIOD_1DAY          = 6;
  KLINE_PERIOD_1MONTH        = 7;
  KLINE_PERIOD_1YEAR         = 8;

獲取15分週期到數組

{ 獲取火幣K線數據 
    Exp:
         var klinearr:TKlineArray;
         klinearr := GetHuobiKLine(KLINE_PERIOD_15MINUTE);
}
function GetHuobiKLine(KLINE_PERIOD:Integer):TKlineArray;
var
  sPeriodCode:string;
  sURL,sSource:string;
  jo:ISuperObject;
  arrKline:TSuperArray;
  i:Integer;
begin
  SetLength(Result,0);
  case KLINE_PERIOD of
    KLINE_PERIOD_1MINUTE:  sPeriodCode := KLINE_PERIOD_1MINUTE_CODE;
    KLINE_PERIOD_5MINUTE:  sPeriodCode := KLINE_PERIOD_5MINUTE_CODE;
    KLINE_PERIOD_15MINUTE: sPeriodCode := KLINE_PERIOD_15MINUTE_CODE;
    KLINE_PERIOD_30MINUTE: sPeriodCode := KLINE_PERIOD_30MINUTE_CODE;
    KLINE_PERIOD_1HOUR:    sPeriodCode := KLINE_PERIOD_1HOUR_CODE;
    KLINE_PERIOD_1DAY:     sPeriodCode := KLINE_PERIOD_1DAY_CODE;
    KLINE_PERIOD_1MONTH:   sPeriodCode := KLINE_PERIOD_1MONTH_CODE;
    KLINE_PERIOD_1YEAR:    sPeriodCode := KLINE_PERIOD_1YEAR_CODE;
  end;
  sURL    := 'http://api.huobi.com/staticmarket/btc_kline_'+sPeriodCode+'_json.js';
  sSource := GetPageSrc(sURL);
  if pos('[[', sSource) <> 0 then
  begin
    jo := SO(sSource);
    if Assigned(jo) then
    begin
      arrKline := jo.AsArray;
      SetLength(Result,arrKline.Length);
      for i :=0 to arrKline.Length-1 do
      begin
        Result[i].Open    := arrKline[i].AsArray[1].AsDouble;
        Result[i].High    := arrKline[i].AsArray[2].AsDouble;
        Result[i].Low     := arrKline[i].AsArray[3].AsDouble;
        Result[i].Close   := arrKline[i].AsArray[4].AsDouble;
        Result[i].Amount  := arrKline[i].AsArray[5].AsDouble;
      end;
    end;
  end;
end;

KDJ數據結構和計算

type
{ K線數據結構 }
  TKDJ=record
    K : Extended;
    D : Extended;
    J : Extended;
    PDK : Extended;
    PDD : Extended;
    PDJ : Extended;
  end;
  TKDJArray = array of TKDJ;

{ 計算KDJ函數 返回最後一個 }
function GetKDJOriginal(KlineArr: TKlineArray; PERIOD_NUM: Integer): TKDJ;
var
  RSV_P,H9_P,L9_P,PDK,PDD,PDJ:Extended;
  i,j:Integer;
  Arr: TKlineArray;
begin
  FillChar(Result, SizeOf(TKDJ), #0);
//  SetLength(Result,2);
  Arr := KlineArr;
  if High(Arr) <> -1 then
  begin
    PDK := 50;
    PDD := 50;
    for I :=Low(Arr) to High(Arr) do
    begin
      Result.PDK := PDK;
      Result.PDD := PDD;
      Result.PDJ := PDJ;
      if I < PERIOD_NUM then Continue;
      H9_P := 0;
      L9_P := 0;
      for J := (I-PERIOD_NUM+1) to I do
      begin
        if H9_P=0 then H9_P := Arr[J].High;
        if L9_P=0 then L9_P := Arr[J].Low;
        H9_P := Max(H9_P, Arr[J].High);
        L9_P := Min(L9_P, Arr[J].Low);
      end;
      RSV_P := ((Arr[I].Close - L9_P) / (H9_P - L9_P)) * 100;
      Result.K   := 2/3*PDK + 1/3*RSV_P;
      Result.D   := 2/3*PDD + 1/3*Result.K;
      Result.J   := (Result.K*3)-(Result.D*2);
      PDK        := TruncTo(Result.K, 2);
      PDD        := TruncTo(Result.D, 2);
      PDJ        := TruncTo(Result.J, 2);
    end;
    Result.K := TruncTo(Result.K, 2);
    Result.D := TruncTo(Result.D, 2);
    Result.J := TruncTo(Result.J, 2);
  end;
end;

//使用例子
MyKDJ := GetKDJOriginal(klinearr,9);//KDJ(9,3,3)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章