大伊人青草狠狠久久-大伊香蕉精品视频在线-大伊香蕉精品一区视频在线-大伊香蕉在线精品不卡视频-大伊香蕉在线精品视频75-大伊香蕉在线精品视频人碰人

您現(xiàn)在的位置:程序化交易>> 期貨公式>> 金字塔等>> 金字塔模型>>正文內(nèi)容

[原創(chuàng)]教你寫一個金字塔不卡的復雜圖表策略[金字塔模型]

 

前言

這是一個代碼框架,其中部分靈感來自阿火的策略、guotx2010的VBA教程和王峰的一句話(如果你注重效率,那么金字塔提供的全局變量數(shù)據(jù)庫的速度完全可以超越INI文件的),所以在此向各位前輩致謝!

 

適用本框架的前提:

不使用金字塔規(guī)定不能用于if ... then中的函數(shù)(如統(tǒng)計函數(shù)、未來函數(shù)等)、采用走完K線、且K線走完后信號就固定下來的(即未來不會發(fā)生改變)、使用新圖表交易函數(shù)、勾選“僅刷最后一根K線”

 

步驟:

 

第一步:創(chuàng)建3個自定義函數(shù),創(chuàng)建方法在此不詳述,VBA代碼如下:

\'定義4個動態(tài)數(shù)組保存信號和信號發(fā)生日期和時間

dim dates()
dim times()
dim values()
dim SigCounts()
SigCount = 0

 

Function INSERTSIG(Formula,SIGNUM,D,T,H)
 \'通過VBA數(shù)組記錄信號以及信號發(fā)生的時間,當最新信號發(fā)出時執(zhí)行一次
 INSERTSIG=0
 On Error Resume Next
 dates(SIGNUM).AddBack(D)
 if err.number<>0 then
  INSERTSIG=1
  exit function
 end if
 times(SIGNUM).AddBack(T)
 values(SIGNUM).AddBack(H)
 if dates(SIGNUM).Count>SigCounts(SIGNUM) and SigCounts(SIGNUM)>0 then
  dates(SIGNUM).RemoveAt(0)
  times(SIGNUM).RemoveAt(0)
  values(SIGNUM).RemoveAt(0)
 end if
End Function

 

Function READSIG(Formula,SIGNUM)
    \'將數(shù)組信號發(fā)生時間轉(zhuǎn)換為K線位置,并記錄到單值全局變量系統(tǒng)中,供Perl公式讀取,每產(chǎn)生一次新K線時執(zhí)行一次
 READSIG=0
 On Error Resume Next
 cc = times(SIGNUM).Count
 if err.number<>0 then
     READSIG = 1
     exit function
 end if
 iGlobal=document.ExtDataNum
 for i=iGlobal to 0 step -1
  iKeyValue=document.GetExtDataByIndex(i,sKeyName)
  if (strComp(left(sKeyName,5),"HH" & right(Formatnumber(1000+SIGNUM,0,0,0,0),3))=0) or (strComp(left(sKeyName,5),"PP" & right(Formatnumber(1000+SIGNUM,0,0,0,0),3))=0) then
   call document.RemoveExtData(i)
    end if
 next
 
 Set History = Formula.ParentGrid.GetHistoryData()
 next_sig_pos = 0
 For i = times(SIGNUM).Count-1 To 0 step -1
  str = Formatnumber(19000000+dates(SIGNUM).GetAt(i),0,0,0,0) & Formatnumber(1000000+times(SIGNUM).GetAt(i),0,0,0,0)
  str = mid(str,1,4) & "-" & mid(str,5,2) & "-" & mid(str,7,2)  & " " & mid(str,10,2) & ":" & mid(str,12,2) & ":" & mid(str,14,2)
  bi = History.GetPosFromDate(str) + 1
  Document.SetExtData "PP" & right(Formatnumber(1000+SIGNUM,0,0,0,0),3) & Formatnumber(bi,0,0,0,0),next_sig_pos
  Document.SetExtData "HH" & right(Formatnumber(1000+SIGNUM,0,0,0,0),3) & Formatnumber(bi,0,0,0,0),values(SIGNUM).GetAt(i)
  next_sig_pos = bi
 Next
 Document.SetExtData "PP" & right(Formatnumber(1000+SIGNUM,0,0,0,0),3) & "1",next_sig_pos
End Function

 

Function INIT_SIG(Formula,SigNum,Count)
    \'初始化數(shù)組,加載公式時或其他必要時間(例如加載新品種時)運行一次
 INIT_SIG=0
 On Error Resume Next
 Set dates(SigNum) = nothing
 Set times(SigNum) = nothing
 Set values(SigNum) = nothing
 if err.number<>0 or SigCount<SigNum+1 then
  ReDim Preserve dates(SigNum+1)
     ReDim Preserve times(SigNum+1)
     ReDim Preserve values(SigNum+1)
     ReDim Preserve SigCounts(SigNum+1)
     SigCount = SigNum+1
 end if
 Set dates(SigNum) = CreateObject("Stock.Array")
 Set times(SigNum) = CreateObject("Stock.Array")
 Set values(SigNum) = CreateObject("Stock.Array")
 dates(SigNum).RemoveAll
 times(SigNum).RemoveAll
 values(SigNum).RemoveAll
 SigCounts(SigNum) = Count
End Function

 

第二步:Perl公式代碼修改為以下框架:

///////////////固定的開頭,您僅可以修改“保留信號數(shù)”以及“策略號”/////////////////////////////////////////////////

GLOBALVARIABLE:d=0,t=0,next_sig_pos=0,保留信號數(shù)=20,策略號=0;
mylot:holding,NODRAW;
if BARPOS=1 then
begin
 if EXTGBDATA(\'股指合約切換\')=1 then
 begin
  d:=0;
  t:=0;
  //EXTGBDATASET(\'股指合約切換\',0);
 end;
 if d=0 and t=0 then
 begin
  xxx:=INIT_SIG(策略號,保留信號數(shù));
 end
 else begin
  xxx:=round(READSIG(策略號));
  if xxx=1 then
  begin
   d:=0;
   t:=0;
   next_sig_pos=0;
   xxx:=INIT_SIG(策略號,保留信號數(shù));
  end
  else
   next_sig_pos:=1;
 end;
end;

if barpos=next_sig_pos then
begin
 myholding:=round(extgbdata(\'HH\' & strright(numtostr(1000+策略號,0),3) & numtostr(barpos,0)))-holding;
 next_sig_pos:=round(extgbdata(\'PP\' & strright(numtostr(1000+策略號,0),3) & numtostr(barpos,0)));
 if myholding>0 then
 begin
  pc:=min(abs(min(holding,0)),myholding);
  kc:=myholding-pc;
  sellshort(pc>0 and holding<0,pc,market);
  buy(kc>0 and holding>=0,kc,market);
 end
 else if myholding<0 then
 begin
  pc:=min(max(holding,0),abs(myholding));
  kc:=abs(myholding)-pc;
  sell(pc>0 and holding>0,pc,market);
  buyshort(kc>0 and holding<=0,kc,market);
 end;
end;

if date()<d or (date()=d and time()<=t) or ISLASTBAR then exit;

//////////////////////////////////////////////////////////////////////////////////////////////////////

 

//這里本應省略N行代碼,這是您原來的策略代碼,為了使您馬上能測試,我隨便寫了個簡單的策略,請不要照用

issell:=close<open and CALLSTOCK(STKLABEL,vtCLOSE,1,-1)<CALLSTOCK(STKLABEL,vtOpen,1,-1);//2連陰空
isbuy:=close>open and CALLSTOCK(STKLABEL,vtCLOSE,1,-1)>CALLSTOCK(STKLABEL,vtOpen,1,-1);//2連陽多

sell(holding>0 and issell,1,market);
SELLSHORT(holding<0 and isbuy,1,market);
buyshort(holding=0 and issell,-1,market);
buy(holding=0 and isbuy,1,market);
j:=0;
for i:=1 to 3000 do              //////////這里加了個循環(huán)3000次,目的是故意拖慢效率
 j:=j+1;

 

//您的策略代碼可以非常復雜,唯一需要注意的是請保證后面的結束語句能被執(zhí)行,即至少產(chǎn)生交易信號時不要使用exit

 

/////////////////固定的結束語句,請原封不動//////////////////////////////////////////////////////////

d:=date();
t:=time();
if (mylot<>holding) then xxx:=round(INSERTSIG(策略號,d,t,holding));

 

一般策略卡的原因:

為了優(yōu)化代碼執(zhí)行效率,使得特別復雜的策略運行起來也不會卡,我專門研究了金字塔公式的執(zhí)行過程,發(fā)現(xiàn)“逐K線計算”+“僅刷最后一根K線”模式的運行原理是這樣的:

加載公式到圖表,或公式被初次stkindi:從第1根K線(barpos=1)逐根計算至最后一根K線(barpos=DATACOUNT且islastbar為true

收到新的行情但沒有產(chǎn)生新的K線:僅就最后一根K線進行計算

收到新的行情并且產(chǎn)生新的K線(即新K線收到第一筆行情):從第1根K線(barpos=1)逐根計算至最后一根K線(barpos=DATACOUNT且islastbar為true

由于以上原因,所以勾選“僅刷最后一根K線”后,一般的公式就應該不怎么卡了,但如果你的公式表現(xiàn)還是卡,那就是兩個原因了:

1、盡管每次只計算最后一根K線,但你的代碼對最后K線計算過程非常復雜,導致剛計算完甚至還沒來得及計算完,又收到新的行情了,你的cpu一直處于高度緊張狀態(tài)

2、當新K線產(chǎn)生時,雖然你勾選了“僅刷最后一根K線”,但新K線收到第一筆行情時,仍會從barpos=1計算至lastbar,所以你如果用1分鐘周期,那么當計算量非常大時,1分鐘會卡一次

 

我的優(yōu)化原理:

1、加載公式時,除了你代碼自身優(yōu)化外,我沒什么能幫你的,所以本策略不能使你的公式加載更快

2、收到新行情但未產(chǎn)生新K線時,我建議你的是采用走完K線模式,所以最后K線完全可以不計算,而只在K線走完時計算倒數(shù)第2根K線,所以我遇到islastbar直接exit,這樣在一根K線未走完時,是完全沒有任何計算的

3、只在產(chǎn)生新K線時對倒數(shù)第2根K線進行計算,如果該K線產(chǎn)生交易信號,那么調(diào)用VBA記錄交易該信號以及產(chǎn)生的K線日期和時間

4、產(chǎn)生新K線時,由于金字塔要求從barpos=1開始重新刷新所有K線,第3點我已經(jīng)為您記錄了交易信號以及其產(chǎn)生的日期和時間,所以,我會在金字塔重新刷新第一根K線前(barpos=1),再次調(diào)用VBA,把所有交易信號(信號產(chǎn)生時間轉(zhuǎn)換為K線序號)寫入單值全局變量數(shù)據(jù)庫

5、金字塔重新刷新所有K線時,我?guī)湍阒苯訌膯沃等肿兞繑?shù)據(jù)庫取信號刷新到歷史K線上,而不需要重新計算,直到倒數(shù)第2根

 

如果你的代碼不復雜,就不要用這個了,反而弄復雜了,計算量越大才越有效,我示范的代碼加了個循環(huán)3000次,可以看出一點都不卡,如果不優(yōu)化,就很卡了

為了寫得通用,我設了兩個參數(shù),解釋一下

保留信號數(shù)=20   //如果設為0表示顯示所有交易信號,如果設20表示僅顯示最后20個信號,設得值越小肯定速度越快,建議設置5~20個左右

策略號=0          //策略號不能重復,如果你有4個策略同時跑,那么請設置不同的策略號,策略號的設置范圍為0~999,如果兩個圖表策略設置相同策略號,將產(chǎn)生沖突

 

最好不要使用ref等金字塔提示不能用在if ... then語句中的函數(shù),如果你要引用前面的周期,建議改為callstock(stklabel,.....)等表達方式,因為金字塔沒有提示在if then中不能用callstock

 

 

假設:你的策略非常復雜,每計算一個K線需要0.2秒,使用一分鐘K線周期,每秒收到兩個tick行情,您的圖表一共有5千根K線,歷史上一共產(chǎn)生了200個交易信號

那么,我可以為您做個優(yōu)化前后的對比:

 

優(yōu)化前:每收到一個tick行情需要計算0.1秒,每秒需要計算兩次,即0.2秒;每根K線走完需要進行一次5千根K線的循環(huán)計算,即500秒(那肯定是卡死了),您以前唯一可以優(yōu)化的是點那個“快速”按鈕,假如您輸入的是100根K線,那么您的程序1分鐘也會卡住10秒鐘,如果你的信號跨度比較大,比如有可能持倉超過100根K線,那么此方法還行不通了

 

優(yōu)化后:一分鐘時間內(nèi)只需要調(diào)用最多兩次VBA,寫和讀200次單值全局變量數(shù)據(jù)庫,200個交易指令,一次完整的K線運算,具體如下:

收到新行情時,直接退出,不消耗cpu;每走完一根K線時,需要調(diào)用一次VBA(消耗0.00001秒),把歷史上的200個交易信號寫入單值全局變量數(shù)據(jù)庫,需要寫200次全局變量(需要0.000002*200=0.0004秒),以上過程加上數(shù)據(jù)處理的時間(主要是將信號產(chǎn)生的日期和時間轉(zhuǎn)換為K線序號),我算他0.1秒是綽綽有余了。另外需要0.1秒計算倒數(shù)第二根K線,如果這根K線產(chǎn)生了信號,那么需要再次調(diào)用VBA把信號記錄(這個記錄操作我也算他0.1秒)。再加上金字塔本身循環(huán)5000個K線所需的時間(但沒有任何代碼去處理他),這個沒測過,應該很快( www.weiqiv.net.cn )

也就是,最多消耗0.3秒左右即可完成,比之前的大大提高了。

注:關于調(diào)用VBA和單值全局變量數(shù)據(jù)庫的操作速度,可參考我另外一個帖子的測試結果,結果顯示 GLOBALVARIABLE快于 單值全局變量數(shù)據(jù)庫 快于VBA調(diào)用,所以我寫程序的時候盡可能把VBA調(diào)用次數(shù)減少到最低,并且能用GLOBALVARIABLE就不用EXTGBxxx

 

{別忘了將本網(wǎng)告訴您身邊的朋友,向朋友傳達有用資料,也是一種人情,你朋友會感謝你的。}

 

 

有思路,想編寫各種指標公式,程序化交易模型,選股公式,預警公式的朋友

可聯(lián)系技術人員 QQ: 1145508240  有需要幫忙請點擊這里留言!!!進行 有償 編寫!不貴!點擊查看價格!

 


【字體: 】【打印文章】【查看評論

相關文章

    沒有相關內(nèi)容
  主站蜘蛛池模板: 国产一区二区三区成人久久片 | jizzjiz熟丰满老妇日本 | 亚洲成人中文字幕 | 天天操天天爽天天射 | 九月丁香婷婷亚洲综合色 | 九色最新网址 | 婷婷久久精品 | 黄色录像日本 | 青青青国产免费手机视频在线观看 | 久久综合99re88久久爱 | 精品国产91乱码一区二区三区 | 午夜一级在线 | 国产理论精品 | 国产com| 男人都懂的网站 | 精品久久中文字幕有码 | 综合网视频 | 成年女人午夜毛片免费看 | 久久一色本道亚洲 | 777精品视频 | 91手机在线 | 波多野结衣久久精品免费播放 | 免费国产一级特黄aa大片在线 | 国产精品二区页在线播放 | 嫩模尺度私拍在线视频 | 在线 v亚洲 v欧美v 专区 | 亚洲国产天堂在线mv网站 | 国产真实一区二区三区 | 青青青视频精品中文字幕 | 天天操精品视频 | 亚洲一级免费毛片 | 91精品国产综合久久婷婷 | 国产精品视频分类一区 | 60岁妇女毛片 | 久久99国产亚洲精品观看 | 国产成人在线播放视频 | 日本免费中文字幕在线看 | 九九热精品视频在线 | 日韩激情中文字幕一区二区 | 五月婷婷婷婷 | 2019中文字幕视频 |