量化交易軟件:沃爾夫波形 (Wolfe Waves)

概述
沃爾夫波形 (Wolfe Wave) 是 Bill Wolfe 發(fā)現(xiàn)并描述的圖形分析形態(tài)。此圖案看起來像一個三角形或楔形 (沃爾夫稱之為 '上升的楔子'), 并具有一些特殊的細微差別。比爾·沃爾夫 (Bill Wolfe) 提出的圖形化方法可以檢測到一種形態(tài), 根據(jù)此形態(tài)可以找到入場的時刻和方向, 并且還有益于預測價格應達到的目標, 以及達到目標的時間。
在本文中, 赫茲量化將詳細研究沃爾夫波形的檢測和解釋規(guī)則。赫茲量化將根據(jù) 通用之字折線 文章中的之字折線指標, 創(chuàng)建自動檢測并顯示波形的指標。赫茲量化還將根據(jù)結(jié)果指標創(chuàng)建一個簡單的專家交易系統(tǒng)。此 EA 將允許我們測試指標績效, 并得到比爾·沃爾夫所提出的圖形分析的第一印象, 之后會在本文中討論。
檢測沃爾夫波形的規(guī)則
赫茲量化來研究買入示例中的沃爾夫波形 (圖例.1)。價格形成兩個連續(xù)下降的低峰 (藍線, 點 1 和 3), 以及兩個連續(xù)下降的高峰 (點 2 和 4)。在點 4 逆轉(zhuǎn)并形成高峰之后, 價格繼續(xù)下滑。一旦價格觸及點 1 — 點 3 的延長線, 就進行買入操作 (點 5)。

