【Python實戰篇】用Flask製作港股通北水追蹤器

【Python實戰篇】用Flask製作港股通北水追蹤器
photo credit: REUTERS/Bobby Yip/達志影像

我們想讓你知道的是

筆者撰寫了一個數據擷取程式,可以一次過到港交所網頁自行下載指定時期北水買賣港股的數據。

港股通開通近4年,現時有逾五百多隻股份可以讓北水買賣,而港交所網頁每日均列出北水在每隻股份的持股量,但要分析個別股份的持股變化及走勢,卻要逐日把數據下載,費時失事,於是筆者撰寫了一個數據擷取程式,可以一次過到網頁自行下載指定時期的數據,轉化成企理的數據庫。然後再用flask撰寫一個數據展示程式,並以互動網頁形式顯示,讀者可到這裡輸入港股通的股份代號,程式便會輸出今年至今每日的北水持股量,每日增/減持變化圖,以及一個每日持股股數的對照表。讀者可以由此得知北水對該個股股價走勢的影響,以及看好或看淡該股。

由數據可見,北水於5月頭便開始減持騰訊(0700),直到8月底才沽壓稍歛。至於匯豐(0005),則自年頭一輪追入後,近期才再見北水捧場,但聲勢遠不及年頭強大。一些北水持重貨的股份,如新華製藥(0719),雖然股價受政策影響大幅回落,但北水仍然密密吸納,未有洩氣情況。種種走勢,用以下的程式便可一目了然。

GIT8

Python成為近年最受歡迎的程式語言,除了易學易上手外,還因為有龐大的程式庫支援,令程式員有很多捷徑可以走。不過,之前示範的程式,都需要讀者自行下載代碼在Python的編繹器內運行,未能即時展示成果。因此今次便嘗試以Python的flask應用框架,製作一個可在網上直接執行的港股通北水追蹤器,令沒有程式經驗的讀者也能看到實際應用。

讀取數據的程式,主要用了我過去常用的Selenium及BeautifulSoup框架,模擬人手逐頁下載數據,並將其組合成一個資料庫供之後使用。相比人手逐頁copy & paste,程式可以三數分鐘便下載過百日的數據,而且做了基本整理,正是自動化的好處。不過,實際處理上來,仍有一些複雜的地方,如公司改名,便會出現一個股票編號、兩個公司名稱的情況,又如公司供股,也有可能會出現臨時股票編號,而原來的股票編號所擷取的數據便出現斷層。現時程式只處理首一個情況,未能處理第二個情況(筆者太懶),惟相信後者佔整體數據只是少數,有興趣的讀者不妨完善之。程式northwater.py已放於文末,只是短短數十行程式。

筆者利用這程式,下載了今年至今的所有股份持股量數據,之後便要用flask來撰寫一個可讓網頁讀到及讓用戶互動的程式。這方面準備工夫較多,先下載flask框架,再設定一個python的虛擬環境(virtual environment),然後把程式需要用到的框架都寫到一個requirements.txt的文字檔案內,這是方便之後雲端服務了解程式的需要,不用每次均下載一大堆無用的框架,浪費資源。這些設定都是三幾行指令碼的事情,讀者可到flask的官方網頁了解。

前期準備功夫完成後,便可以撰寫程式,輸入flask框架及相關數據庫,其主要程序結構如下:

app = Flask(__name__)

@app.route("/", methods=['POST', 'GET'])

def submit_new_profile():

if request.method == 'POST':

.

.

return render_template(...)

elif request.method == 'GET':

.

.

return render_template(...)

首行是指定動作,第二行則是當在首頁出現存取表格資料時啟動submit_new_profile程序,若是用戶輸入資料,則request.method是'POST',按照用戶輸入的股票編號抽取數據庫中的時序數據,然後再製作相關的圖形,並更新index.html檔案。

除了以上幾行程式外,其餘與Python一般的程式無異,詳細程式看文末的main.py列表。

那麼index.html又有可不同呢?其實只是加入了一些雙重大括號的變數如{{name}}等,這些變數是與main.py作溝通用,並可以被main.py來動態更新的。如此一來,main.py便可以與網民互動,就算是程式中的圖表,在html檔中,亦只是一個簡單的{{model_plot}}便搞定。可以說html檔成為一道道填充題,內容交由Python處理。

git1

各樣元素齊備後,便可以在flask模擬的一個簡單本地伺服器上測試,確定程式無誤,便可以選擇一個雲端服務商把程式上線(google cloud, 亞馬遜的AWS,或微軟的Azure均可),筆者則選擇免費的Pythonanywhere ,先登記一個帳戶,然後開設一個新的web app,再把程式上載,包括requirements.txt, main.py, index.html(這檔案一般會放在templates的子目錄下),以及相關的數據庫、圖片及字型庫。大功告成?

別想得太美了,整個過程,最令人沮喪的,並非要學習試用flask框架,而是除蟲工作,以為在本地伺服器環境下運作正常的,到雲端就不知為何無法再運作了,看錯誤訊息永遠摸不著頭腦,左查右查之下,才發現Pythonanywhere要求載入檔案必須輸入完整的檔案路徑,否則會發出檔案不存在的警告。

另一個痛點,是廣受歡迎的繪圖框架matplotlib並不支援中文,若要顯示中文,必須指定一個中文字庫,方能正常顯示。具體作法坊間有很多,但不是招招都管用,這又成為一個實驗試錯的過程,筆者現時用的是google開發的思源宋體。

雖然今次頗多挑戰,但因為flask可以將完成品直接送到網民面前,讓不懂Python的人也能直接使用,而且日後還會多多使用,倒也不算白費功夫。事實上,用flask來撰寫web app,令Python應用可以直接與互聯網語言html配搭,加上雲端服務,便可以直接執行,連伺服器設定等繁瑣工作都可以慳返。昔日寫web application可能要學php, mysql等後台語言,但現在都可以由Python一手包辦,這正是Python的強大之處。

GIT2
GIT3
GIT4