2018年9月8日 星期六

「內外盤」計算及其應用


在看盤軟體中,我們經常會看到稱為「內外盤」的數字,這組數字與「成交價」、「五檔報價」,並列為盤中 3 大最重要的指標,在預測股票「日內走勢」上,內外盤具有非常高的成功率。


其實在證交所或期交所的即時資料中並沒有所謂的內外盤,那是劵商利用「五檔報價」和「成交價」分類出來的結果。簡單地說,就是由「五檔報價」挑出最佳買賣價,如果成交價比較靠近買進價則稱為「內盤價」,反之則稱為「外盤價」,而其成交量則分別稱「內盤量」、「外盤量」。

接著示範利用元大行情API為訊號源,然後程式會將成交價分類為內外盤,所採用的程式語言是VC++ ,並引用了MFC( Microsoft Foundation Class Library ) 類別庫。程式自動交易原本用C語言來寫就比較方便因牽涉到作業系統底層API ) 再加上元大報價API是採用元件物件模型(Component Object Model),我原本熟悉的NetBeans編輯器雖可開發C++的程式,但卻無法處理COM元件,因而改用VC++ 。 但MFC是一種圖形介面和事件驅動的程式,編輯器會自動加入許多程式碼,因此我只能挑重點來介紹。
                         

                             

上圖第一行中的三個參數,原本在元大行情API的變數代號為BestBuyPri BestSellPri MatchPri,分別代表最佳買進五檔價、最佳賣出五檔價、成交價。第六行是找出買進價,第七行的 atof 是將字串轉換成浮點數值,第十五、十七行則是利用距離的觀念來判斷內外盤價。


有了內外盤價和內外盤量之後,就可以有各種變化應用了。例如可以利用內外盤量差達五千口就作空;內外盤量的比值與即時漲跌幅差異過大,就可以去作多(作空 );只要有這些歷史資料,就可以作各種實驗和變化,當然最後一定要回測績效才能下場。

底下展示一張今年八月二日分鐘級的散佈圖,縱軸是外內盤量的差,橫軸是當時的漲跌幅。特別值得注意的是,如果用一條線性迴歸線來代表這些資料點,其判定係數(Coefficient of Determination )高達99%以上,代表外內盤量的差與漲跌幅間,呈現強烈的線性正相關。不僅是這天,只要是當天「日內走勢」有出現趨勢性走勢,其判定係數都高達96%以上,這些數字對迴歸分析有研究的人來說,就會是莫大的啟發。




程式(.cpp ) : https://drive.google.com/file/d/1A5AIlG3tibuBf5aC8TNhclpH0fLlPScd/view?usp=sharing

2017年9月22日 星期五

策略模組- 類神經網路(1)

類神經網路(Neural Network)是人工智慧的一支,我十幾年前就開使接觸這類東西,現在好像已改名叫『深度學習』。本質上就是利用數學所建構出來的一門學問,如果要玩玩其實也不難,我以前就是用matlab的工具箱,把參數設一設,然後把資料丟進這個黑盒子,也不去探究其理論(這理論說實在的,也不容易懂),結果程式跑出來就是"Garbage In,  Garbage Out"。所以建議有心要把這玩意應用到股票市場的人,要對其數學理論有些了解才行,這方面資料請見參考資料一 。

matlab有個壞處,它可能為了商業利益,幾乎年年改版,雖然只是改一些皮毛的東西(核心部分很少改) ,但如果版本不符,程式執行時就會有問題。在此將利用Java語言為工具,重新檢視類神經網路及其應用,本篇只是開頭,後面將有實際應用到股票市場的預測。首先,來作一個Iris(鳶尾花)的分類問題,為什麼會先作這個問題﹖Iris資料集可說是在樣式辨認研究中,最常被引用到的資料集,它可以很客觀地確認系統的分類能力,這樣去作更複雜的問題才能走得更穩。

此外,在這邊使用一個Oracle的開源碼 - Neuroph,它是用來開發神經網路架構的輕量級java框架。該框架提供一個java程式庫以及一個GUI工具(稱為NeurophStudio),可以用它來在java項目中創建和訓練自己的神經網路,其下載點見參考資料二。
 




上圖第37行顯示創建一個多層前饋倒傳遞網路(Multilayer Feedforward Neural Network with Backpropagation Training),多層前饋網路(通常應用上只會用到三層,也就是只有一層隱藏層)是目前被應用最多的網路結構,而倒傳遞則是最常用的監督式網路學習法則。這個網路共有三層,輸入層、隱藏層、輸出層的神經元個數分別為4163

第45~53行則分別建立訓練資料及測試資料,訓練資料有100筆,其餘的50筆則留作測試資料。

訓練資料的精確度可達98%,而測試資料的精確度也可達96%,也就是50個樣本只會錯 2個。很多人看到這個結果一定相當滿意了,也對類神經網路的能力刮目相看。其實這是因為這個dataset太『純淨』,特徵也太明顯了,說句比較不入流的話,就算不用類神經網路,用其他的分類器隨便作,預測的結果也應該都不錯。相對而言,股票的資料就充滿雜訊,也可能會有互相衝突的訊號,因此預測結果的好壞,關鍵其實是在特徵選擇(Feature Selection)及資料的前處理,不過這個主題必須另闢專章來討論了。


參考資料
Hagan & Demuth & Beale, "Neural Network Design", Thomson Learning,Inc.,1996. 台灣翻譯本: 類神經網路設計,譯者: 汪惠健, 經銷商: 普林斯頓國際公司。

二、http://neuroph.sourceforge.net/download.html

三、資料檔及程式碼下載 :  https://drive.google.com/file/d/1HSzx4If2rBjOyz-yjo2hzHz_DoTT89OY/view?usp=sharing
 
   

2017年7月8日 星期六

策略模組- A. 小台指動能策略(當沖)

再來就是策略模組了,這個模組須結合前面兩個模組,所以程式看起來會比較複雜。這個範例的基本精神就是『追高殺低』:當成交價超過開盤價40點,且每分鐘成交量超過1200口,買進小台期貨一口;當成交價低於開盤價40點,且每分鐘成交量超過1200口,賣出小台期貨一口,且於收盤前平倉。


先在此聲明,該策略不保證賺錢。應該也有人會問,上面的一些數字,如1200口等是怎麼來的?答案是用歷史資料回測來的。



上圖第14行起為下單模組,我把下單會用到的一些方法都寫在這個類別內。一般習慣是會把這個類別寫在另外一個檔,在這邊因為下載的便利性,就把它們都放在同一個檔,不過熟悉Java語言的人都知道,編譯過後會產不同的位元碼檔案。




上圖第127行起為這個範例的主要類別,main方法就是寫在這個類別內。我把一些參數設定,統一寫在第135~148行以方便管理,各位將來當然可以自己改參數,不過建議最好要用歷史資料回測。


2017年7月6日 星期四

即時報價模組- A. excel 報價

目前一般劵商會免費提供的報價有DDE RTD、及API報價,這三者經常會以excel為輸出,最後一個可能有些資格限制,因此從excel讀取報價是最常見的途徑。若是採用DDE報價,通常還要開著劵商的看盤軟體,在記憶體的用量上會比較吃緊,RTD報價則毋須開啟劵商的看盤軟體。


還是同樣的理由,Java無法直接讀取excel內的資料,在這邊我使用一個叫JDDE的套件,這個套件是提供excelJava間作DDE的溝通,其下載點:http://jdde.pretty-tools.com/examples.php





上圖第16行顯示我的資料來源是RTD。在這個範例程式中,我使用一個timer2秒去抓一次報價(這個設定是寫在第44~45行),若成交價低於某一個價位則印出訊息。因為這只是個範例程式,我不想讓程式變的太複雜難懂,一般實際的狀況是送出委託單,那就是插入之前介紹的下單模組


2017年7月5日 星期三

下單模組- B. 元大下單API

元大下單API是採用元件物件模型(Component Object Model),這是上世紀九零年代微軟所發展的一套規範,它制定了用戶端程式與及元件間溝通的介面,以達到相互操作(interoperability)所應共同遵循的一套標準。在使用該元件之前,必須先向作業系統註冊,元大下載的檔案裏有一個install_YTFutOrdAP.bat檔可用來執行此動作,但記得使用系統管理員身分執行。


同樣的原因,Java不能直接調用COM,在這邊我是使用JACOB(Java COM Bridge),其下載點: https://sourceforge.net/projects/jacob-project/






上圖第17行中『Yuanta.YuantaOrdCtrl.64』是元大下單元件在註冊表中的名稱。第20行用了一個DispatchProxy的類別,這個類別的作用是在兩個執行緒間傳送COM物件。這一行程式花了我大概一個月的時間,原因是JACOB這套件的API文件寫得不清楚,許多用法都要花時間去試,加上當初我對元件物件模型的運作原理不是很瞭解,因此不明白client端的介面指標無法直接指到物件的介面,必須透過proxy介面作傳送。如果有人不看我的程式碼,能在一個月內把程式寫出來,希望給我個電郵,咱們交個朋友吧。

36~40行是期貨委託的參數,總共15個參數須傳送,一個也不能少,就算是不必填的參數也要用空白傳送,算是蠻麻煩的。目前我也只想到把它寫成方法,以減少不必要的參數,但若要傳送多筆委託,這樣的寫法還是很不方便。


