感謝七爺的無私幫助和糾正。
爲了儘可能地提高數據複用,可能給多個指標運算。所以獲取的週期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)