新增函數(shù)應(yīng)用:如何遍歷板塊股票代碼
PHP代碼:--------------------------------------------------------------------------------
bk:='深圳A股';
variable:j=1,k=0,dm_len=0,lstr[6]='00000',blksum:=STKCOUNT(bk),dmstr[blksum]='';
lstr[2]:='0000';lstr[3]:='000';lstr[4]:='00';lstr[5]:='0';lstr[6]:='';
while j<=blksum do begin
dm:=NumToStr(k,0);
dm_len:=strlen(dm);
dm:=lstr[dm_len]+dm;
if stkinblock(dm,bk) then begin
dmstr[j]:=dm;
j:=j+1;
end;
k:=k+1;
end;
//以下是一些字符串函數(shù)及運(yùn)算的綜合應(yīng)用
EXPLAIN(1,dmstr[1]); //在解盤中,輸出深圳A股第1只股票的代碼
EXPLAIN(1,stknameex(dmstr[2]));//第2只股票的名稱
EXPLAIN(1,dmstr[3]+stknameex(dmstr[3]));//第3只股票的代碼及名稱
EXPLAIN(1,'深圳A股第4只股票的代碼是:'+dmstr[4]);
EXPLAIN(1,dmstr[5]+'最后收盤價:'+numtostr(close,2));
EXPLAIN(1,'深圳A股共有股票:'+numtostr(blksum,0)+'只');--------------------------------------------------------------------------------
如果您有編程的功底,上面代碼一看就明白,但對沒有編程經(jīng)驗(yàn)的狐友們來說就不容易了。下面盡量詳細(xì)地對思路和公式代碼做一些解說,并對代碼進(jìn)行適當(dāng)擴(kuò)展。
1、所謂遍歷股票代碼,就是能夠訪問某板塊中所有的股票代碼,如果連訪問都不能實(shí)現(xiàn),怎么做一些更加強(qiáng)大的諸如橫向統(tǒng)計(jì)、排序的功能?
2、上面的公式代碼是以深圳A股板塊為例,我們看看深圳A股的股票代碼,它們都是很有規(guī)律的,000001、000002、...、000999、001696、001896,請注意這些代碼的特征:
?、俟善贝a要理解成字符串,而不是數(shù)值,如果是數(shù)值的話,股票代碼就成了1、2、...、999、1696、1896。
②這些代碼如果轉(zhuǎn)換成數(shù)值,大體集中在某個數(shù)的范圍,如上面所示,深圳A股代碼的數(shù)值目前都小于1896,代碼的數(shù)值大多都是呈遞增1的規(guī)律,少量有跳躍的情況,比如000040跳到000042,000041不存在。
因此,我們初步可以設(shè)計(jì)一個循環(huán)
PHP代碼:--------------------------------------------------------------------------------
j:=0;
while j<=1896 do
begin
j:=j+1;
end;--------------------------------------------------------------------------------
上面這段代碼,是個循環(huán),每次循環(huán)都執(zhí)行一次由begin和end所包圍起來的語句,這里只有一條語句即j:=j+1,目的讓變量j從1每次循環(huán)都遞增1,直到j(luò)=1896為止。
j:=j+1這條賦值語句,初次接觸的話不大好理解,大意是這樣,右邊的j比如現(xiàn)在等于2,這條語句是讓右邊的j現(xiàn)有的數(shù)值加上1,然后再送回到變量j之中,執(zhí)行完這條語句后,j就由2遞增1變成了等于3。
j:=j+1,看起來有點(diǎn)象計(jì)數(shù)器的功能吧?每循環(huán)一次,計(jì)數(shù)器就增加1,因此也可以稱變量j為計(jì)數(shù)器(變量)。
好了,思路敏捷的狐友,馬上就能想到,這個計(jì)數(shù)器會生成從0到1896總共1897個數(shù)值,如果進(jìn)行轉(zhuǎn)換,也就是把數(shù)值轉(zhuǎn)換成字符串,則深圳A股所有的股票代碼都包含在里面了。
呵呵,的確是這樣,因此我們設(shè)計(jì)下面一個稍加改進(jìn)的循環(huán),來逼近我們要完成的任務(wù):
PHP代碼:--------------------------------------------------------------------------------
j:=0;
while j<=1896 do
begin
dm:=NumToStr(j,0); //把數(shù)值j轉(zhuǎn)換成字符串并賦值給變量dm,保留小數(shù)位數(shù)0
j:=j+1;
end;
EXPLAIN(islastbar,dm); //當(dāng)處在最后一根K線位置時,輸出字符串dm的內(nèi)容--------------------------------------------------------------------------------
最后一行代碼,是用解盤函數(shù)輸出字符串變量dm的結(jié)果,我們可以在“解”中觀察,不過這里由于dm是單值變量,不是序列變量,只能保存最后的一次結(jié)果,因此只能觀察到結(jié)果是1896。
如果想觀察其它的結(jié)果,只好改循環(huán)首語句,比如:
while j<=1 do
大家可以發(fā)現(xiàn)這些結(jié)果,還有一點(diǎn)小問題,沒有前導(dǎo)的0,即我們要的是000001、0001896,而不是1、1896這樣的字符串,怎么辦呢?
給它們的前面加上0就可以了,但加上0的個數(shù)有講究的,比如1在前面要加上5個0,1896前面只需加上2個0,很明顯,要加的0的個數(shù),等于6減字符串的字符個數(shù)。因此,設(shè)計(jì)公式代碼如下:
PHP代碼:--------------------------------------------------------------------------------
variable:lstr[6]='00000';//定義一個數(shù)組lstr[6],共6個元素,并讓所有6個元素初始都等于字符串'00000'
//下面對字符串?dāng)?shù)組lstr[]第2至第6個元素重新進(jìn)行賦值,以便巧妙應(yīng)用
lstr[2]:='0000';lstr[3]:='000';lstr[4]:='00';lstr[5]:='0';lstr[6]:='';
j:=0;
while j<=1896 do
begin
dm:=NumToStr(j,0); //把數(shù)值j轉(zhuǎn)換成字符串并賦值給變量dm,保留小數(shù)位數(shù)0
dm_len:=strlen(dm); //求出dm的長度,并賦值給變量dm_len
dm:=lstr[dm_len]+dm; //由dm的長度,確定應(yīng)該給dm的前面加上多少個字符0
j:=j+1;
end;
EXPLAIN(islastbar,dm); //當(dāng)處在最后一根K線位置時,輸出字符串dm的內(nèi)容-------------------------------------------------------------------------------- 對這行代碼稍加解釋:dm:=lstr[dm_len]+dm,如果某次循環(huán)右邊的dm等于'19',則它的字符串長度為dm_len等于2,則這行代碼此時等價于dm:=lstr[2]+dm,而lstr[2]等于'0000',結(jié)果就是在'19'的前面加上4個字符'0'即成了'000019',然后再把'000019'賦值給dm,于是左邊的dm就等于'000019'
到此為止,我們只是實(shí)現(xiàn)了所生成的字符串,可以讓深圳A股的代碼全部被包含在其中,但還有大量的“廢”字符串,我們要把沒用的字符串過濾掉。取出我們真正需要的。 要用到的函數(shù) ?、賡tkinblock(dm,bk),函數(shù)注釋:如果股票代碼dm從屬于板塊bk,則函數(shù)返回?cái)?shù)值1,否則返回?cái)?shù)值0 ?、跅l件控制語句IF cond THEN expr1 ELSE expr2,意思是:當(dāng)滿足 cond 條件的時候,執(zhí)行語句 expr1,否則執(zhí)行 expr2 語句 設(shè)計(jì)代碼如下:PHP代碼:--------------------------------------------------------------------------------
variable:lstr[6]='00000';
lstr[2]:='0000';lstr[3]:='000';lstr[4]:='00';lstr[5]:='0';lstr[6]:='';
j:=0;
bk:='深圳A股'; //bk賦值為字符串'深圳A股'
while j<=1896 do
begin
dm:=NumToStr(j,0); //把數(shù)值j轉(zhuǎn)換成字符串并賦值給變量dm,保留小數(shù)位數(shù)0
dm_len:=strlen(dm); //求出dm的長度,并賦值給變量dm_len
dm:=lstr[dm_len]+dm; //由dm的長度,確定應(yīng)該給dm的前面加上多少個字符0
if stkinblock(dm,bk) then //如果股票代碼dm屬于bk,則執(zhí)行下面由begin、end包含的語句
begin
dm1:=dm; //真正需要的股票代碼是這里的dm1
end;
j:=j+1;
end;
EXPLAIN(islastbar,dm1); //當(dāng)處在最后一根K線位置時,輸出字符串dm1的內(nèi)容--------------------------------------------------------------------------------
公式代碼設(shè)計(jì)到這里似乎可以結(jié)束了,因?yàn)槲覀円慕Y(jié)果都可以生成了。其實(shí)還有改進(jìn)的余地: ?、賒m1只是個單值的字符串變量,它只能保存最后的結(jié)果,而不能保存所有的結(jié)果。這里考慮使用數(shù)組,數(shù)組可以自行定義很多個元素,讓每個元素保存一個結(jié)果?! 、谘h(huán)首的j<1896總覺得不對勁,不夠智能化,比如將來“深圳A股”板塊最后的代碼不是0001896,則這段公式代碼的結(jié)果就不對了?! ♂槍σ陨蠁栴},設(shè)計(jì)公式代碼如下: PHP代碼:--------------------------------------------------------------------------------
variable:lstr[6]='00000';
lstr[2]:='0000';lstr[3]:='000';lstr[4]:='00';lstr[5]:='0';lstr[6]:='';
j:=0; //記錄循環(huán)次數(shù)的計(jì)數(shù)器
k:=1; //記錄股票代碼的個數(shù)的計(jì)數(shù)器
bk:='深圳A股'; //bk賦值為字符串'深圳A股'
blksum:=STKCOUNT(bk); //板塊所包含證券數(shù)量
variable:dmstr[blksum]=''; //定義一個字符串?dāng)?shù)組用于記錄股票代碼,元素個數(shù)為blksum,初始值為空
while k<=blksum do //當(dāng)計(jì)數(shù)器k<=blksum時,執(zhí)行以下循環(huán)
begin
dm:=NumToStr(j,0); //把數(shù)值j轉(zhuǎn)換成字符串并賦值給變量dm,保留小數(shù)位數(shù)0
dm_len:=strlen(dm); //求出dm的長度,并賦值給變量dm_len
dm:=lstr[dm_len]+dm; //由dm的長度,確定應(yīng)該給dm的前面加上多少個字符0
if stkinblock(dm,bk) then //如果股票代碼dm屬于bk,則執(zhí)行下面由begin、end包含的語句
begin
dmstr[k]:=dm; //真正需要的股票代碼,記錄到字符串?dāng)?shù)組dmstr的第k個元素中
k:=k+1; //記錄找到的股票代碼的個數(shù)
end;
j:=j+1; //記錄循環(huán)的次數(shù)
end;
EXPLAIN(islastbar,dmstr[1]); //當(dāng)處在最后一根K線位置時,輸出深圳A股第1只股票的代碼--------------------------------------------------------------------------------
有了以上公式,我們就可以把范圍擴(kuò)大,比如遍歷'A股板塊'的所有股票代碼,很簡單,只需改一條語句,即把 bk:='深圳A股' 改成 bk:='A股板塊'?! 」酱a如下(且慢執(zhí)行,等下面的解說):PHP代碼:--------------------------------------------------------------------------------
variable:lstr[6]='00000';
lstr[2]:='0000';lstr[3]:='000';lstr[4]:='00';lstr[5]:='0';lstr[6]:='';
j:=0; //記錄循環(huán)次數(shù)的計(jì)數(shù)器
k:=1; //記錄股票代碼的個數(shù)的計(jì)數(shù)器
bk:='A股板塊'; //bk賦值為字符串'深圳A股'
blksum:=STKCOUNT(bk); //板塊所包含證券數(shù)量
variable:dmstr[blksum]=''; //定義一個字符串?dāng)?shù)組用于記錄股票代碼,元素個數(shù)為blksum,初始值為空
while k<=blksum do //當(dāng)計(jì)數(shù)器k<=blksum時,執(zhí)行以下循環(huán)
begin
dm:=NumToStr(j,0); //把數(shù)值j轉(zhuǎn)換成字符串并賦值給變量dm,保留小數(shù)位數(shù)0
dm_len:=strlen(dm); //求出dm的長度,并賦值給變量dm_len
dm:=lstr[dm_len]+dm; //由dm的長度,確定應(yīng)該給dm的前面加上多少個字符0
if stkinblock(dm,bk) then //如果股票代碼dm屬于bk,則執(zhí)行下面由begin、end包含的語句
begin
dmstr[k]:=dm; //真正需要的股票代碼,記錄到字符串?dāng)?shù)組dmstr的第k個元素中
k:=k+1; //記錄找到的股票代碼的個數(shù)
end;
j:=j+1; //記錄循環(huán)的次數(shù)
end;
EXPLAIN(islastbar,dmstr[1]); //當(dāng)處在最后一根K線位置時,輸出字符串深圳A股第1只股票的代碼-------------------------------------------------------------------------------- 假如你試圖執(zhí)行這段代碼,你會發(fā)現(xiàn)好慢哦~~ 為何會這樣?因?yàn)閺纳钲贏股切換到上海A股的股票代碼時,是從1896跳躍到600000,中間有508104次空循環(huán),這中間沒有一個代碼是真正的股票代碼,因此可以這樣來提高循環(huán)的執(zhí)行效率,在公式代碼中插入如下幾行代碼:if j=1896 then j:=599999;if j=600999 then break; 優(yōu)化后的代碼如下: PHP代碼:--------------------------------------------------------------------------------
variable:lstr[6]='00000';
lstr[2]:='0000';lstr[3]:='000';lstr[4]:='00';lstr[5]:='0';lstr[6]:='';
j:=0; //記錄循環(huán)次數(shù)的計(jì)數(shù)器
k:=1; //記錄股票代碼的個數(shù)的計(jì)數(shù)器
bk:='A股板塊'; //bk賦值為字符串'深圳A股'
blksum:=STKCOUNT(bk); //板塊所包含證券數(shù)量
variable:dmstr[blksum]=''; //定義一個字符串?dāng)?shù)組用于記錄股票代碼,元素個數(shù)為blksum,初始值為空
while k<=blksum do //當(dāng)計(jì)數(shù)器k<=blksum時,執(zhí)行以下循環(huán)
begin
dm:=NumToStr(j,0); //把數(shù)值j轉(zhuǎn)換成字符串并賦值給變量dm,保留小數(shù)位數(shù)0
dm_len:=strlen(dm); //求出dm的長度,并賦值給變量dm_len
dm:=lstr[dm_len]+dm; //由dm的長度,確定應(yīng)該給dm的前面加上多少個字符0
if stkinblock(dm,bk) then //如果股票代碼dm屬于bk,則執(zhí)行下面由begin、end包含的語句
begin
dmstr[k]:=dm; //真正需要的股票代碼,記錄到字符串?dāng)?shù)組dmstr的第k個元素中
k:=k+1; //記錄找到的股票代碼的個數(shù)
end;
if j=1896 then j:=599999; //計(jì)數(shù)器j直接跳到到上海A股對應(yīng)的最小代碼
if j=600999 then break; //如果記錄到這個代碼則跳出循環(huán)
j:=j+1; //記錄循環(huán)的次數(shù)
end;
//以下是一些字符串函數(shù)及運(yùn)算的綜合應(yīng)用
EXPLAIN(1,dmstr[1]); //在解盤中,輸出深圳A股第1只股票的代碼
EXPLAIN(1,stknameex(dmstr[2]));//第2只股票的名稱
EXPLAIN(1,dmstr[3]+stknameex(dmstr[3]));//第3只股票的代碼及名稱
EXPLAIN(1,'深圳A股第4只股票的代碼是:'+dmstr[4]);
EXPLAIN(1,dmstr[5]+'最后收盤價:'+numtostr(close,2));
EXPLAIN(1,'深圳A股共有股票:'+numtostr(blksum,0)+'只');-------------------------------------------------------------------------------- 這行代碼 if j=600999 then break 有什么用?以防萬一,如果有人改了市場規(guī)則,把500001之類的股票計(jì)入上海A股的話,這里的循環(huán)會出不來的,會造成電腦死循環(huán),飛狐長時間沒有響應(yīng)。 以上公式代碼,只是個示例,效率不太高,如果能有個方法,直接給出板塊中所有的股票代碼,那就不需要這段公式代碼。 給出這個示例,是想通過大致解剖整個公式代碼的設(shè)計(jì)過程,讓大家對循環(huán)、條件語句有個初步的認(rèn)識?! ∽詈?,給大家個練習(xí)的機(jī)會: 1、修改上述代碼,計(jì)算“A股板塊”的成交量(這就是橫向統(tǒng)計(jì)了) 2、以上公式代碼,使用的是while循環(huán),有辦法改成fox循環(huán)嗎?(當(dāng)心,在修改代碼的過程中,如果不慎的話,有可能造成死循環(huán),對于win9x操作系統(tǒng),也許很難退出,對于NT以上操作系統(tǒng),可以強(qiáng)行退出) 3、高級問題:通過以上代碼,可以做出橫向排序,不過建議不要用代碼本身來實(shí)現(xiàn)排序(會很慢的),應(yīng)使用今天發(fā)布的新函數(shù)SORTPOS(X,D,N1,N2)來實(shí)現(xiàn)?! ?、借用論壇的一個問題:ff:=barslast(date=1030107);周期:=5;VERTLInE(ff=0 or ff=周期*1 or ff=周期*2 or ff=周期*3 or ff=周期*4 or ff=周期*5or ff=周期*6 or ff=周期*7 or ff=周期*8 or ff=周期*9 or ff=周期*10or ff=周期*11 or ff=周期*12 or ff=周期*13 or ff=周期*14 or ff=周期*15or ff=周期*16 or ff=周期*17 or ff=周期*18 or ff=周期*19 or ff=周期*20or ff=周期*21 or ff=周期*22 or ff=周期*23 or ff=周期*24 or ff=周期*25or ff=周期*26 or ff=周期*27 or ff=周期*28 or ff=周期*29 or ff=周期*30or ff=周期*31 or ff=周期*32 or ff=周期*33 or ff=周期*34 or ff=周期*35or ff=周期*36 or ff=周期*37 or ff=周期*38 or ff=周期*39 or ff=周期*40),POInTDOT; 把以上代碼,改成用循環(huán)表示?! ?、一個數(shù)列定義如下:f[1]=1,f[2]=1,f[n]=f[n-1]+f[n-2],你能用循環(huán)計(jì)算出f[10]等于多少嗎?這個數(shù)列是很有名的,許多股票預(yù)測都會用到它。 呵呵,具體我也記不住了,誰能告訴我它叫什么?