奇狐社區論壇
在這個頁面顯示本主題全部的 10 個文章

奇狐社區論壇 (http://www.chiefox.com.tw/bbs/index.php)
- [進階教學] (http://www.chiefox.com.tw/bbs/forumdisplay.php?forumid=46)
-- 04. 數列運算(陣列運算) 《適用4.0版》 (http://www.chiefox.com.tw/bbs/showthread.php?threadid=2649)


由 cgjj 在 2005-03-10 18:38 發表:

04. 數列運算(陣列運算) 《適用4.0版》



【何謂數列】






數列為多個數的組合(亦可稱為陣列、數組或序列)



例如公式中 Open 為開盤價 Close 為收盤價

Open 本身儲存每一個交易日的開盤價

Close 本身儲存每一個交易日的收盤價

Open 和 Close 都是數列

數列是由很多數組成的, 其中的數我們以元素稱呼之

一個數列中共存放有5個數, 我們說它共有5個元素

在奇狐中數列可直接對數列或數值做運算

也可以針對數列中的單一元素做運算存取




【數列的整組運算】






數列可直接與其它數值做整組運算, 例如:

   X:Close/2;

運算時會從第一個交易日算到最後一個交易日

將每日收盤價除2儲存於 X 這個數列當中



數列也可直接與其它數列做整組運算, 例如:

   X:Close-Open;

運算時會從第一個交易日算到最後一個交易日

將每日收減掉開儲存於 X 這個數列當中



【數列的元素運算】






數列的單一元素可用 x[n] 的方式來存取

例如 m[2] 為 m 這個數列裡的第2個元素

若該數列為系統預設的則無法直接存取

需先用一變數來儲存它再存取, 例如:

   CC:=C;

   XX:CC[2];

C 為系統預設的數列儲存每個交易日的收盤價

先將它轉存至CC這個變數, 再做後續的存取

計算後 XX 為第二個交易日的收盤價, XX 為數值(非數列)



※觀念挑戰










X:=2;

X:=C*0+2;

X:2;

X:C;

X:O-C;

M:=C; X:M[2];
X是數值

X是數列, C是數列

X是數值 (之前為數列, 自4.0.60208版起改為數值,
僅對VBS撰寫者有影響)


X是數列

X是數列

M是數列, X是數值 (之前為數列,
自4.0.60208版起改為數值, 僅對VBS撰寫者有影響)




【取得數列的最小編號與最大編號】






一個數列有很多個元素, 若將這些元素編號自最前頭開始編到最尾部(小到大)

最小編號(下界) 可用 LBOUND 函數來存取,
例如: MinNo:LBOUND(c);

最大編號(上界) 可用 UBOUND 函數來存取,
例如: MaxNo:UBOUND(c);

一般而言最小編號都是自1開始 (除非用 SETLBOUND 重設過)

若您有用移動平均等類似的指令最小編號就未必是 1 , 例如:

   CC:MA(C,2);

CC這個數列的最小編號是自2開始(因取兩天平均, 第二日CC的值才有效)

故應用時建議以 LBOUND(n) 做為迴圈起始(不要用1)





【無效數列】






當一個數列裡面沒有存放任何有效數值時,該數列我們稱之為無效數列。例如:

XX:Barslast(barpos=0);

上行公式中的XX就是一個無效數列,因為不可能會有barpos=0的條件成立。

無效數列其下界值必定為零。

因此我們可用 LBOUND 函數來檢驗數列是否有效(零為無效, 大於零為有效)。


由 cgjj 在 2005-03-10 18:39 發表:

【範例1】於第 1、50、100 根 K棒的位置畫垂直線






DlineY:=c*0;

DlineY[1]:=1;

DlineY[50]:=1;

DlineY[100]:=1;

VERTLINE(DlineY);


由 cgjj 在 2005-03-10 18:50 發表:

【範例2】求最後五日成交量的平均值






平均:0;

vv:=v;

maxno:=ubound(vv);

for i = maxno downto
maxno-5+1 do begin

  平均:=平均+vv[i];

end;

平均:=平均/5;


由 cgjj 在 2005-03-10 18:52 發表:

【範例3】求高的歷史最高價






MaxH:=0;

HH:=H;

minno:=lbound(HH);

maxno:=ubound(HH);

for i = minno to
maxno do begin

  if HH[i]>MaxH
then MaxH:=HH[i];

end;

最高:MaxH;


由 cgjj 在 2005-03-10 18:53 發表:


【範例4】求最近一次KD黃金交叉的收盤價






INPUT:N(9,1,100), M1(3,2,40),
M2(3,2,40);

RSV:=(CLOSE-LLV(LOW,N))/(HHV(HIGH,N)-LLV(LOW,N))*100,COLORCYAN;

K:=SMA(RSV,M1,1);

D:=SMA(K,M2,1);




CK:=CROSS(K,D);

CC:=C;

for i = ubound(ck)
downto lbound(ck)
do begin

  if CK[i]=1
then break;

end;

KDC:CC[i];




由 cgjj 在 2005-03-10 18:55 發表:

【範例5】求指定年份的最低價






FindYear  為指定的年份

MinLow    為該年份的最低價

     若為 -1 代表不存在該年份數據



FindYear:=2002;

UseY:=YEAR;

UseL:=LOW;

MinLow:=-1;

StartNo:= lbound(UseY);

EndNo:= ubound(UseY);

for i = StartNo to
EndNo do begin

  if UseY[i]
= FindYear then begin

    if UseL[i]
< MinLow or MinLow = -1 then
MinLow:= UseL[i];

  end;

end;


最低:MinLow;





由 cgjj 在 2005-03-10 18:57 發表:

【範例6】將成交量由小排到大(用氣泡式排序法)






此範例僅適合具程式設計基礎的用戶參考




■原來以 VBS 撰寫的方法

VV:VOL;

<%

VV = FFL.VarData("VV")

StartNo = lbound(VV)

EndNo = Ubound(VV)

for i = StartNo to EndNo-1

  for j = i+1 to EndNo

    if VV(i)>VV(j) then temp=VV(i):VV(i)=VV(j):VV(j)=temp


  end if

  next

next

FFL.VarData("VV") = VV

%>
<%

VV = FFL.VarData("VV")

StartNo = lbound(VV)

EndNo = Ubound(VV)

for i = StartNo to EndNo-1

for j = i+1 to EndNo

if VV(i)>VV(j) then

temp=VV(i):VV(i)=VV(j):VV(j)=temp

end if

next

next

FFL.VarData("VV") = VV

%>




■新版以數列撰寫的方法

VV:vol;

StartNo:= lbound(VV);

EndNo:= ubound(VV);

for i = StartNo to
EndNo-1 do begin

  for j = i+1
to
EndNo do begin

    if VV[i]>VV[j]
then begin


      temp:=VV[i]; VV[i]:=VV[j]; VV[j]:=temp;

    end;

  end;

end;




註:以上這兩種方法都跑的慢,有更簡易且高效率的方法喔

  請見 排序函數
SORT, SORTPOS
的介紹



由 cgjj 在 2005-03-10 21:48 發表:


【範例7】求當日那一個價成交量最多






MaxVolC 為其價

MaxVolV 為其量

請用分筆成交週期運算下列公式:




UseC:=C; UseV:=V; //為分筆成交 Close 和 Vol 的數列

RdC:=c*0; RdV:=c*0; //存分價分量 Close 和 Vol 的數列

KStNo:=lbound(UseC);

KEndNo:=ubound(UseC);

RdStNo:=KStNo; RdEndNo:=KStNo;

RdC[RdStNo]:=UseC[KEndNo];

RdV[RdStNo]:=UseV[KEndNo];

for KNo = KEndNo-1 downto
KStNo do begin //自近日開始往過去找尋

   for RdNo = RdStNo to
RdEndNo do begin

    if UseC[KNo]
= RdC[RdNo] then
begin //分價分量數列裡已有該價(累加該價的量)

      RdV[RdNo]:=RdV[RdNo]+UseV[KNo];


    end;

  end;

  if RdNo = RdEndNo + 1 then
begin //分價分量數列裡沒有該價(加入該價)

    RdEndNo := RdEndNo + 1;

    RdC[RdEndNo] := UseC[KNo];

    RdV[RdEndNo] := UseV[KNo];

  end;

end;

MaxV:=0; MaxRdNo:=0;

for RdNo = RdStNo to
RdEndNo do begin //
找出成交量最大的價


  if RdV[RdNo]>MaxV
then begin

    MaxV:=RdV[RdNo];
MaxRdNo:=RdNo;

  end;

end;

MaxVolC:RdC[MaxRdNo];

MaxVolV:RdV[MaxRdNo];



註:此公式運算時會先將當日每一個價的量先記錄於數列中,完成後再從中找量最多的那一個價

  若碰到有兩個價都是最多時, 取離目前時間最近的價。此公式僅適用於分筆成交週期。


由 cgjj 在 2005-03-11 09:04 發表:


【範例7 再簡化的結果】






UseC:=C; UseV:=V; //為分筆成交
Close 和 Vol 的數列


RdC:=c*0; RdV:=c*0; //存分價分量 Close 和 Vol 的數列

KStNo:=lbound(UseC);

KEndNo:=ubound(UseC);

RdStNo:=KStNo; RdEndNo:=0;

for KNo = KEndNo-1 downto
KStNo do begin //自近日開始往過去找尋

  for RdNo = RdStNo to
RdEndNo do begin

    if UseC[KNo]
= RdC[RdNo] then
begin //分價分量數列裡已有該價(累加該價的量)

      RdV[RdNo]:=RdV[RdNo]+UseV[KNo];


    end;

  end;

  if RdNo = RdEndNo + 1 then
begin //分價分量數列裡沒有該價(加入該價)

    RdEndNo := RdEndNo + 1;


    RdC[RdEndNo] :=
UseC[KNo];

    RdV[RdEndNo] :=
UseV[KNo];

  end;

end;

MaxV:=0; MaxRdNo:=0;

for RdNo = RdStNo to
RdEndNo do begin //
找出成交量最大的價


  if RdV[RdNo]>MaxV
then begin

    MaxV:=RdV[RdNo];
MaxRdNo:=RdNo;

  end;

end;

MaxVolC:RdC[MaxRdNo];

MaxVolV:RdV[MaxRdNo];




 後續教學 排序函數
SORT, SORTPOS
有更快的算法喔


由 cgjj 在 2006-11-07 16:21 發表:

20061107 更新Ok


全部時間均為台灣時間, 現在時間為06:04
在這個頁面顯示本主題全部的 10 個文章


Powered by: vBulletin Version 2.3.0 - Copyright©2000-, Jelsoft Enterprises Limited.

簡愛洋行 製作 Copyright 2003-. All Rights Reserved.