2017年7月1日 星期六

前言

程式交易是近年來相當熱門的交易模式,許多劵商大力的在推這個項目,主因是一方面可增加手續費,另一方面可收取平台使用的租金。以目前最流行的交易平台MultiCharts來說,一個月的租金大概也要一千元,除非你已經有一個很賺錢的策略在跑,要不然這也是一個負擔。

由於網際網路的發達,新一代的學子很多在學校都有學過Java語言,但能夠把它用在程式交易上的卻很少,原因是Java最大的特色在於它的跨平台性,也就是同一支程式無須作修改就可以在windowsiosandroid 等作業系統上運作。Java在作編譯時是把原始碼翻成位元碼(bytecode),而不像C等其他語言編譯成機械碼,因此只要作業系統上有安裝Java 虛擬機器(JVM),就可執行該位元碼。但程式交易如自動下單、讀取即時報價等功能都牽涉到作業系統底層的APIJava在這方面的操控能力就很差,必須借助JNI(Java Native Interface)及其衍生的套件(如後面會用到的JNAJACOB),而這些資料在一般Java的教科書上絕對找不到,網路上或許有,但必須先把它消化吸收。

或許有人會嫌Java不是編譯成機械語言,因此執行速度比較慢。我曾針對此論點加以測試:用台指期這種大成交量的商品,以市價委托下單,然後觀察下單和成交時間,基本上在『秒』這個數量級是沒有差別的,除非你的策略要求到『毫秒』等級。每一種程式語言都有它的強項和弱點,Java的強項是在網際網路的應用,要不然你用C語言來寫個網路程式看看。而我之所以開這個部落格,一來是Java在這方面的應用較少,另一方面是公開我辛勞的成果,讓有興趣的同好少走點冤枉路。

接下來簡介程式交易的模組,很多部落格在這方面已著墨很多,但為顧及文章完整性及部落格的連貫性,因此在這邊簡單提一下。

下單模組:以劵商所提供的API(Application Programming Interface)下單,我會分別介紹日盛及元大的下單API,並提供Java程式下載。這些程式碼只要你有帳號密碼,都是實際可運作的。

即時報價模組:這也是程式交易不可或缺的部份,目前一般劵商會免費提供的報價有DDE RTD、及API報價,前兩者通常會以excel為輸出,最後一個可能有些資格限制。既然從excel讀取報價是最常見的,因此我會介紹一個叫JDDE的套件。此外,我一直想從劵商的Ajax網頁抓取即時報價,但這方面一直還有些問題。

策略模組:前面兩個模組算是基礎,這個模組才是真正決定是否會賺錢的部份。但據很多程式交易者表示,真正賺錢的策略很難寫,而且這跟交易者的個性、心智狀態有絕對關係(因交易者可能隨時把程式停掉)。當然我也會演示一個範例,但『師父領進門,修行在各人』。


2017年6月30日 星期五

下單模組- A. 日盛下單API

首先,我要介紹一個我正在使用的下單API- 日盛API,這裡可能有點打廣告的嫌疑,不過在這塊他們的確比別的劵商更用心在經營。我後面會再介紹元大的下單API,他們可能是把重心和資源都移往MultiCharts了,因此使用上就要困難且麻煩。

日盛HTS API是以單一DLL(Dynamic Linked Library, HTSAPITradeClient.dll)形式提供函數,讓外部程式呼叫HTS 應用程式的下單核心服務,因此只要在Java程式中載入HTSAPITradeClient.dll即可使用它所提供的所有下單功能。另外日盛還提供一個 API Trade Manager,它的畫面如下:



這個畫面顯示它有模擬下單和正式下單,也有提供下單次數限制的防呆功能,我認為這一點在程式測試階段很重要,想像如果因為程式裏的一個疏忽,導致在一秒內以市價下了一百口的台指期,那時真的想哭都哭不出來。

前面提到在Java程式中載入HTSAPITradeClient.dll即可使用下單功能,但dll是一種與平台相依的函式庫,Java沒辦法直接叫用它,我這邊是使用了JNA套件,該套件的下載點https://github.com/java-native-access/jna

如下圖,程式的第16~23行是載入HTSAPITradeClient.dll,這個動作會在程式的最開始時執行;第25~29行是宣告一個介面,而這個介面是繼承JNA套件中的StdCallLibrary介面,另外在第27~28行宣告了兩個方法,這兩個方法都是日盛HTS API內的函數。我在這邊只示範了兩個函數,其實日盛API內還有很多函數,請各位真的有用到時再去參考。



最後提醒一下,目前HTSAPITradeClient.dll只能用在Windows x86