程式買賣:恆指對沖策略分析與設計實例(5)

parksondow935
圖9-35

 

現在的勝率拉到了42.11%,風險利潤比1.42;這裡的破產風險大約50%,這一切是比一開始的數據好多了。注意這裡風險利潤比是惡化了一點,但是一般的情形,這就像翹翹板很難一起改善的。
再多認識一個新數據叫平均每筆盈虧「Avg Trade(win & loss)」。這裡的數字是59.68港元,代表無論每次的勝負,我們等於在每次交易中平均獲利59.68元;如果一天交易一次的系統,等於我們每天薪水是59.68…可憐的交易者。
獲勝的交易共224次,平均每筆獲利為4658.48元。4658.48 x 224 = 1,043,499.52,我們是從這裡一直失守下來的,繼續努力把失地要回來。
parksondow936
圖9-36 系統的績效曲線

 

parksondow937
圖9-37

 

減少一些交易次數後,好像中央分佈的點比較少了,代表實際的壓制了一些無謂的交易雜訊。但可不可能再更好呢?要使用什麼方式來降低呢?代入抑制雜訊的機制就似化療般,殺了癌細胞也會殺掉一些正常的細胞,所以不可不謹慎去考慮選用。
思考後決定使用ADX來測試效果,我們改寫Condition1,修正如下…

Condition1 = time >= 0915 and time <= 1500 and ADX(14) > ADXR(14);

編譯之後我們再來看看成效如何?
parksondow938
圖9-38 加入ADX濾網後訊號明顯的減少

 

parksondow939
圖9-39

 

加入ADX濾網後獲利拉到了152,750港元,這純粹是雜訊減少的結果,因為我們並沒有修改其他的參數。勝率拉高到46.5%、風險利潤比回升到1.8,如此的比率破產風險比將被壓低到10%以下。我們的薪水也加薪到了972.93港元。
parksondow940
圖9-40 績效曲線感覺上平滑了不少

 

parksondow941
圖9-41 交易次數從開始的877次,減到目前剩157次,清爽多了

 

經過ADX的過濾帶後,數字被大幅改變。因為我們加入一個新的策略元素,所以謹慎的設計要求下,我們實在有理由再來一次Period與Pcnt參數的最佳化。當然如果你願意的話,ADX的天數其實也可以拿來試試的。
parksondow942
圖9-42

 

一如所料、新的參數組合出現了!Period小步移到19,但Pcnt卻大幅的調高到1.43。交易次數再次下降到剩119次,獲利卻不因交易次數下降而減少,反而升到了165,550。
但是如果我們不以獲利來排名,而使用風險利潤比的話,將會發現原先的組合(18,0.51)仍是穩居榜首。兩組數據各有其優點,看倌請自行選定。
parksondow943
圖9-43 原組合表現仍然不錯

 

parksondow944
圖9-44

 

使用19與1.43組合的結果,更高的勝率與我們的薪水。這些改良到底有沒有用呢?事實是非常滿意的對我來說。我所覺得很滿意的請觀察我們毛利、毛損與淨利之間的關係,它被拉到了我很少碰到的比率。
一般我們談過當沖的宿命,常常遇到的就是…獲利感覺上是被「榨」出來的。淨利20萬如果是從200萬毛利得來,一點也不驚訝。但是我們看目前的數據毛利幾乎只跟淨利存在倍術關係而已,這是非常難得與罕見的。
毛利就像一家公司的營業額,毛損就是所有的營業成本與支出。一樣賺20萬的公司,我們現在開的就是小而美兼有效率的。大毛利對大毛損的就是好像講排場苦內心的公司,所以這樣的結果我們應該高興的。
這樣的結果滿意嗎?我們來檢視看看吧!系統自2012/05/02到2013/12/27約一年半的時間,扣除手續費後淨利為165,550港元。如果以一口保證金7萬港幣一口來計算,年投資報酬率約為165,550 / 70,000 / 1.5 = 約158%左右。精確的來算我們必須準備,保證金加所謂MDD的金額才可以順序交易這個系統。MDD就是Max DrawDown(最大資金回檔風險),見表中的Max Intraday Drawdown,系統為(-45,550)。這個數字代表的是我們不能只拿7萬元進場交易,因為當遇到虧損讓本金低於7萬時,我們就無法進場交易了。那要準備多少錢呢?這個MDD就是系統評估後給我們的建議金額,也就是說整個系統在運作中應該不會遭遇連續虧損超過45,550的機會,並保護我們的系統可以順利執行下去。所以真正的狀況是我們必須準備70,000 + 45,550 = 115,550才是我們的進場最少要求資金。如此來算165,550 / 115,550 / 1.5 仍有約96%的年回報。那…還有調高的空間嗎?
找了找,我們把歪腦筋給動到表上的Largest losing trade(最大的單筆損失),它的數字是(-14,600)。以恆指一個跳動點值50港元來算,它折合了292點值,天呀!這個是必須存在的一筆虧損嗎?
parksondow945
圖9-45

 

找到該筆交易是發生在2013/10/17,發現蠻詭異的、因為它是一路虧損到收盤,怎麼可以虧損292點卻都沒有啟動反向的賣出動作呢?
parksondow946
圖9-46

 

