Jamyy's Weblog

Google Apps Script: 取得即時股價

by Jamyy on 一月.27, 2015, under Coding


目的: 從台灣證券交易所基本市況報導網站取得指定股票之當盤成交價, 更新於 Google 試算表

2015-06-26 更新: http://mis.twse.com.tw/stock/api/getStockInfo.jsp?ex_ch=tse_2330.tw_20150626&json=1&delay=0&_=UNIX_Timestamp (ref)

開啟 Google 試算表, 點入 [工具] → [指令碼編輯器...] 編輯以下內容 ( ):

function myFunction() {

  //取得 ActiveSheet 資料表內容
  var sheet = SpreadsheetApp.getActiveSheet();
  var aryData = sheet.getDataRange().getValues();

  //以資料時間判斷是否需要更新資料
  if (checkIfNeedToRun(aryData[0][14])) {

    //從第二列開始讀取 Sheet 資料
    for (var i = 1; i < aryData.length; i++) {

      //帶入股票代號查詢股票現價
      var nowprice = getNowPrice(aryData[i][0]);

      if (nowprice > 0) {

        //將股票現價寫入第 i+1 列, 第 9 欄 (I欄)
        sheet.getRange(i+1,9).setValue(nowprice);

      }

    }

    //更新資料時間
    var now = Utilities.formatDate(new Date(), "GMT+8", "yyyy-MM-dd HH:mm");
    sheet.getRange("O1").setValue("資料時間: "+now);

  }

}

function checkIfNeedToRun(strDataTime) {

  //取得今天日期
  var date = Utilities.formatDate(new Date(), "GMT+8", "yyyy-MM-dd");

  //取得現在時間
  var time = Utilities.formatDate(new Date(), "GMT+8", "HH:mm")

  if (strDataTime > "") {

    //將傳入的資料時間轉為陣列方便比對
    aryDataTime = strDataTime.split(" ");

  } else {

    //沒有資料時間則強制更新資料
    return true;

  }

  if (time >= "09:00" && time <= "13:40") {

    //現為交易時間
    return true;

  } else if (aryDataTime[1] != date) {

    //資料時間非當日
    return true;

  } else if (aryDataTime[2] < "13:40" && time > "13:40") {

    //資料時間小於 13:40 且現時已過收盤時間
    return true;

  }

  //以上條件均不符合: 不更新資料以節省資源
  return false;

}

function getNowPrice(stockid) {

  try {

    //取得今天日期
    var today = Utilities.formatDate(new Date(), "GMT+8", "yyyyMMdd");

    //向證交所取得資料
    var response = UrlFetchApp.fetch("http://mis.twse.com.tw/stock/api/getStockInfo.jsp?ex_ch=tse_"+stockid+".tw_"+today+"&json=1&delay=0&_="+Date.now());

    //處理回傳的 JSON 資料
    var jsonData = JSON.parse(response);

    //將 JSON 裡的 msgArray 內容轉成字串
    var strMessage = JSON.stringify(jsonData.msgArray);

    //以逗號為區隔, 將字串轉成陣列
    var aryMessage = strMessage.split(",");

    //找出陣列中含有 "z": 內容的資料
    for (i=aryMessage.length-1; i>=0; i--) {

      if (aryMessage[i].indexOf('"z":') > -1) {

        //以雙引號為區隔, 將字串轉成陣列
        var aryNowPrice=aryMessage[i].split('"');

        //回傳陣列第四個欄位值
        return aryNowPrice[3];

      }

    }

  } catch (error) {

    //若以上過程發生錯誤則回傳 0
    return 0;

  }

}

設定 Trigger: 點擊 [資源] → [現有專案的啟動程序] → [尚未建立觸發程序,按一下這裡來新增觸發程序。]

執行: myFunction
活動: 來自試算表開啟時

最後按 [儲存] ( )

日後開啟此 Google 資料表時將自動更新股價資料.

若不喜歡以上 Syntax Highlight 色調, 另有 Google Doc + Code Pretty 版本


 
Ref:



:,