人人爽天天爽夜夜爽qc-人人爽天天爽夜夜爽曰-人人天天爱天天做天天摸-人人天天夜夜-色网站在线-色网站在线看

您現(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;

 

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

 

/////////////////固定的結(jié)束語句,請原封不動//////////////////////////////////////////////////////////

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.kzuj.com.cn )

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

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

 

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

 

 

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

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

 


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

相關(guān)文章

    沒有相關(guān)內(nèi)容
  主站蜘蛛池模板: 高清 国产 日韩 欧美 | 一级做a爰全过程免费视频 一级做a爰片鸭王 | 欧美日韩亚洲天堂 | 中国黄色一级片 | 日韩欧美精品在线视频 | 91高素质城中村在线观看 | 亚洲精品网站在线 | 中文字幕日韩欧美一区二区三区 | 情人边吃奶边做好爽嗷嗷叫 | 一级国产特黄aa大片 | 99在线在线视频免费视频观看 | 亚洲免费观看视频 | 国产精品密蕾丝视频 | 丁香六月 久久久 | 国产日韩欧美二区 | 天天摸天天看天天爽 | 国产真实乱偷人视频 | 理论片一级 | 2019最新中文字幕 | 窝窝免费午夜视频一区二区 | 成人xxxxx| 印度一级毛片免费的 | japan孕妇孕交 | 日本色片网站 | 日韩久久久精品首页 | 宅男在线 午夜影院 | 日本3p视频在线看高清 | 又黄又爽的成人免费视频播放 | 中文字幕亚洲无线码在线一区 | 日日操天天射 | 香蕉免费在线视频 | 中文字幕日韩精品麻豆系列 | 亚洲深夜福利视频 | xxxxwww一片| 日韩黄色在线视频 | h色视频在线 | 青春草在线视频免费 | 欧美怡红院免费全视频 | 日本久久综合视频 | 黄色小网站在线观看 | 糟蹋小少妇17p |