兇手找到了!果然像前面說的化療效果,這次被殺死的就是冤枉的好細胞。當賣出訊號產生時,卻被ADX濾網給擋掉了。我們有兩種解決的方式,第一種是加入這兩行程式碼…
If Marketposition = 1 and AMAHs – AMAVal Crosses Above AMAFVal Then ExitLong Next Bar at open;
IF Marketposition = -1 and AMAVal – AMALs Crosses Above AMAFVal Then Exitshort Next Bar at open;
parksondow947
圖9-47

 

改完後感覺效果並不好,整體的獲利有點下降,MDD也增加了。最重要的是趕走那筆一萬四的,還是沒有把所有的大筆損失的問題解決。

現在讓我們退回上一個起點,試試另一種修正的方法。先看底下這張圖,它是統計所有的交易過程中,曾經產生的盤中最大虧損值。
parksondow948
圖9-48

 

這是包括獲利與虧損的所有交易。可以看到許多獲利的交易也有深入負值的部份,這代表一般的獲利交易還是在起頭時是呈現某一段時間的虧損,之後才轉虧為盈的。所以我們不能設定一個50港元的止損,那樣也會把絕大多的獲利交易弄得提前出場。那這個適當的止損值該是多少呢?如果用目測我們發現約在5,000港元左右就幾乎可以防止大多數的「誤殺」事件,事實很少有直接獲利的、但也鮮少進場先虧個一兩萬港元的倉位,還可以轉虧為盈的。
首先、我們修改以下的程式碼…

Inputs: Period(19), Pcnt(1.43), StpHKD(5000);
Vars: AMAVal(0), AMAFVal(0), AMALs(0), AMAHs(0);
SetStopContract;
SetStopLoss(StpHKD);

增加了一個Inputs輸入項StopHKD,預設為5,000港元。然後增加一個內建的資金管理指令,SetStopLoss(金額)為設定止損金額。TS許多的資金管理指令都要配合SetStopContract或SetStopPosition指令一起使用。
SetStopContract代表隨後的SetStopLoss是針對每一個倉位考慮,就是表示我們要設定每口倉位最大只能虧損5,000元。如果我們的總倉位有3口單,那就是可能虧損15,000元。如果配合的是SetStopPosition就代表以總倉位虧損為考慮,一口時虧損5,000元,如果總倉位是3口那總虧損還是5,000元,每口虧損為1,666.6元(5,000 / 3)。
我們現在增加了一個輸入項與修改了兩個預設值,直接編譯時將會發生以下錯誤。

 

parksondow949
圖9-49 我們的輸入項目與數值的改變影響了策略對應值

 

parksondow950
圖9-50

 

進入策略建構功能,點選我們的策略名稱後再點選「Edit」編輯。
parksondow951
圖9-51 沒錯我們就是要修正這錯誤,點確定

 

parksondow952
圖9-52 關鍵就是要來這頁點這個重置鍵「Reset」,讓參數同步

 

parksondow953
圖9-53 點選「是」我們就完成了

 

最安全的方式就是最後再回來做編譯一次,確定剛才出現的錯誤訊息不再出現。這樣的改變後成效如下…
parksondow954

圖9-54 最大的虧損被限制在5,000元,5,300是加上手續費。

 

parksondow955
圖9-55 原先的最大盤中虧損被齊頭砍在 -5,000以上

 

除這個5,000元的目測值外,有可能出現更好的數據嗎?不妨在來個最佳化尋找一下吧。
parksondow956
圖9-56 我們目測的結果也吻合最佳化的結果

 

到目前終於可以鬆一口氣了,我們的開發工作告一段落,自己慶祝一下吧!本章的最後再提一些注意的細節,然後把最終的程式碼再總結一次後結束。
在兩個函式中都有這一行…

efRatio = Signal / Noise;

請改為

efRatio = IFF(Noise = 0, 0, Signal / Noise);

這個防止除零的錯誤防止一定要做。然後在策略的參數頁中…
parksondow957

圖9-57

 

這個回測設定部份一定要打勾,並選擇以一分鐘資料為主。如果我們沒有調到這樣的精度引用,如我們現在是以10分鐘資料為主,可能在回測時會有許多不精確的結果產生。
以下是最後修正的程式碼

Inputs: Period(19), Pcnt(1.43), StpHKD(5000);
Vars: AMAVal(0), AMAFVal(0), AMALs(0), AMAHs(0);
SetStopContract;
SetStopLoss(StpHKD);
AMAVal = SS_AMA(Period);
AMAFVAl = SS_AMAF(Period, Pcnt);
Condition1 = time >= 0915 and time <= 1500 and ADX(14) > ADXR(14);
Condition2 = time >= 1600;
IF CurrentBar = 1 Then Begin
AMALs = AMAVal;
AMAHs = AMAVal;
End Else Begin
IF AMAVal < AMAVal[1] Then AMALs = AMAVal;
IF AMAVal > AMAVal[1] Then AMAHs = AMAVal;
If Condition1 and EntriesToday(Date) < 5 Then Begin
IF AMAVal – AMALs Crosses Above AMAFVal Then Buy Next Bar at open;
IF AMAHs – AMAVal Crosses Above AMAFVal Then Sell Next Bar at open;
End;
If MarketPosition <> 0 and Condition2 then Begin
ExitLong (“TimeExB”) Next bar at open;
ExitShort (“TimeExS”) Next bar at open;
End;
End;

以上提供資訊僅供參考,不應視為任何投資之建議或邀請,投資涉及風險,應先考慮個人因素,如有疑問請諮詢專業意見。
%d bloggers like this: