大部分我們對交易策略的發想比較著重在怎麼「進場」,想方設法追求進在最漂亮的位置或是進在該進的時間點,但仔細想想,「如何提高勝率?」、「如何吃到整個波段?」等等獲利核心命題,其實是離不開「出場」策略。股市老手都知道,會進場是徒弟,會出場才是師傅。本文先拋磚引玉提供入門的交易人幾種基本(萬用)的出場語法。 >>讀完本文您可以學到什麼? 1.同時掛出停損停利語法 2.移動停損/停利語法 3.時間出場語法 固定點數停利、停損固定點數停利或停損大概是最簡單也最值觀的出場方式,首先必要先搞懂Limit委託跟Stop委託的差異,再搭配EntryPrice(進場價)這個保留字就可寫出來。
停利就是低買高賣,要掛Limit單。以多單來講,你的停利點一定在進場價之上,反之以空單來講,停利點就在進場價之下,語法範例如下: 多單停利出場:… sell next bar at EntryPrice+100 Limit; 空單停利出場:… buytocover next bar at EntryPrice-100 Limit;
停損就是高買低賣,要掛Stop單。以多單來講,你的停損點一定在進場價之下,反之以空單來講,停損點就在進場價之上,語法範例如下: 多單停損出場:… sell next bar at EntryPrice-50 Stop; 空單停損出場:… buytocover next bar at EntryPrice+50 Stop;
停利停損也可以一起寫,MultiCharts在執行自動交易時會以類似OCO(二擇一委託,一邊成交另一邊自動取消)方式執行委託。我們就以一個簡單通道突破策略為例,當收盤站上最近20根K棒高點多單進場,收盤跌破上最近20根K棒低點空單進場,停利100點,停損50點,語法如下: ===================================== inputs:len(20),loss(50),profit(100); vars:HH(0),LL(0); HH=highest(high,len)[1]; LL=lowest(low,len)[1]; if close cross over HH then buy next bar at market; if close cross below LL then sellshort next bar at market; if marketposition=1 then begin sell next bar at entryprice+profit limit; sell next bar at entryprice-loss stop; end; if marketposition=-1 then begin buytocover next bar at entryprice-profit limit; buytocover next bar at entryprice+loss stop; end; ===================================== 在這個腳本中特別留意這段HH=highest(high,len)[1]; ,其中[1]為取前值,為什麼要取前值?讀者可以自行思考一下。 附帶一提,常有交易人使用固定點數停損停利,並將出場點數設為參數來跑最佳化,根據經驗這樣的做法很容易過度美化績效,陷入最佳化陷阱中,不可不留意。 固定點數改為依指數波動程度動態調整固定點數停利停損的優點是簡單,點數也可以直接連結交易人可以承受的單筆盈虧金額,但比較大的問題在於,第一個它忽略了指數的高低位階,指數在2000點跟指數在10000點,停損都抓一樣50點顯然不合理;第二個缺點是沒有考量當下的波動度。因此更常用的方式是以平均真實區間(Average True Range)來取代固定點數。 真實區間(True Range)即K棒高低點加計跳空,是計算震幅的一種方式,PowerLanguage中內建有AvgTrueRange()函數來計算平均真實區間,所以前面的停利停損範例若改用平均真實區間,語法如下: ===================================== inputs:len(20),loss(2),profit(5); vars:HH(0),LL(0),ATR(0); ATR=AvgTrueRange(len); HH=highest(high,len)[1]; LL=lowest(low,len)[1]; if close cross over HH then buy next bar at market; if close cross below LL then sellshort next bar at market; if marketposition=1 then begin sell next bar at entryprice+profit*ATR limit; sell next bar at entryprice-loss*ATR stop; end; if marketposition=-1 then begin buytocover next bar at entryprice-profit*ATR limit; buytocover next bar at entryprice+loss*ATR stop; end; ===================================== 也就是把原本的固定點數改成N倍的AvgTrueRange來取代,這樣就可以相當程度反映當下的指數位高低階跟波動程度。 移動停損移動停損是一個非常重要的出場方式,因為導致交易虧損最的問題就是賺小賠大,採用移動停損出場,既有停損功能又有移動停利效果,就可以同時解決賺小跟賠大的問題。 最簡單實用的移動停損方式就是採取跌破進N根K低點多單停損,漲過近N根K棒高點則空單停損,語法如下(假設N=5): if marketposition=1 then sell next bar at lowest(low,5) stop; if marketposition=-1 then buytocover next bar at highest(high,5) stop; 這個語法的效果是當MultiCharts多頭建倉後,立即於下一根K棒丟一張停損單,停損價為最近5根K棒低點,這個動作我們可以視為保護性停損單,只要行情不利,這張單子就幫我們踩煞車,限制虧損,但只要當方向正確行情往上漲,低點會越來越高,於是lowest(low,5)就會跟著往上移,只要高過部位進場價,移動”停損”就會變成移動”停利”;空單同理。 其他如SAR指標(MultiCharts內名稱為Parabolic)或是移動平均線也有可以用來作為移動停損的出場依據。 時間出場
某些情境下我們需要在指定時間前出場,例如台指期日盤當沖單收盤前一律出場: If marketposition=1 and time>1320 then sell next bar at market; If marketposition=-1 and time>1320 then buytocover next bar at market; 這個語法要注意使用的K棒如果是較長時間架構可能會出不了場,例如套用60分K,日盤的最後兩根K棒時間分別是12:45及13:45,只有最後一根K棒才符合出場時間條件,但是卻已經收盤。
如果是不想處理轉倉問題,直接結算前強制出場也很常見,以台指期(每月第三個例拜三結算)為例: Condition1=dayofmonth(date) > 14 and dayofmonth(date) < 22 and dayofweek(date) = 3 ; If condition1 and marketposition=1 and time>1320 then sell next bar at market; If condition1 and marketposition=-1 and time>1320 then buytocover next bar at market; 上述condition1即判斷當天是否每月的第三個禮拜三,其他較有規律的商品結算日都可以用類似語法來寫,或是在網路上搜尋前人分享的語法。
BarsSinceEntry是一個很實用的函式,它回傳訊號進場後已經過之K棒數,如果我們希望當進場後超過5根K棒且倉位已經有獲利時,加一道「損益兩平」出場: Condition2= BarsSinceEntry >= 5 and Openpositionprofit > 0; If condition2 and marketposition=1 then sell next bar at entryprice stop ; If condition2 and marketposition=-1 then buytocover next bar at entryprice stop; 損益兩平要建立在已經獲利為前題,且為避免太早被洗出去也不宜在進場後馬上啟動損益兩平機制,兩個條件成立後,在進場價(entrypeice)掛一筆保護性的停損單,確保立於不敗之地(視需要也可以把交易成本的點數考慮進去)。不過損益兩平出場通常只是配套,須搭配其他出場訊號。 進場K棒當根出場以及SET系列語法前面介紹的出場語法都是採用Next Bar方式掛單,也就是進場後最快也要下一根K棒才能出場,這樣就會遇到一種情況,當一進場就遇到大行情,K棒還沒走完就達到停損或停例的條件,卻仍要等下一根K棒才能出場,這個時候PowerLanguage內建的SET系列出場指令可以派上用場。範例如下: ===================================== inputs:len(20),loss(50),profit(100); vars:HH(0),LL(0); HH=highest(high,len)[1]; LL=lowest(low,len)[1]; if close cross over HH then buy next bar at market; if close cross below LL then sellshort next bar at market; SetStopLoss(loss*bigpointvalue); SetProfitTarget(profit*bigpointvalue); ===================================== 保留字bigpointvalue回傳交易商品1大點的金額(bigpointvalue在QuoteManage中設定),所以當在倉部位達到SetStopLoss或SetProfitTarget指定的盈虧金額就會全部出場,即便在進場的當根K棒也是可行。PowerLanguage還有其他內建的SET語法,但使用這一系列語法有許多限制(陷阱),要特別留意: 1. SET系列的出場前面不能有If…條件限制,不然無法達到K棒中即時執行與出場,會變成要等K棒收完才執行。 2.使用SET系列語法在策略屬性>回溯測試中要設定細部回測(Ticks),不然回測績效失真。 3.在目前MultiCharts9.0版下,使用SET系列語法在自動交易會一定機率出現異常,所以目前官方公告建議不要使用。讀者或許要等更新版或是再與官方確認再實單上線。 快速結論在這篇我們比較快速、概略地介紹了幾個常用的出場策略,計有:
其實出場方法的重要性不輸進場,但卻較少被討論,曾有人研究過,採隨機進場但停損不停利的策略來模擬交易損益,結果竟然是可以獲利的,藉此來說明資金管理與出場方式的關鍵性。本文算是拋磚引玉,非常建議交易人多加著墨出場策略,找出與眾不同的出場方式,讓績效得到更上一層樓的提升。 【警語】:
/統一期貨相關連結/
|