2017年8月17日 星期四

外接下單機的結算日清倉實作


我在台指上的交易,讓交易策略每到結算日就收盤清倉的作法,已經維持數年。
僅用 if _checkDay then setexitonclose; 一句來達到訊號的回測。但是,這樣的寫法是不能直接用在日常實戰的。我自己不用內建下單機,不知道她會怎麼動作?而外接下單的方式,則因為單純這樣的策略內指令不會在結算日的收盤前有任何圖表訊號出現,所以也就不會輸出部位變化給外接下單機知道。因此,實際上是根本沒有任何的平倉動作,讓交易所把我的部位給結算掉,而得到真實清倉的效果。

但是,因為外接下單機沒有接收到任何的部位變化訊息,它也就不會有任何動作,從而在結算日收盤後變成錯誤的帳上留倉部位,這會導致後續的交易錯誤。因此,我必須在結算日這天的收盤後,採用手動或自動的方式,讓外接下單機上的帳上留倉部位(下單大師稱為"實際倉位")給歸零。

這裡提供一個方式,讓外接下單機可以知道我要在結算日這天清倉:把輸出給它的資訊,強迫改成... 0。

在你要輸出到外接下單機的訊號或是指標中做這樣的寫法:

var: IntrabarPersist MP(0);

{MP 是要輸出給外接下單機的部位數值,因為我要他在結算日的收盤後做變動,但當時會沒有 tick 進來,所以要宣告成宣告成 IntrabarPersist ,好讓我變更這個變數的數值後得以保留,不會被回復。}

if CheckDay and ( currentTime<0845 or currentTime>1340 ) then
  MP= 0
else
  MP= i_marketposition * i_currentcontracts;

{這一段是判斷 K棒是否屬於結算日,並且如果電腦時間在 08:45 前 或 13:40 後的話,把 MP 設為 0,其他時候則 MP 就是本來你要輸出的訊號部位。這裡需要想像一下,CheckDay 的結算日判斷,是以 K 棒的日期作為判斷的依據,所以當今天是結算日的話,是從開盤第一根K棒就開始回報為 True,所以要限制它必須電腦時間在 13:30(結算合約的最後交易時間)之後才可以變成 0。而當結算日收盤後一直到隔天的早上開盤前,因為沒有新的 tick 進來,不會有新的 K棒日期出現,所以就圖表來看這一段時間,函數 CheckDay 回傳值都會是 True,加上電腦時間在 08:45 之前也算(以防你的 MultiCharts 與下單機都一直開著沒有關掉),就讓結算日的 13:41~ 隔天的 08:45 前,把 MP 指定成 0 的條件都成立}


RecalcLastBarAfter(1);

{這個指令是為了在沒有 tick 的時候,強迫這個訊號或指標的 code 都每秒 run 一次,透過這個指令,才能在 13:41 開始,把 MP 從原本的部位數值變成 0,輸出出去給下單機接收到,也因為這個變化是在沒有 tick 進來的狀況下,不可能會有換 bar,讓一般的變數值更新,所以才需要把 MP 宣告為 IntrabarPersist}


透過這樣在負責輸出部位數值給外接下單機的訊號或是指標,就能夠在 13:41 的時候讓下單機知道部位應該要變成零,而去執行下單的動作,雖然當時的委託送出其實是會失敗的(非該商品的交易時間),真實部位一樣進入結算,但下單機內的帳上留倉部位卻會歸零。我也就不需要另外手動去調整下單機內的帳上部位了。

K棒是否屬於結算日的判斷函數(CheckDay)請見:http://www.yctseng.net/2012/03/blog-post_13.html

熱門文章