2017年12月26日 星期二

證交所最佳五檔的程式解析

證交所提供了股票即時最佳五檔的網頁,供一般民眾查詢(但我相信,會觀注的多半是碼農,從最佳五檔的網址,它主要的Host是 mis.twse.com.tw ,這是我們要注意的第一個點,透過 dig command,我們可以發現twse.com.tw網域用了4台DNS主機來應付輸詢,這也是我要提的第一個建議:
若不是用瀏覽器執行JavaScript程式
 URL直接採用網址IP連結,不要使用mis.twse.com.tw網域,輸詢太多次會卡住,且若每次輸詢結果不一致時,會導致Session遺失
再來針對它的程式設計加以說明:
先說一下,用網頁查詢的網址格式是
http://mis.twse.com.tw/stock/fibest.jsp?lang=zh_tw&stock={代號}
,在瀏覽器下通常lang=zh_tw參數會被省略,但是程式設計時,請不要忘了要加上去。這是最重要的一個關鍵,因為我們必須在這頁取得Session(並且要保留),否則後面的資料存取將無以為繼,所以若是以程式要取得Session的第一件事就是連到
http://mis.twse.com.tw/stock/fibest.jsp?lang=zh_tw
我們取得這個網頁只是為了取得Cookie
然後我們再檢閱最佳五檔的網頁源碼, 可以發現一個重要的JavaScript:ctrl.fibest.js,所有的故事從這裡開始:假設我們查詢的是6294智基,它會先到(參考 function initStock()) http://mis.twse.com.tw/stock/api/getStock.jsp?ch=6294.tw&json=1&_=時間亂數
取回6294的程式代號
{
   "msgArray":[
      {
         "ex":"otc",
         "d":"20170109",
         "it":"12",
         "n":"智基",
         "i":"20",
         "ip":"0",
         "w":"110.00",
         "u":"134.00",
         "t":"07:50:00",
         "p":"0",
         "ch":"6294.tw",
         "key":"otc_6294.tw",
         "y":"122.00"
      }
   ],
   "rtmessage":"OK",
   "queryTime":{
      "stockDetail":2315,
      "totalMicroTime":2315
   },
   "rtcode":"0000"
}
其實這裡不難看出上市代號前綴 tse_,而上櫃代號則前綴 otc_,作為碼農,您應該找個地方把所有代號的上市櫃狀態記錄在某個地方,並不時更新,若不知道請參考
http://isin.twse.com.tw/isin/C_public.jsp?strMode=2

http://isin.twse.com.tw/isin/C_public.jsp?strMode=4
另外,tse_t00.tw與otc_o00.tw分別為上市櫃指數代號
 2017/8/26 開始在取得最佳5檔前,必須先經過
http://mis.twse.com.tw/stock/api/getStockInfo.jsp?ex_ch=tse_t00.tw|otc_o00.tw|tse_FRMSA.tw&json=1&delay=0&_={時間亂數}
請注意,| 必須escape %7c(c必須為小寫)
然後再參考下面一點取得5檔資料
最後是取得五檔資訊(參考 function loadStockInfo()),它會載入
/stock/api/getStockInfo.jsp?ex_ch=otc_6294.tw&json=1&delay=0&_=時間亂數
實際上這個連結反履變過數次,若是資料出不來,就回報檢查看看是否這裡有所變動,其資料回傳範例如下(BJ4,自已對一下就知道欄位義意,該注意的是它的Json資料型態是Array,可見是為了可以回傳多筆查詢),註:回傳的json其值必須包含 "rtcode":"0000" 項問才可視為查詢成功,若不是,則請重新查詢
{
   "msgArray":[
      {
         "ts":"0",
         "tk0":"2330.tw_tse_20170116_B_9999925914",
         "tk1":"2330.tw_tse_20170116_B_9999925580",
         "tlong":"1484528728000", //目前時間
         "f":"217_1784_1144_1788_1190_",            //五檔賣量
         "ex":"tse",
         "g":"2165_1133_3126_1611_1962_",           //五檔買量
         "d":"20170116",
         "it":"12",
         "b":"179.00_178.50_178.00_177.50_177.00_", //五檔賣價
         "c":"2330",
         "mt":"549353",
         "a":"179.50_180.00_180.50_181.00_181.50_", //五檔賣價
         "n":"台積電",
         "o":"180.00",  //開盤價
         "l":"179.00",  //最低成交價
         "h":"180.50",  //最高成交價
         "ip":"0",      //1:趨跌,2:趨漲,4:暫緩收盤,5:暫緩開盤
         "i":"24",
         "w":"163.50",  //跌停價
         "v":"6359",    //累積成交量
         "u":"199.50",  //漲停價
         "t":"09:05:28",//揭示時間
         "s":"34",      //當盤成交量
         "pz":"180.00",
         "tv":"34",
         "p":"0",
         "nf":"台灣積體電路製造股份有限公司",
         "ch":"2330.tw",
         "z":"179.50",  //最近成交價
         "y":"181.50",  //昨日成交價
         "ps":"2459"    //試算參考成交量
      }
   ],
   "userDelay":...
   ...
   },
   "rtcode":"0000"
}
第3點是取得單一股票的方式,另外它也有方法可以同時取得多檔股票記錄,它取得的方式是:
http://mis.twse.com.tw/stock/api/getStockInfo.jsp?ex_ch=代號1|代號2|...|代號N&cp=0&json=1&delay=0&_=時間亂數
,範例如下(要注意HTTP Get 有長度限制):
http://mis.twse.com.tw/stock/api/getSTKInfo.jsp?ex_ch=tse_2377.tw%7cotc_6294.tw%7c&cp=0&json=1&delay=0&_=1483942971571
2017-8-12註:|(pipeline)  若要編碼請一定編為%7c(小寫),因為在前一天(8/11),證交所不再接受%7C了
取回的資料格式跟第3點類似,只不過取回的資料是一次多筆罷了,所以作為碼農,打開IDE,開始寫程式去吧!

上面的解析,寫成Java程式,可以從此處下載(程式碼在此),下載程式後只要在命令視窗下執行 

來源:http://kentyeh.blogspot.tw/2015/07/blog-post_16.html

0 意見: