2014年7月20日

股市自動交易系統(半完成品) - 設計發想與架構

隨著台股上9000點,加上最近比較沒這麼忙,
又想起了一直想做的程式交易。

在先前,為了做程式交易,我陸續自行開發了許多程式交易的程式和元件,
但最終因為一個人人力有限無力負擔,加上回測部份一直沒有完成,
操作演算法一直沒有頭緒,因此就讓它自然荒廢了,
我想,網路力量大,把它Open Source出來,也許會有比較多人想一起來寫,
這篇,會先介紹這個未完成系統的架構與設計發想。

程式交易架構:
程式交易系統千千萬萬,但不外乎下面這幾個元件:


設計發想:
在開始設計時,我有幾個需求:

  1. 希望在Linux上進行程式交易
  2. 希望能夠有彈性,方便開發和修改交易演算法
  3. 全自動操作,免人為操作
  4. 最好有類似證券軟體的GUI可以回測


因為上述條件,我開始進行設計。

設計:
即時資料源:
在台灣,台灣的證券公司普遍提供Microsoft DDE做為即時資料源,
我不得不說,DDE這東西已經快變成骨灰了,Microsoft自己都不太維護這東西了,
證券公司是該改改了吧,
人家國外直接有IB提供完整的API,可以抓歷史資料、即時資料、下單,
靠DDE是要打混摸魚到什麼時候?
離題了.......

因為DDE是Microsoft的東西,Linux一定不支援,
加上要做到全自動,自動啟動證券軟體的開啟、登入是必要的,
因此針對Windows的DDE,我做了下面的設計:

這個設計簡單說,就是在Windows上寫個Agent,
Linux端透過Agent取得資料源的資料,
Linux端也透過Agent控制證券軟體的操作。

歷史資料:
歷史資料主要就是Parse證交所網頁的每日資料和歷史資料,
當然也可以從證券軟體中把歷史資料匯出到Excel後取出。

歷史資料的儲存,設計上是儲存到mysql,
但理論上,因為它沒有用特殊語法,因此它應該可以支援各式SQL Server。
設計如下:

下單:
在元大寶來有提供B2CAPI,可以透過寶來點金靈進行下單,
但和取得即時資料有相同的問題,它只支援Windows,不支援Linux,
因此設計上和取得即時資料相同,都要透過Windows的Agent進行操作。
設計如下:

交易演算法:
這裡的交易演算法,是我的稱呼,它其實就是俗稱的「下單機」、「自動交易程式」...等。
設計上就是JavaATS Server(ATS為Automated Trade System的簡稱)。

它的設計發想包含2部份:

  1. 它是Time Trigger的系統
  2. 演算法容易開發、維護


Time Trigger設計:
在設計時,它的定位不是高頻交易系統,也不是當沖系統
它的設計比較趨近於短線操作(精確度:分鐘),或中長線操作(精確度:天以上),
因此它並不是根據成交觸發的Event Trigger設計
它的設計是以Time Trigger的方式,定時觸發執行。

它有2種Time Trigger觸發執行,
一種是以秒為單位的定時觸發,
另一種的執行週期最短執行為每分鐘,最長可以是數天甚至數週。

為了提供彈性的定時執行計畫,我以Linux的crontab設計為發想,設計了下面這樣的語法:
*_*_*#* *:*/1

[年]_[月]_[日]#[週] [時]:[分]

語法和crontab類似,
可定義「某年」、「某月」、「某日」、「某周」、「某時」、「某分」。

和crontab一樣,它可以定義週期執行,例如:
*_*_*#* *:*/1

*/1     表示每分鐘執行

和crontab一樣,它可以定義多個特定時間點,例如:
*_*_*#* *:1,5,10,15,20,25

1,5,10,15,20,25     表示每小時的1分、5分、10分、15分、20分、25分執行

和crontab一樣,它可以用「*」定義是否mask該時間設定,例如:
2014_7_*#* 13:0

2014年7月,每天的13:00執行

這樣的設計理論上可以提供極大的彈性,規劃出任何時間的週期執行。

這個設計的缺陷是,它不支援以秒為單位的短時間觸發,
因此,我另外設計了Interval Timer Trigger,可以設定固定間隔幾秒觸發執行。

演算法設計:
在我一開始找程式交易相關資料時,注意到下面幾個是大部分人的開發系統:

  • Excel
  • HTS

Excel:
Excel因為有大量Cell和方便的圖表產生器,
最重要的是,它有方便的VBA可以開發,
因此是很多人入門的首選。

HTS:
HTS實際上裡面提供了Power Language的程式開發功能,
可以簡單的開發出交易程式,搭配HTS內提供的圖表,可以方便的回測。

再經過一段時間的摸索後,我得出一個重要結論,
演算法不好開發,等於無法使用。

想想看,我希望有個MA(移動平均)資料,卻要寫出2頁程式碼,
這應該沒人受得了,
但偏偏傳統的通用語言C/C++、Java、Python、Perl、PHP...等,
都不是針對自動交易設計,一定是難用又難受,
光想到寫個簡單的邏輯演算法,卻要Compile再Compile,
如果是C/C++,甚至還要處理new、free、delete的問題,嗯.....很痛苦.......

但矛盾的是,大部分的程式資源,又都集中在C/C++、Java...等通用語言上,
像Power Language這類語言,沒有提供的功能,你就是無法使用,
試想看看,一個開放的競技場,不限定使用的武器,
但你用Power Language,表示你只能用長矛、用盾牌、用護甲。
槍呢?對不起,沒有提供
劍呢?對不起,沒有提供

我認為在先天上就輸了,你用它可以贏過沒有裝備的人,
但對於有能力自製武器的人而言,你先天就輸了,因為你缺乏武器........

為此,當時我找了一些Open Source的Script,
加上Java ATS一開始是用Java設計,
因此後來選定了BeanShell做為開發。

BeanShell本質上就是Java,理論上所有Java SDK都可以透過BeanShell呼叫執行,
BeanShell以Script方式執行,可以很方便的在修改後直接執行,
不用經過Compile,Java不用解釋了,它不用free/delete,
這能夠很大程度的降低開發門檻。

剩下的麻煩是呼叫方式,我希望簡單的呼叫個function,
就能夠達成,例如:
BUY(0050, 1);           //買0050,1張

因此,我當時決定寫個API,就叫做StockAPI,
提供些會用到的function,能夠方便的呼叫使用,
裡面實際上就包裹了實際操作的麻煩。

針對上述的2項設計,以及前面的幾項元件,其架構如下:
訊息通知:
訊息通知不外乎就是,
下單後通知自己,已經下單,
成交了通知自己,已經成交,
有危險時通知自己,快點逃命。

訊息通知方式,不外乎有數種IM軟體,包括:

  • MSN
  • Skype
  • GTalk
  • LINE
  • What's App
  • Yahoo Messager


實際上,有提供API的,大概只有

  • MSN
  • GTalk


Line和What's App都沒有免費提供API,Yahoo Messager我沒有使用,
Skype好像有,但之前很少用,現在被Microsoft併購後,SDK是否有提供不清楚。

因此在先前,我先開發了MSN的Client,後來寫了GTalk的Client。

SMS?
SMS要花錢,原則上直接排除。

回測:
很不幸的,回測部份我並沒有找到很好的回測設計方式,
這也是這個系統遲遲無法使用的主要原因之一。

我本來期望的是,能夠類似HTS一樣,下個Draw之類的就能畫出來,
但不幸的,每種資料的資料形式差異太大,
資料的X軸、Y軸標記形式太多,
並沒有一個固定的模式可以動態產生所有想要的圖形,
因此沒有設計出來。

另一方面,回測的作法目前我也沒有概念,
是用類似replay的方式餵資料,或者載入後直接顯示在圖形上,
還沒有想好設計方式,因此回測部份目前沒有任何設計。


6 則留言:

elleryq 提到...

訊息通知可以考慮用 pushbullet 這個服務。
或是提供 RSS,這樣就可以用 ifttt 讓使用者自訂怎麼通知自己。

傅阿呆 提到...

感謝!我會研究看看!

傅阿呆 提到...

pushbullet我昨天和今天有試著玩過,的確是相當方便好用。
今天簡單的用Java寫Demo Code,也很容易就寫出來了,之後會將它加入進去。

Dean 提到...

台灣也有另一位大大寫Open Source 程式交易系統,可惜大家沒有合作,不然完成度應該比較好
http://blog.lifetaiwan.net/2013/03/autotrader.html

匿名 提到...

感謝分享!

鄭傳耀 提到...

請問 如果我想做到 看盤中有下 大單(超過20或50張) 有辦法可以做到嗎?