最近在咖啡店看到好多人在研究股票,看股票數據的程式其實很多,但對我來說,只要能知道即時報價即可(雖然有三竹的App),於是好奇查了一下有沒有公開的API可用,雖說證交所有提供公開API,但沒有即時報價,最後是找到官方網頁上的API,雖說這不算正規的使用方式,但我想只要頻率不要太高,應該是不會被官方擋掉。

以下是API的格式:

https://mis.twse.com.tw/stock/api/getStockInfo.jsp?ex_ch=tse_{stock code}.tw&json=1&delay=0&_={unixtime}

參數只有兩個:

  • 股票代號
  • 目前的 Unix Time

所以只要使用 HttpClient 就可以抓到 JSON 資料了,以台積電為例,它所呈現的資料如下:

{
   "msgArray":[
      {
         "tv":"5517",
         "ps":"5504",
         "pz":"545.0000",
         "bp":"0",
         "fv":"13",
         "oa":"547.0000",
         "ob":"546.0000",
         "a":"546.0000_547.0000_548.0000_549.0000_550.0000_",
         "b":"545.0000_544.0000_543.0000_542.0000_541.0000_",
         "c":"2330",
         "d":"20231016",
         "ch":"2330.tw",
         "ot":"14:30:00",
         "tlong":"1697437800000",
         "f":"512_1601_536_362_218_",
         "ip":"0",
         "g":"372_209_713_856_509_",
         "mt":"000000",
         "ov":"32676",
         "h":"547.0000",
         "i":"24",
         "it":"12",
         "oz":"546.0000",
         "l":"542.0000",
         "n":"台積電",
         "o":"546.0000",
         "p":"0",
         "ex":"tse",
         "s":"5517",
         "t":"13:30:00",
         "u":"608.0000",
         "v":"19830",
         "w":"498.0000",
         "nf":"台灣積體電路製造股份有限公司",
         "y":"553.0000",
         "z":"545.0000",
         "ts":"0"
      }
   ],
   "referer":"",
   "userDelay":5000,
   "rtcode":"0000",
   "queryTime":{
      "sysDate":"20231016",
      "stockInfoItem":2386,
      "stockInfo":100981,
      "sessionStr":"UserSession",
      "sysTime":"18:24:32",
      "showChart":false,
      "sessionFromTime":-1,
      "sessionLatestTime":-1
   },
   "rtmessage":"OK",
   "exKey":"if_tse_2330.tw_zh-tw.null",
   "cachedAlive":31075
}

程式碼非常簡單,就一段而已:

using System.Text.Json.Nodes;

string unixtime = DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString();

string stockCode = "tse_2330"; //台積電,前面要加 tse

HttpClient client = new HttpClient();
client.BaseAddress = new Uri("https://mis.twse.com.tw");
var response = await client.GetAsync($"stock/api/getStockInfo.jsp?ex_ch={stockCode}.tw&json=1&delay=0&_={unixtime}");
string jsonStr = await response.Content.ReadAsStringAsync();
JsonNode jsonNode = JsonNode.Parse(jsonStr.Trim());

if(jsonNode["rtmessage"].ToString()=="OK")
{
    string price = jsonNode["msgArray"][0]["pz"].ToString();
    string name= jsonNode["msgArray"][0]["n"].ToString();
    string fullName= jsonNode["msgArray"][0]["nf"].ToString();
    string serverTime= jsonNode["queryTime"]["sysTime"].ToString();
    string updatedTime = jsonNode["msgArray"][0]["t"].ToString();
    Console.WriteLine(price);
    Console.WriteLine(name);
    Console.WriteLine(fullName);
    Console.WriteLine(serverTime);
    Console.WriteLine(updatedTime);
}

不過要做到真正能使用,還需設計架構。

參考資料