[Side Project] Google Apps Script 實作 Google Sheet 抽股票的篩選工具

有抽過股票的人應該都知道 HiStock嗨投資有一個公開申購/股票抽籤日程表的網頁:


不過我們自己應該都會去有一些規則去篩選,例如最簡單的篩選規則我們可以這樣訂:

  • 承銷張數 >= 1000 (越多張中籤率越高)
  • 獲利 >= 5000 (獲利太少我幹嘛去抽?)
  • 報酬率(%) >= 10 (報酬率太低怕可能等抽到股價已經跌破承銷價)
  • 不要含有 "KY" 的股票

在 Google Sheets 試算表匯入網頁資料

我們可以打開一個空白的試算表,在最左上角的一格輸入:


=IMPORTHTML("https://histock.tw/stock/public.aspx", "table")

這樣表單就會大概一小時更新一次把上面網頁的資料匯入到工作表中:


條件式格式設定好難用

如何把我們想要篩選的列給標示出來? 我們可以用條件式格式設定 (Conditional formatting)。

為了套用顏色到每一列,我們只能先選全部範圍,再用公式的方式:


=AND($F1>=1000, $I1>=5000, $J1>=10)

可是光是套用前三條規則我們立刻就發現公式變得很長又不好讀:


條件式格式設定的缺點

條件式格式設定這麼難用,我盡量會避免的原因是:

  • 剪下、複製、貼上一些資料後,套用範圍經常會亂掉,會這邊缺一個洞、那邊缺一個洞
  • 要經常更改公式會變得很麻煩

在 Excel 也會碰到同樣的問題。第一個剪下貼上的問題可以透過一些小技巧避免,第二個問題基本上無解。

用 Google Apps Script 寫小工具: Smart 篩選

之前就有用 Google Apps Script 幫不會用公式的朋友寫一些好用的小工具的經驗,所以我就在想,我能不能做出一個比條件式格式設定更好用的工具?

於是我就花了一些時間用 Google Apps Script, jQuery, DataTables, Bootstrap 5 加上比較新的 ES6 來練習寫一個工具 Smart 篩選:


安裝方法我就放在 GitHub 不在這邊贅述了。

只要是 Table 格式的資料都可以用,我這邊只是用抽股票來當範例。

使用方式

把 GitHub 中的檔案都在 Apps Script 設置完後,重新整理 Google Sheets 應該就會看到選單多一個 "Smart 篩選":


點 "設定" 後右邊會先讀取目前工作表中最上面一列的欄位有哪些,之後就會看到漂亮的 Bootstrap 5 側欄:


如果我們想要讓符合條件的列用綠色標示,我們可以在 "篩選器(包含)" 下方點 "新增" 加入一個條件,"欄位"、"運算子"、"數值"都可以快點兩下來編輯,或是你先選完格子後再按上面的 "編輯" 也可以。之後就會看到我們可以對工作表的其中一個欄位來做篩選:


新增完很多條件後點 "更新" 後側欄才會真的把 client 端的資料傳給 Apps Script server 端去請他更新:


更新完後不只右下角會跳出一個吐司訊息,你應該也會注意到工作表的背景顏色有變化:


背景顏色也可以換成其他顏色,你可以點一下背景顏色後面那個小色塊來去做選擇。

接著我們同樣在 "篩選器(排除)" 那邊加入兩個條件後更新:


篩選規則

目前的 "篩選器(包含)" 裡的所有條件必須要全部符合才會讓那列資料用綠色背景顏色顯示,"篩選器(排除)" 則是任何一個條件符合就會用紅色背景顏色顯示。

如果同一列資料同時被包含又被排除的話,目前的設計是會當成是被排除的,也會被算進 "衝突書量" 的統計數字裡。

小技巧: 自己創篩選的數值

如果我們要篩選的數值比較複雜,甚至不在原始資料怎麼辦?

那我們就可以先用一些公式自己新增一欄 (column),再用 Smart 篩選來對這個新增的欄位做篩選。

例如範例的資料是從政府資料開放平台的 "盤後資訊 > 個股日成交資訊" 來的,但他並沒有漲跌幅程度的欄位,我們就可以先創一欄用以下的公式來推估當天的漲跌程度 (通常是介於 -10% - 10%):


=IF(ISBLANK($E2), 0, $I2/$E2)

接著打開 Smart篩選工具來去篩選 "漲跌幅度" 的欄位,例如我們想要用很簡單但很爛的方式判斷是不是飆股,我們說一天大於 5% 就是的話,出來的結果會長這樣:


雖然它顯示 6.73% 但那只是因為我把那欄的顯示格式變成百分比(%),實際他格子的數字是 0.0673,所以在 Smart篩選的數值我們是打 "0.05" 而不是 "5"。

寫這個 Project 學到的經驗

一開始用了一大堆 functions 來做,可是很快的整個程式架構就變得非常亂,況且篩選器有兩個,很明顯就可以創一個 class 兩邊一起 reuse。所以後來就借用了 Qt 的程式架構用類似 MVC 的方式去讓一個 XXXController 負責一塊 GUI 的部分。

我不會想用一些像是 Angular 或 React 的架構來寫是因為我還是想讓這個 project 的程式碼盡量簡單,希望初學者一看程式碼都可以很好找到要改的地方,我也盡量寫的讓大家一目了然知道我在做什麼,所以幾乎沒什麼 comments。

我覺得用 Google Apps Script 的地方在於做 client 這端的 debugging 還是不太好做,有時候不小心犯了一個 syntax error 但是看 console 卻沒有任何 stack trace 的資訊可以看。這和 server 端有 bug 其實可以寫一個 function 在 Apps Script 網頁來跑 Debug 是不太一樣的。這時候還是要靠額外的工具像是 Visual Studio Code 把程式碼貼過去用 ESLint 幫忙看一下哪邊可能有問題。本地端寫完一陣子測試沒問題最好就用 git 留個紀錄也會是個好習慣。只不過這次一開始都是完全在 Chrome 上面寫程式,好險中途沒發生什麼問題,下次我應該還是用 VSCode 當作主要編輯環境比較好。


留言

  1. 是不是壞掉了
    google試算表好像抓不到網頁資料

    回覆刪除
    回覆
    1. 我自己的經驗是 IMPORTHTML 會因為網頁不穩定有時候會抓不到資料,這種時候只能等一陣子再重試,或是把網址稍微換一下不影響結果,例如 https://histock.tw/stock/public.aspx 改成 https://histock.tw/stock/public.aspx?abc=123

      刪除

發佈留言

此網誌的熱門文章

[試算表] 追蹤台股 Google Spreadsheet (未實現損益/已實現損益)

[Side Project] 互動式教學神經網路反向傳播 Interactive Computational Graph

[插件] 在 Chrome 網頁做區分大小寫的搜尋