編輯
圖例. 1. 買入沃爾夫波形。藍線是價格, 紅線是形成的檢測目標。在點 5 執(zhí)行入場, 目標是點 7
1—3 和 2—4 延長線的交匯點 6 則為檢測目標的到達時間。目標價位 (點 7) 的定義是 1—4 延長線與通過點 6 繪制的垂直線的交點。此方法不提供止損計算算法, 通常建議是您自行決定使用止損。以上是沃爾夫書中講述的波形檢測規(guī)則。
當開發(fā)本文的指標時, 還會發(fā)現(xiàn)更多的規(guī)則。
點 3 必須遠低于點 1, 以下條件應予以檢查:v3<v1-d1此處:
v3 — 點 3 的價位;
v1 — 點 1 的價位;
d1 — 點 1 和 點 2 (線段 1''-2'') 之間的垂直距離乘以 K1 (K1 是屬性窗口的參數(shù), 其默省缺值為 0.1)。
檢測目標的 1—4 延長線必須向上, 即點 4 必須遠高于 點 1。以下條件應予以檢查:v4>v1+d1;v4 — 點 4 的價位。
點 4 必須遠低于點 2, 以下條件應予以檢查:v4<v2-d2;此處 v2 是點 2 的價位, d2 是點 2 和點 3 (線段 2''-3'') 之間的垂直距離乘以 K2 (K2 是屬性窗口的參數(shù), 其默省缺值為 0.1)。
檢測目標到達時間的 2-4 與 1-3 延長線必須交匯點于右側(cè), 所以 2-2' 的高度必須遠高于 4-4' 的高度。在此必須執(zhí)行以下檢查:h2-h4>K3*h2;此處 h2 是線段 2-2' 的高度, h4 是線段 4-4' 的高度, K3 是比率 (K3 是屬性窗口的參數(shù), 其默省缺值為 0.1)。
這些規(guī)則聲明并未假定絕對正確。以后我們在指標的創(chuàng)建過程中還要詳細描述。基于這些素材, 您可以根據(jù)自己的想法調(diào)整代碼。
選擇使用的之字折線
開始之前, 赫茲量化下載 附件, 它包含許多 通用之字折線 一文中的多種版本之字折線指標。我們需要從中選擇一個在我們的文章中使用。我們不使用 iUniZigZagPrice 和 iUniZigZagPriceSW, 它們設計時基于圖表上運行的其它指標進行計算, 因此它們僅對視覺分析有用。其它指標似乎更有趣。它們當中的每一個都可用來創(chuàng)建專家交易系統(tǒng)。此外, 我們不會使用 iCloseZigZag 和 iHighLowZigZag, 它們只是如何創(chuàng)建之字折線的初始示例。剩下兩個版本, 即 iUniZigZag 和 iUniZigZagSW。在子窗口中工作的 iUniZigZagSW 指標更適合我們, 因為它提供了更廣泛的功能。附件中也包含 iUniZigZagSWEvents 指標, 并展示了使用 iCustom() 函數(shù)訪問 iUniZigZagSW 指標的示例。我們將使用此變體, 因為它將允許我們使用 iUniZigZagSW 指標的所有可能性, 且可另行將沃爾夫波形的檢測代碼與之字折線代碼分離。
iUniZigZagSWEvents 指標顯示在價格圖表上, 四個緩沖區(qū)用于繪制指標: 兩個帶箭頭的緩沖區(qū), 另外兩個畫點。這些就是我們檢測定沃爾夫波形所需要的。箭頭將指示形態(tài)識別位置, 點則用于目標。赫茲量化的指標將用到 圖形對象, 特別是 趨勢線 繪制波形和構型以檢測目標。如果您將其繪制為線段而非延伸射線, 那么它會是顯示不同構型的非常方便的工具。 ?
除了檢測入場時刻和方向外, 沃爾夫波形也用于預測目標。所以, 當使用 iUniZigZagSW 時會出現(xiàn)困難。指標帶有 SrcSelect 參數(shù), 可以根據(jù)所繪制的之字折線選擇分析數(shù)據(jù)的來源。可以選擇以下四個選項之一:
Src_HighLow — 按照最高價和最低價;
Src_Close — 按照收盤價;
Src_RSI — 按照 RSI 指標;
Src_MA — 按照移動均線。
基于我們現(xiàn)正創(chuàng)建的指標創(chuàng)建專家交易系統(tǒng)。此即為什么如果我們利用價格來構建之字折線, 那么預測的目標就可以用來放置止盈位。在圖表上顯示目標沒有任何問題。但是如果使用RSI (SrcSelect=Src_RSI) 計算之字折線, 則預測目標將是 RSI 指標, 而非價格。所以, 一旦 RSI 指標達到目標值, 我們就需要市價平倉, 而不可能在圖表上顯示目標價格和附加構型。
當使用基于價格 (Src_HighLow 或 Src_Close) 繪制的之字折線時, 目標價格和附加構型將顯示在圖表上。在所有其它情況下, 只會顯示一個箭頭, 表示已發(fā)現(xiàn)的結(jié)構及其方向。目標值仍然在適相應的價格緩沖區(qū)中提供 (為了能夠讓專家交易系統(tǒng)以市價平倉來應對任何其它目的), 但不會顯示。
很有可能在實踐中, 當指標達到目標價位時, 市價平倉的想法無法實現(xiàn)。大多數(shù)指標的值在一定范圍內(nèi)變化, 目標結(jié)果可能在此范圍之外。但是, 在任何情況下, 緩沖區(qū)都將包含目標值。
收集關于之字折線峰值的數(shù)據(jù)
我們現(xiàn)在開始創(chuàng)建指標。赫茲量化在編輯器中打開 iUniZigZagSWEvents, 文件并將其保存為 iWolfeWaves。我們將操控這個指標。 直接訪問所有的之字折線峰值非常方便 — 在此情況下, 我們不必每次都在歷史中搜索它們。我們來創(chuàng)建一個數(shù)組保存數(shù)值。現(xiàn)在, 每當之字折線改變方向時, 一個新的元素將被添加到數(shù)組中。如果指標簡單地延伸最后一個線段 (更新極值), 則數(shù)組的最后一個元素將被更新。 對于每個峰值, 赫茲量化將保存峰值、方向和所在柱線的索引 (索引從左到右)。為此目的, 我們將使用一個含有三個字段的 結(jié)構: struct SPeackTrough{ ? ?double ? Val; // 峰值 int ? ? ?Dir; // 方向 int ? ? ?Bar; // 柱線索引 }; ? 我們來創(chuàng)建一個這些結(jié)構的數(shù)組: SPeackTrough PeackTrough[]; 如果之字折線僅僅基于最高價和最低價 (SrcSelect = Src_HighLow), 當方向改變的情況下將數(shù)組遞增就足夠了, 設置數(shù)值并用指標最后延伸的一段更新最后的元素。基于收盤價 (SrcSelect = Src_Close) 或任何其它指標數(shù)據(jù)的之字折線更難辦。在柱線形成期間, 方向改變, 之字折線可以返回原來的狀態(tài) (即當前柱線開盤之前)。這意味著對于相同柱線的每次重新計算, 峰值數(shù)組需要返回到前一根柱線的初始狀態(tài)。如果我們經(jīng)常更改數(shù)組大小, 這可能會減慢指標的運行。因此, 赫茲量化來引入一個附加的變量, 所用數(shù)組大小將被保存其內(nèi)。必要時, 數(shù)組將以塊為單位進行修改, 只允許尺寸增長。重新計算同一根柱線之前, 我們要返回此變量的初始值。 我們將使用兩個變量來存儲數(shù)組大小。在一個變量中, 存儲前一根柱線時的數(shù)組大小。當前計算的柱線時的大小將存儲在第二個變量當中: int PreCount; // 前一根柱線時 PeackTrough 數(shù)組的大小 int CurCount; // 當前計算柱線時 PeackTrough 數(shù)組的大小 在柱線形成并計算完成后, 或計算歷史柱線之后, CurCount 變量的值應轉(zhuǎn)移到 PreCount 變量。然后, 在每次計算新形成的柱線之前, 赫茲量化要把數(shù)值從 PreCount 移動到 CurCount。只有 CurCount 變量將會用于所有的計算。PreCount 變量只是輔助。關于柱線結(jié)構完畢的信息只能在下一根柱線開盤 (或計算切換到歷史中的下一根柱線) 時才知道。新柱線的出現(xiàn)將由時間決定: 如果柱線時間已經(jīng)改變, 則會出現(xiàn)一根新柱線 (或計算歷史中的下一根柱線已經(jīng)開始)。需要一個輔助變量以便確定新的柱線: datetime LastTime; PreCount, LastCount 和 LastTime 是指標的全局變量。但是它們也可以在 OnCalculate() 指標函數(shù)里聲明為靜態(tài)變量。 我們轉(zhuǎn)進到 OnCalculate() 函數(shù)。基于 prev_calculated 的值, 判斷是第一次執(zhí)行指標計算還是僅計算新的柱線。0 意即全部計算。在此情況下, 變量 PreCount, CurCount 和 LastTime 需要初始化。以下代碼位于 OnCalculte() 函數(shù)的最上面, 定義計算的柱線范圍, 并初始化輔助變量: int start; // 起始計算的柱線的索引變量 if(prev_calculated==0){ // 計算全部的柱線 ? ?start=1; ? ?CurCount=0; ? ? ? PreCount=0; ? ?LastTime=0; } else{ // 計算新柱線 ? ?start=prev_calculated-1; } ? 現(xiàn)在我們來處理標準的指標循環(huán)。在一開始, 我們要將變量 PreCount, CurCount 中的數(shù)值組織轉(zhuǎn)移: for(int i=start;i<rates_total;i++){ ? ? if(time[i]>LastTime){ // 計算新 (下一次) 柱線 ? ? ? LastTime=time[i]; ? ? ? PreCount=CurCount; ? ? ? PreDir=CurDir; ? ?} ? ?else{ // 柱線重新計算 ? ? ? CurCount=PreCount; ? ? ? CurDir=PreDir; ? ?} ? 在所有的計算當中, 僅適用 CurCount 變量, 而 PreCount is 僅設計用于維護當前的 CurCount 值。在新柱線開盤伊始, CurCount 首先包含前一根柱線計算后獲得的數(shù)值。這就是為什么我們要把這個數(shù)值移動到 PreCount。在新柱線計算之后, CurCount 的數(shù)值可以改變。但是, 赫茲量化只能在下一根柱線的開盤時才能確定該值是最終的。這就是為什么在重新計算同一柱線的情況下, PreCount 變量的數(shù)值被放置到 CurCount。 主要指標循環(huán)應包含取自 iUniZigZagSWEvents 指標的以下代碼: UpArrowBuffer[i]=EMPTY_VALUE; DnArrowBuffer[i]=EMPTY_VALUE; ?UpDotBuffer[i]=EMPTY_VALUE; DnDotBuffer[i]=EMPTY_VALUE; ? ? ? ?// 方向 double dir[2]; if(CopyBuffer(handle,3,rates_total-i-1,2,dir)<=0){ ? ?return(0); } if(dir[0]==1 && dir[1]==-1){ ? ?DnArrowBuffer[i]=high[i]; ? ?c++; ?} else if(dir[0]==-1 && dir[1]==1){ ? ?UpArrowBuffer[i]=low[i]; ? ?c++; } ?// 新的最高價 double lhb[2]; if(CopyBuffer(handle,4,rates_total-i-1,2,lhb)<=0){ ? ?return(0); } if(lhb[0]!=lhb[1]){ ? ?UpDotBuffer[i]=high[i]; } ?// 新的最低價 double llb[2]; if(CopyBuffer(handle,5,rates_total-i-1,2,llb)<=0){ ? ?return(0); } if(llb[0]!=llb[1]){ ? ?DnDotBuffer[i]=low[i]; } ? ? 繪制箭頭的代碼部分將不會被使用, 所以我們來刪除它。