其實我認知到有程式交易時,還沒聽過MC、AB、MT等知名交易軟體,只是一股腦的想怎麼實現整個交易過程,之後知道這些軟體時,早已經沉醉在寫程式的苦海中了,頭都洗一半了...。所以這套交易系統的規劃算是個人經驗的累積,包含資金控管、績效回測、滑價模擬、限價模擬、轉倉等等,再整合即時報價、盤後回補與下單API做到一條龍的程式交易系統,不需要再安裝第三方軟體即可運作(當然券商的API等還是需要的)。
先看看圖形介面可供設定的選項,對系統有初步認識後,再看交易策略腳本怎麼寫吧。
選單畫面
首先是選擇策略
整體設定 - 資控
點進"中控"可以看到...
第一次看到這個畫面會覺得有些混亂,解說一下。最上方看到[整體策略]跟[周K突破],分別點選後都會看到不同的選單,[整體策略]是針對群體的設定,其他例如[周K突破]是針對個別策略的設定。以這張圖來說,看到的是[整體策略]的設定(因為[整體策略]是以紅字顯示),整個看到的是[整體策略]>>[設定]>>[資控]
記錄檔:實單交易時須給定紀錄名稱,並選定紀錄方式到"不重置"。
執行模式:實單交易時須設定成"實單"。
資控:整體資控主要是設定本金與盈餘的分配比例。
整體設定 - 商品
點進"中控"可以看到...
這些是預設的可操作商品,設計上主要是針對期貨,選擇權也可以下,只有"台股"是不能下實單的,當然日後也是可以擴充的。策略中也可以設定成混和操作的方式。
整體設定 - 查價
當策略分析的商品與實際下單商品不同時就會有查價的需求,通常不用理會,只有在交易"非熱門合約"時需要設定成"以商品合約報價"。
交易撮合延遲可以用來模擬滑價的情形,這段延遲就相當於下單到交易所撮合成交的時間。
整體設定 - 追蹤
可以在特定的時間點暫停腳本,在策略開發期間可以用來檢視每個信號的合理性,也有助於類似覆盤的型態觀察。
整體設定 - 報價群
這裡可以看到所有策略執行需要的報價者,每一個都相當於一個副腳本執行核心(ScriptCore/InnerCore),負責提供報價、指標等數據供策略參考。
個別策略設定 - 策略設定
點選個別策略後可以看到...
這裡邊的設定可以減少開發策略腳本的困擾,自動平倉、轉倉等,減少腳本需要處理的事務。
個別策略設定 - 風險控制
主要是準備金的設定,與交易量的動態調控。
個別策略設定 - 信號規則
主要是抑制信號量,也可以直接在策略腳本中控制,都行。
個別策略設定 - 委託
實單交易時委託下單機構須設定為"康和期貨",這也是ACTrader唯一支援的期貨商,可以再擴充其他家,但暫時沒有需求與必要性,系統還算穩定。
個別策略設定 - 動作
這部分是用來手動干預信號或部位用的,畢竟有時還是會"出槌",像是報價斷線、下單失敗等,這麼多年還是有遇過幾次。
外掛 - 下單API
一樣只支援康和期貨。帳號密碼輸入完記得按下[Enter]鍵,再測試登入,確定沒問題後再勾"自動登入"。
芭樂單的測試會委託一個不可能成交的價位,只要券商軟體有看到委託,即算是有成功。
---
至此,加上先前介紹過的即時報價外掛,與程式交易相關的畫面大概都看完了。這套系統現在最大的限制就是只能下"康和期貨",因為從幼幼一直用到現在,穩定度還可以。
---
系統概述
在講策略怎麼寫前,容我先簡單陳述一下ACTrader的架構。整個系統有三個主要類別:
1.) ACTradeCenter : 如其名,它就是系統的中控,負責協調各個部分,也是MyScript(主腳本)必須繼承的對象。但這個部分已經有一個固定的腳本叫"策略集",會替開發者搜尋"library/策略集"下的所有策略,再透過圖形介面點選即可已加入策略。
2.) ACQuoter : 報價者。負責提供報價、指標等數據供交易策略參考,本身是以InnerCore(副腳本)的方式存在。
3.) ACTrader : 交易(策略)者,相當於交易策略。ACTradeCenter會在適合的時間點讓交易策略執行。
對策略開發者而言,要知道一個ACTrader(交易者)一定要配一個ACQuoter(報價者),之後衍生出另一種整合ACQuoter與ACTrader的類別,叫ACTactic,本身是一個ACQuoter,開發者需在其類別內建立一個ACTrader,即ACTrader宣告在ACQuoter內,也是現在最常用的方式。
ACQuoter的部分其實就相當於一個繼承了CustomCore的MyScript,照樣像以前一樣建立需要的指標即可。而交易動作的部分則集中在ACTrader上,為因應期貨、選擇權的操作屬性,又做了一個叫TWFOTrader的類別來繼承ACTrader,這個類別中附加了平倉的方式與時間,還可以選定交易商品、模式等,減少開發者的工作,若有不足時,也可以改寫另一個適合的類別,這就是物件導向繼承的好處。
策略範例
所以現在我們可以看一下策略要怎麼寫了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | class BREAK_WEEK extends ACTactic { static String nickname = "周K突破"; //指標宣告(程式碼與參數從UI導出) MA ma = addIdct("K線", "均線", new MA("N[0]=100.0&_color[0]=4291020916&_paint_width[0]=2.0&_cut_daily[0]=false")); TIMEFRAME week = addIdct("K線", "周K", new TIMEFRAME("period=5&validsize=10&_syncz[1]=true&_show[1]=true&_syncz_sft[1]=1.0&_syncz[2]=true&_syncz_sft[2]=1.0&_show[2]=true&_paint_width[2]=2.0&_color[2]=4278216345&_color[1]=4294927872&_paint_width[1]=2.0&_cut_daily[1]=true&_cut_daily[2]=true")); public BREAK_WEEK() { //給定預設值,不給也可以,之後再透過UI修改 CFG_PERIOD_N = 15; CFG_PERIOD_TYPE = PERIOD_MIN; } class MyTrader extends TWFOTrader { public MyTrader() { //給定預設值,不給也可以,之後再透過UI修改 CFG_BAR_SIGCNT = 1; CFG_DAY_SIGCNT = 1; } //交易策動 public void trader_trade() { //確保能參考到需要的資料 if (ma.isNullRef(1) || week.high.isNullRef(5)) return; double week3HL = ???; if (getSig() != D.STYPE_LONG && ???) { if (week3HL < ??? && ???) setSig(D.STYPE_LONG); //建立多方信號 else setSig(D.STYPE_CLS); //建立平倉信號 } if (getSig() != D.STYPE_SHORT && ???) { if (week3HL < ??? && ???) setSig(D.STYPE_SHORT); //建立空方信號 else setSig(D.STYPE_CLS); //建立平倉信號 } } } } |
這裡面可以看到兩個類別(class)的宣告,分別繼承(extends)了ACTactic、TWFOTrader,其中ACTactic相當於ACQuoter,TWFOTrader相當於ACTrader,也就是一個"交易者"包在一個"報價者"裡面的架構。
寫好後只需把這個腳本放在"library/策略集"下即可,之後再將圖格中腳本切換到"策略集",就可以看到寫好的策略選項。
---
接著大概看一下需要認識的API有哪些。對於一般的投資人,其實透過方才的範例就已經學到了足夠的API可以編寫策略了(即getSig與setSig)。
API - 中控(ACTradeCenter)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | public abstract class ACTradeCenter extends ScriptCore { //當中控準備完成會呼叫這個函數,通常會在此時建立策略 public abstract void center_ready(); //加入一個ACTactic public void addTactic(String ID, ACTactic tactic) //寄信(gmail). 寄收件人由UI設定. RTQOnly為true表示只有在盤中寄送. public void mailNotice(boolean RTQOnly, String title, String content) //暫停執行. 偵測交易狀況用. 繼續執行的按鈕在除錯視窗中. public void pause(ACTrader trader) //取得某ACTrader的初始資本 public double getInitPrincipal(ACTrader trader) //取得某ACTrader的可再投資資本 public double getReinvest(ACTrader trader) //取得某ACTrader的可投資資本 (即InitPrincipal+Reinvest) public double getInvestableFund(ACTrader trader) } |
在ACTrader中可以用"center"這個變數名稱對應到ACTradeCenter。
還有些跟選股回測相關的沒列出來,手上也沒有好的範例,暫時就別徒增困擾了。
API - 報價者(ACQuoter)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | public class ACQuoter extends CustomCore implements ParamIns { //指定報價符號 public String CFG_SYMBOL = ""; //指定結算商品 public String CFG_SELLTE_COMM = ""; //指定K線週期N public int CFG_PERIOD_N = 10; //指定K線週期 public int CFG_PERIOD_TYPE = PERIOD_MIN; //指定報價刻度 public int CFG_PRECISE_TYPE = PERIOD_AUTO; //指定K棒保留數量 (避免多策略時造成記憶體不足) public int CFG_VALID_KSIZE = 10000; //--- //報價者ID public String QID = null; //中控 public ACTradeCenter center; //K線圖層 Layer lay_k = null; //信號圖層 Layer lay_sig = null; //--- //報價init() public void quoter_init() {} //報價run() public void quoter_run() {} //取得報價對應合約的剩餘天數 public int getValidDays() //檢查時間是否已過合約收盤時間-backward_time(ms) public boolean timesup(long backward_time) //ms //檢查時間是否穿越hhmmss public boolean timecross(int hhmmss) //檢查時間是否在hhmmss1與hhmmss2之間 public boolean timeinside(int hhmmss1, int hhmmss2) } |
有初始值設定(CFG_開頭)的部分,以及getValidDays()用來取得距離結算的天數。如果還有額外的指標或變數要運算可以寫在quoter_run()中。
API - 交易者(ACTrader)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | public abstract class ACTrader extends ScriptBasic implements CorePartner, ParamIns { //---信號限制設定主要是基於安全性 更細部的動作控制還是要寫到策略中 //設定一日的信號數量 public int CFG_DAY_SIGCNT = 99; //設定一根K棒的信號數量 public int CFG_BAR_SIGCNT = 1; //--- //交易者ID public String TID; //中控 public ACTradeCenter center = null; //監視的報價者 public ACQuoter quoter = null; //統計 public STATS stats = null; //當下信號 public RecSig curr_sig = null; //---(事件類型,供複寫(Override)) //策略部分. public void trader_init(){}; public void trader_run(){}; public void trader_eop(int type){}; public void trader_menu(HtmlInputHelper html){}; //策略處理. public abstract void trader_trade(); //信號部分. public void sighd_init(){}; public void sighd_run(){}; public void sighd_eop(int type){}; public boolean sighd_trade(){return true;}; public void sighd_menu(HtmlInputHelper html){}; //信號處理 (產生標的物及目標口數) public abstract void sighd_sig(final int stype); //--- //設定信號 public boolean setSig(int stype) {return setSig(stype, null);}; public boolean setSig(int stype, String desc) //取得當下信號 public int getSig() //--- //取得交易合約 public Contract getContract(String comm_key, int cont_shift) //取得選擇權交易合約 public Contract getContract(String comm_key, int cont_shift, int cp, double price, int p_shift) //--- //信號發生的t點 public int sigT = -1; //信號清除(平倉)的t點 public int clsT = -1; //信號發生或清除的t點 public int actT = -1; } |
大致比較有機會用上的有這些。在前面的範例中我們只用到了trader_trade()、getSig()、setSig()就足以完成一個策略,其他像是交易商品、結算、準備金、口數控制等都可以透過圖形介面修改,除非要做比較特別的交易方式,不然這樣差不多夠了。
擴充類別
有兩個功能是可以擴充的,分別是風險控制(交易量調控、RiskCtrl)與停損停利(StopCtrl),只要分別繼承(extends)這兩個類別放在程式碼中,就可以在UI選單中找到,若放在library中就可以讓所有策略共同使用這些功能,不用一直重寫,也方便嘗試不同搭配。詳細的寫法在library/ACTrader中都可以找到範例(搜尋關鍵字類似"extends RiskCtrl")。
總結
本著童叟無欺的理念,最後還是要很客觀的評價自己的東西。如果你是一個放眼世界的投資人,AC不會是一個好選擇,甚至不會是一個選項,這是可以理解的,畢竟小弟隻身一人、沒有團隊支援、沒有財經背景,也是盡了很大的努力才只有這樣的進度。
---
2017-05-07更新
花了幾個月的時間熟悉了一下Multicharts,很快就進入狀況了,報價與下單也都整合的不錯,我的程式交易平台已經完全轉移到MC上了,也就是說我已經放棄AC程式交易的部分了,以一個程式開發者而言我感到有些遺憾,但以一個交易者而言我感覺得到了解脫,終於能夠認真地從事交易了.
沒有留言:
張貼留言