【祿】邁向財務「自由」之路 II — 育成收發 Telegram 的智能秘書(上篇)

筆者的智能秘書已從只懂發出電郵,進化到懂得接收及發出 Telegram 短訊了 :D

筆者去年發表 Step-by-step 開發 Google Sheet 智能秘書的教學文章,利用 ImportXML 和簡單兩句發送電郵的程序,自動定時提示六合彩下期獎金,幸獲不少讀者的好評。

然而 Google Sheets + Email 這個組合也有不少短處和限制,也許嘗試過一起動手做的讀者也曾感受一二:
  • ImportXML 函數擱取資訊的表現不很穩定,對某些網站的標的偶爾會傳回 #N/A
  • 基於試算表格式的限制,只能擱取資訊的原型,如要進一步處理資訊會頗為麻煩,例如參考筆者回覆讀者 Nelia 的提問,在擱取牛記匯率時需要將幾幅圖片蘊含的數字以及小數點併湊在一起,要在 Google Sheets 處理便很費時失事
  • 資訊的長度不一(也可能是動態),例如不同股票的派息紀錄,長度和所載資訊也不一,很難用統一的試算表格式處理
  • Google Script 每日有頗低的運算資源上限,筆者曾嘗試開發股價數據資料庫,但每 15 分鐘處理一隻股票也爆錶
誠如筆者在半桶水爸爸網誌留言,程式碼是現代語言,編程是現代人不能不認識的技巧,所以筆者把心一橫,將智能秘書的核心技術由 Google Sheets + Script 改寫為 Python 並放上雲端運算,同時賦予秘書收發 Telegram 短訊的能力,一次過解決以上問題。

這回讓筆者以牛記匯率為例,實戰如何用幾句簡單的程式碼擱取網路資訊,並以自己喜歡的方式呈現出來。上篇主要集中討論擱取資訊的技巧,而下篇則集中討論資訊的展現、與 Telegram 的聯繫,以及如何將程序放上雲端運算。

跟去年文章一樣,擱取的對象只是示例,筆者旨在刺激讀者思考,一理通百理明。另外,請注意網絡資訊的版權屬於相關資訊提供者,本篇及下篇文章只作教學及示範用途。


上篇:利用 Python 及其程序包 Beautiful Soup 輕鬆取得並整理匯率資訊


1. 準備開發環境

首先需要準備的是 Python 的開發環境。現在的開發者有福了,因為 Google 最近支援雲端 Python Notebook,也 Pre-install 了一系列常用的程序包(包括下文提及的 requests 和 BeautifulSoup),甚麼安裝也不用做已經可以著手開發自己的程序。Google 用戶只需到 Co-laboratory (colab.research.google.com),然後新增一個 Python 2 Notebook 便可。稍後開發完成,只需把整個程序碼檔案下載(「File」->「Download .py」)便行,方便得不得了。

如果希望在自己的電腦上進行開發,Mac 的用家會比較方便,因為 MacOS 已內置 Python 2.7,直接在 Terminal 輸入 Python 便能進入環境。Windows 的用家也許需要 Google 一下如何安裝 Python 2.7,反正網路上有海量資源,就當成是第一個練習吧!另外,我們會用到兩個程序包(Package),分別是 requests 和 BeautifulSoup(留意在 Python 中,大小寫是有分別的)。安裝 Python 後,我們可以在 Mac Terminal / Windows Command Prompt (往後簡單以 Terminal 代表)用 pip 命令安裝這兩個程序包(需要網路連線): 

  $ pip install requests
  $ pip install beautifulsoup4 

留意 $ 號並不是輸入,而是 Terminal 自動生成的提示碼。至於關於這兩個程序包的詳細資訊,可以參考: 

進入 Python 開發環境(在 Google Co-laboratory 新增 Python 2 Notebook,或者在 Terminal 輸入 $ python,此時提示碼變成 >>> 代表進入成功,否則安裝可能出了問題),輸入以下的程序碼以載入兩個剛下載了的程序包。 

  >>> import requests 
  >>> from bs4 import BeautifulSoup 

留意在 Google Colaboratory 需要按 Shift + Enter 去執行程式碼。 

如果沒有輸出(Terminal 的話,提示碼維持 >>>),代表成功安裝,可以進入下一個步驟。

往後的討論主要假設以 Google Colaboratory 作為開發環境,因為相信有能力操作 Terminal 的讀者應該有能力找到相應的處理。 





2. 探索牛記匯率網頁原始碼 

這一個步驟所用到的技巧,跟系列上一篇探索馬會六合彩網頁的技巧類似。 

讓我們先在瀏覽器探索一下。打開牛記發佈匯率的網頁(http://www.nkcl.com.hk/change-ch.php),利用 Inspect Element 並從原始碼檔了解匯率的排列方式,不難發現其頁面的結構相對簡單: 
  • 所有的匯率資訊都放在頁面上第一個 <table> 裏面
  • <table>的首兩行(<tr>)是標題,並沒有匯率資訊的存在
  • 從第三個 <tr> 開始,每行有四格( <td>)。第一格是國旗和貨幣全名,第二格是貨幣國際通用代碼,第三格是買入價,最後一格是賣出價。
  • 買入價和賣出價以圖片而非文字表示。圖片的名稱(即 <img src="xxx" /> 的 xxx)與其標示數字相符,例如 1.png 代表數字「1」。小數點的圖片名稱則是 vir.png。
  • 我們希望取得的是貨幣代碼、買入價和賣出價,當中後兩者以數字而非圖片表示,並以有條理的方式(例如列表)儲存好。
有了以上對目標擱取資料的認識,已經足夠完成任務了。接下來,只剩下將以上各點編寫成程序了!




3. 將對標的物的描述換成程式碼 

3a. 下載目標網頁並建立結構方便資訊擱取 

回到 Python 開發頁面。第一步是讓程序「瀏覽」即下載目標網頁。先定義我們的目標網頁網址:

  url = "http://www.nkcl.com.hk/change-ch.php" 


按 Shift + Enter (下文略),此時應該沒有輸出。

利用 requests 程序包,將網頁內容從互聯網下載並讀進 r 物件內(r 的名稱可以自定義,另外這一步很明顯需要網絡連線):

  r = requests.get(url).content

此時如果我們檢視 r 的內容(可以用 print r),就會發現 r 只是目標網頁的原始純文字檔;此時對於 Python 來說,文字檔只是一堆沒有意義的符號的集合。




要為 r 賦予意義,即要讓 Python 懂得閱讀這純文字檔的結構,例如讓它知道哪一個 <table> 裏面有哪一些 <tr>,<tr> 裏面又有 <td> 這些從屬關係,而每一個 tag 各自有其標示的屬性,就是簡單而強大的工具包 BeautifulSoup 的工作了。只消以下一句簡單程式碼,即能為 r 賦予意義,回傳的是經過整理、蘊含所有屬性和從屬關係的 BeautifulSoup 物件「Soup」:

  Soup = BeautifulSoup(r, "html.parser")

此時如果讀者用 print Soup 的話,見到的也只是同一個原始碼檔;但請放心,只要沒有 Error 跑出來的話,Python 已經明白了整個 HTML 檔的結構了!有了這個經整理的 Soup ,我們就可以就著對所要求標的物的認識,輕鬆從中尋找並擱取所需資訊。

(至此可能對沒有編程經驗的讀者來說是有點抽象,但只要繼續閱讀下去相信讀者必定能找到端倪,加油!)



3b. 鎖定網頁的資訊目標

就着第 2 節擱取要求的第一點「所有的匯率資訊都放在頁面上第一個 <table> 裏面」,我們要尋找的是 Soup 內第一個 <table> 物件。要取得第一個物件,方法是利用 find 方法:

  TargetTable = Soup.find("table")

所回傳的 TargetTable 其實是一個較小的 BeautifulSoup 物件,內含網頁中第一個 <table> 至 </table> 內所有的屬性和子物件。用一下 print TargetTable 看看,應該就能讓讀者安心了。由於我們需要的匯率資訊都在這個 <table> 內,有了 TargetTable 便能方便收窄其後程式碼的搜索範圍。 





就著要求第二點「<table> 的首兩行(<tr>)是標題,並沒有匯率資訊的存在」,我們要尋找 TargetTable 內所有 <tr> 物件,並去除首兩行。

要取得所有物件,方法是利用 find_all 方法:

  AllRows = TargetTable.find_all("tr")

所回傳的 AllRows 是一個 Python 的列表(List)物件,這個 List 的每一個元素(Elememt)各自是一個 BeautifulSoup 物件,每一個 BeautifulSoup 物件對應在 TargetTable 內找到的一個 <tr>...</tr>。即在概念上,AllRows = [ Soup_tr1, Soup_tr2, ..., Soup_trN ]。

至於除去首兩行,即在 Python List 中除去首兩個 Elements,則是輕而易舉的事:

  TargetRows = AllRows[2:]

留意上述數句的程式碼其實可以簡單一行輕鬆完成: 


  TargetRows = Soup.find("table").find_all("tr")[2:]

這是由於 find 方法接受一個 BeautifulSoup 物件後,回傳的又是另一個BeautifulSoup 物件。這種連鎖寫法,簡單方便直接之餘,又能方便人類閱讀(很容易就能理解為「TargetRows 就是在網頁 Soup 內找第一個 <table>,然後在內找所有 <tr>,再回傳除首兩項外所有的 <tr> 項目」),這就是 Python 之美。



3c. 建立「字典」儲存匯率資訊


接下來我們就可以從每一個 <tr> 行(即 TargetRows 裏面每一個 Element),擱取需要的貨幣代碼、買入價和賣出價。但在討論下去之前,我們先要考慮一下在擱取得實際資料後,我們打算如何有系統、有條理地儲存起來,方便發送 Telegram 短訊的部分使用。

我們的目的,是建立一個「字典」,可以讓我們利用外幣的代號,查詢其買入和賣出價。如果這個字典叫做 FXDatabase,我們希望它讀畢網頁的資訊後,效果如下:

  print FXDatabase['GBP']['Buy']
  10.01

  print FXDatabase['GBP']['Sell']
  10.06

  print FXDatabase['CHF']['Buy']
  7.84

  print FXDatabase['CHF']['Sell']
  7.96

在 Python 裏的確有一種叫做「字典」(Dictionary)的物件,能不費吹灰之力就能做到上述效果。如果我們一早知道英鎊和瑞士法郎的匯價,以上的字典可以如此定義:

  FXDatabase = {
    'GBP' : {'Buy' : 10.01 , 'Sell' : 10.06 },
    'CHF' : {'Buy' : 7.84 , 'Sell' : 7.96 }
    }


留意在 Python 中,字典是以花括號 { } 定義的;另嚴格來說,FXDictionary 是「字典的字典」(留意兩層花括號結構)。

但現在的問題是,我們未讓程式「閱讀」網頁前,並不知道每一種外幣的匯價,甚至連有甚麼外幣提供也不知道(為增加程式的可用性,請盡可能不要將外幣列表手動抄下來然後手動的對號入座,試想像牛記可以隨時更改其可供兌換的貨幣種類)。所以,接下來我們得讓程式從每一個 <tr> 行擱取所需資訊,並續一寫進我們的字典。

要這樣做,我們得先建立一部「空字典」:

  FXDatabase = {}

然後就可以開始命令程式從每一個 <tr> 行進行閱讀並寫進字典裏。要指令程式將 TargetRows 的每個 Element 執行一遍,先要定義一個 for 迴圈:

  for Row in TargetRows:

此時請不要按 Shift + Enter,改用 Enter 直至整個 for 迴圈編寫完畢。同時請留意,Python 是用縮排(Indentation)去區隔不同程序碼的集合的,所以由下一行起,所輸入的在 for 迴圈內的程序碼,請謹記在前面加相同數目的空格。

好了,第一個我們希望取得的資訊是「貨幣國際通用代碼」,存在每一行的第二個 <td> 裏。由於 TargetRows 是一堆 BeautifulSoup 物件的表列,所以 Row 就是一個 BeautifulSoup 物件,可以用我們之前使用過的方法處理。聰明的讀者應該已經想到,可以利用 find_all 函數將所有 <td> 找出來:

  TDs = Row.find_all("td")

然後告訴 Python 需要 TDs 的第二個 Element (注意第一個 Element 的 Index 為 0、第二個 Element 的 Index 為 1,如類推):

  TDCurrency = TDs[1]

此時,TDCurrency 所包含的就是我們目標的那一個 <td> 格的 BeautifulSoup 物件,所以當然也包含了定義該 TD 相關屬性和其他子物件。例如,在英鎊匯價的那一行,我們得到的將會是(部分從略):

  TDCurrency = '<td style="..." width="10%">GBP</td>'

我們需要的,就只是 TDCurrency 裏顯示出來的文字部分,即上面的「GBP」三個字。從 BeautifulSoup 物件取得顯示文字的方法是 text。筆者再後加一個 .encode(‘utf-8’),因為網頁是用 UTF-8 編碼寫成,如此便能讓 Python 對擱取的文字進行相應的解碼:

  Currency = TDCurrency.text.encode('utf-8')

當然,以上的幾句程序可以簡潔的用一行表達:

  Currency = Row.find_all("td")[1].text.encode('utf-8')

至此貨幣代碼擱取完成。之後便輪到買入和賣出價,分別是 <tr> 的第三和第四個 <td>:

  TDBuy = Row.find_all("td")[2]
  TDSell = Row.find_all("td")[3]

由於牛記匯率很聰明地利用圖片而非文字表示匯率,所以我們不可以直接用 text 方法取得匯率資訊。我們得額外做一些功夫,將 <td>...</td> 內的資訊換成是匯率數字。為了不打亂我們的邏輯思考,現在讓我們先假設有一個叫做「GetFX」的自定義的函數,能做出這樣的轉換:

  Buy = GetFX(TDBuy)
  Sell = GetFX(TDSell)

至此我們已經取得所需要的三項資訊,即「貨幣代碼」Currency、「買入價」Buy 和「賣出價」Sell,可以將資料寫入預先建立的字典:

  FXDatabase[Currency] = { 'Buy' : Buy, 'Sell' : Sell }

好了, for 迴圈要執行的動作已編寫完成。但請先不要按 Shift + Enter 執行,因為不要忘記我們其中一步假設了「GetFX」自定義函數的存在,強行執行只會招致程式錯誤:



(在 Terminal 開發的朋友,對不起了 :P)




3d. 建立函數將圖片換成文字再換成數字匯率

現在讓我們先離開 for 迴圈的編寫,在 Google Colaboratory 建立一個新的 Code Cell 去定義 GetFX 函數。前文說過, GetFX 的作用,是將擱取到的 <td>...</td> 內的資訊換成是匯率數字。例如,行文之日,英鎊買入價為 10.01,從上面的程序我們將會讀到(部份從略):

  TDBuy = '<td align="center" style=...>
           <img src="images/1.png"/>
           <img src="images/0.png"/>
           <img src="images/vir.png"/>
           <img src="images/0.png"/>
           <img src="images/1.png"/></td>'

而現在我們就要編寫一個小函數,將 TDBuy 中間的 <img> 煎皮拆骨,使得:

  print GetFX(TDBuy)
  10.01

這回請容許筆者先展示完成的函數,再逐行解釋:

  def GetFX(TD):
      FX = ""
      for ImgTag in TD.find_all('img'):
          Src = ImgTag['src']
          ImgName = Src[(Src.find("/")+1):Src.find(".png")]
          Digit = "." if ImgName == "vir" else ImgName
          FX = FX + Digit
      return float(FX)

  • def GetFX(TD):
    在這行我們定義一個名為 GetFX 的函數,接受一個叫做 TD 的 BeautifulSoup 物件作為參數。TD 就是我們在上面 for 迴圈中傳入蘊含匯率圖片的 <td>...</td> BeautifulSoup 物件。
  • FX = ""
    由於我們要將每一張圖片逐一幻化成文字(每一張圖片將得到一個數字符或小數點),繼而合併再變成匯率數字,而我們不知道 <td> 中圖片的數量,所以我們又得利用 for 迴圈,而在迴圈之前我們先定義一個空字串去裝著逐一得到的文字。
  • for ImgTag in TD.find_all('img'):
    建立 for 迴圈,讓程序將 <td> 內找到的所有 <img> 也逐一執行一次以下的程式碼,就是從 <img> 中抽取所需的字符。
  • Src = ImgTag['src']
    字符存在 <img> 的檔案名稱內,所以我們感興趣的是 <img> 的 src 屬性。Src 執行的結果就是字串 "images/X.png",而 "X就是我們希望得到的字符。
  • ImgName = Src[(Src.find("/")+1):Src.find(".png")]
    要從 "images/X.png" 抽出 "X",方法就是找出字符 "/" 和 ".png" 在 Src 的位置,然後在 Src 本身取得相應位置的字符。這方法跟 Excel 中的 MID() 和 FIND() 混合使用的原理是一樣的。
  • Digit = "." if ImgName == "vir" else ImgName
    這步很容易明白,如果讀到的圖片檔名是 "vir",代表它是小數點,應以 "." 取代之;否則所需字符就是圖片檔名本身。
  • FX = FX + Digit
    將新得到的字符置於代表整個匯率的 FX 最後方,然後重新跑一次 for 迴圈去閱讀下一個字符,直至 <td> 內所有 <img> 完成為止。
  • return float(FX)
    最後,將得到的整個匯率 FX(字串)利用 float 函數轉為數字,並作為整個 GetFX 函數的結果回傳(return)。

現在我們只需先執行這個函數的 Code Cell 將其定義,然後再返回上面的 for 迴圈再執行一次,Error 就會消失。雖然 for 迴圈沒有回傳,但我們的匯率字典已經在瞬間編寫完成了!

如果不相信的話,可以試著執行以下的指令:

  print FXDatabase
  print FXDatabase['CHF']
  print FXDatabase['GBP']['Sell']


雖然開發過程好像很漫長,但回首一看,我們只是用了短短 22 行的程式碼,已經取得了所需的資訊,並有系統地儲存好。 

以下列出本篇訖今整個程序碼,Google Colaboratory 的使用者可以下載 .py 文檔再加以修飾得到;使用 Terminal 的開發者可以另開新純文字檔,將我們的 Python 程序碼儲存成以下 Python Script 檔案:

  ## NgauKeeFX.py

  import requests
  from bs4 import BeautifulSoup

  def GetFX(TD):
      FX = ""
      for ImgTag in TD.find_all('img'):
          Src = ImgTag['src']
          ImgName = Src[(Src.find("/")+1):Src.find(".png")]
          Digit = "." if ImgName == "vir" else ImgName
          FX = FX + Digit
      return float(FX)

  url = "http://www.nkcl.com.hk/change-ch.php"
  r = requests.get(url).content
  Soup = BeautifulSoup(r, "html.parser")
  TargetRows = Soup.find("table").find_all("tr")[2:]

  FXDatabase = {}

  for Row in TargetRows:
      Currency = Row.find_all("td")[1].text.encode('utf-8')
      TDBuy = Row.find_all("td")[2]
      TDSell = Row.find_all("td")[3]
      Buy = GetFX(TDBuy)
      Sell = GetFX(TDSell)
      FXDatabase[Currency] = { 'Buy' : Buy, 'Sell' : Sell }


至此,上篇要討論的,從網際網路擱取資訊的技巧已完成討論。下篇我們會將擱取到的匯率資訊,以喜歡的方式在 Telegram 短訊呈現。敬請期待!



【祿】政府年金之我見

這兩天多位 Blogger 都在討論政府年金,讓筆者也湊湊熱鬧。政府年金的產品特色、償付條件、各方評價相信大家已經聽得太多,容許筆者不再贅述,直入正題。

(圖片來源:香港 01)


首先筆者必須指出,年金不是純投資的產品。說得白一點,年金其實是在生的年金持有人「發死人財」的遊戲。年金持有人所得到的「年金回報」,背後其實是年金公司資產管理者從資產所賺取的「投資回報」,加上「死亡回報」製作出來的:

個人「年金回報」 = 整體「投資回報」+ 「死亡回報」

容許筆者以例子說明。為求簡化例子,本例假設投資回報為零。

假設一群 100 名 70 歲的長者成立了一個互助社,每人貢獻 $300 萬出來成立「自製年金信託」,即成立日基金總額為 $3 億。從即日起,每年之初,信託管理人跟據這班長者的指示,從信託基金取出 $1,000萬,並平分給每年年初所有在生的長者。由於本例假設投資回報為零,基金一共可以取出款項 30次,直至這群老人家 100 歲。

  • 第 1 年,100 名老人家均健在,每人分得 $10萬。
  • 第 2 年,有 1 位老人家在第 1 年內不幸過身了。餘下在生人數只有 99 位,每人分到 $101,010。
  • 第 3 年,有另外兩位老人家不在,餘下在生人數只有 97 位,每人分到 $103,092。
  • ...
  • 第 30 年,只有一名老人家仍然生還,他該年獨吞 $1,000萬。


可以看見,即使支持「信託基金」背後的資產回報為零,每一名在生的老人家所得到的「年金」收入仍然可以遞增,因為在生的人瓜分了死去的同伴最初的貢獻。這便是所謂的「死亡回報」,學名是 Survivorship Accumulation。

留意政府年金的給付是每個月定額的,並不如上述例子每年遞增,這只政府年金公司的產品定價部門將現金流搓圓按扁再排得整整齊齊,但背後產生年金回報的來源概念上是一樣的。(註:上面這個信託安排的學名叫做「唐提」Tontine,有興趣的讀者不妨研究一下。)

政府年金之所以能做到 6.3%-7%「粗略回報率」(Crude Return Rate,即男性年取 $69,600、女性年取 $63,600 除以 $100萬本金),粗算概念就是由政府保證 4% 的「投資回報」,加上每年平均有 2-3% 老友記離開而為在生的年金持有人提供「死亡回報」製造出來的。但由於投保人在投保時並不知道誰人會先行離去,所以年金投保人有機會會是第一年交保費後立即過身「蝕盡」的那位,也有機會是上例守候 30 年的「最後武士」(或「最後無事」)。



當筆者說到這裏,或者說到政府年金在過早身故或者提早贖回會有賠本機會(有些人的「賠本」可以指「比內部回報率 4% 回報為低」,縱使政府已經在死亡給付上包了 105% 底),有些朋友或者老友記就會說,「如果我早死,那豈不很蝕底?」「如果我過早死了,為甚麼後人一筆過償付死亡保障要被『懲罰』?」

要拆解這個謎思,請容許筆者將上面的例子換一換。假設那 100 名長者均有上述老友記「早死好蝕」的擔心,而大家在開盤之初都不知道自己是「賺了」還是「蝕了」那位,於是在成立「自製年金信託」之時,指示信託人在有人離世時必須返還該位長者所貢獻的金額,減去未曾獲分發的年金。結果?


  • 第 1 年,100 名老人家均健在,每人分得 $10萬。
  • 第 2 年,有 1 位老人家在第 1 年內不幸過身了。由於該老人付出了 $300萬但只曾獲發 $10萬年金,他獲得了 $290 萬的賠償。基金現在只剩下 $2億 8710萬。由於預算分 29 年,如果繼續每年攤分 $1,000萬基金到最後便入不敷支,所以管理人今年只分發 $990萬 = $28,710萬 / 29。餘下在生人數只有 99 位,所以每人分得 $10萬,不多不少。
  • 第 3 年,有另外兩位老人家不在,該兩位各得到 $280萬賠償。餘下在生人數只有 97 位,不用多說,每人也只是分到 $10萬。
  • ...
  • 第 30 年,只有一名老人家仍然生還,但基金此時只剩下 $10萬。這位仁兄 30年來不多不少取回當初貢獻出來的 $300萬。


結果就是,每一位老人家都要公平,所以人人「得個吉」!每人分不到「死亡回報」,只能理論上從基金得到「投資回報」(如有的話,上例假設為零);信託當中沒有分擔長壽風險的機制,那就每位老友記自己去投資好了,不用搞甚麼年金。很多人覺得「早死會蝕」就對年金「耍手擰頭」,因為這班人不明白年金的真締就是跟其他年金投保人賭長命「發死人財」,而「賭」就是有「賭贏」和「賭輸」的機會。如果閣下不願意冒上「賭輸」的風險,想魚(死亡給付)與熊掌(生存年金)兼得,那年金產品並不適合閣下。

所以分析年金,我們不應該單看年金的「粗略回報率」或者「內部回報率」,因為當中包含了保險保障的成份,而這回所保障的是「長壽風險」。如果單看回報高低就不買,那麼倒轉過來筆者極力推崇的定期人壽保險也一定不要買了,因為不死就一毛錢都取不到,保險公司「袋晒」;而筆者相信除了有心「呃保險」的極小眾外,應該沒有人希望能取到壽險賠償吧?



筆者認為,考慮應否購買年金,應該同時考慮回報和保障兩個部份。
  1. 年金的保障部份的確要看當事人有多擔心長命的。以同一個資產內部回報率來計,因著「死亡回報」,將本金年金化(Annuitize)所得到的每期回報(即上述的粗略回報率)定必有所提高。如果一名 65 歲男士無人又無物,健康無病痛,手頭上只有 $100萬現金,讀者如果是他,會選擇 (a) 將投資於在保證年回 4% 的收息物,年取 $40,000,還是 (b) 購買政府保證內部回報率 4% 的年金,年取 $69,600?

    當然上述選擇假設了 (1) 他只有兩項回報相同的投資可供選擇(回報的問題在下面討論)、(2) 故事主角無人又無物,沒有遺產需要留給後人的考慮、(3) 他確實擔心長壽,即某程度上他有自信「賭贏」。留意如果他明知自己多病痛、食煙飲酒三高,筆者就會勸他不要學人賭長命,就算賭都應該考慮留番個錢睇醫生。


  2. 年金的回報部份,在比較時也要留意,應該與擁有相似特性的投資物作比較。政府年金「投資」的特性是長線、流動性低但政府保證回報,因此筆者會採用跟政府長期債券去作比較,而非像某些評論員般以股票作點評。需知道 4 厘保證回報,現市況來說真的多長的政府債券 / 銀髮債也做不到。當然日後加息幅度和時間也很難說,但至少就現市況來說,4% Guaranteed IRR 簡直就是政府在派錢。

    在私人市場,筆者敢寫包單一般人壽保險公司不可能會開出這個盤。其實 10 年前金融海嘯以前,年金產品也曾經掀起過一輪熱潮,不過當時賣的是「變額年金」Variable Annuities,年金給付跟投資相連掛勾之上還有各式各樣的保證回報,甚麼 GMDB、GMAB,百花齊放,好像金融市場上的衍生工具、Accumulator 玩法一樣五花百門。這些產品在海嘯後「連影都無」,為甚麼?因為一場海嘯,令監管機構真正意識到「保證回報」是有成本的,而且在零息時代成本之鉅大高得很多人都不相信。海嘯後監管機構、會計準則紛紛修例,要求保險公司更準確反映保證回報的資本成本(Capital Cost)和準備金(Reserves)。長期 4% 保證回報,資本成本高高在天,要不是我們港府儲備雄厚,保監根本不可能批准推出。這也正說明了為甚麼政府要為年金產品設有 100 / 200 億元的額度。

    所以 4% 保證回報是高是低?見仁見智吧。

最後筆者有兩點補充評語:
  • 公共年金的設計上有個「死位」最惹人詬病,就是年金給付「追不上通脹」。筆者也認為政府日後在設計類似年金產品時可以考慮加入通脹的元素,例如年金給付能隨通脹遞增,或者以固定某個百分率增長。但大家也明白「羊毛出自羊身上」的道理,在保證回報大約不變的前提下,要日後通脹派多些,自不然現在要派少些。到時買 $100萬 而年金金額每年遞增 4%,但第一年每個月只取得 $3,000 左右,讀者又會買還是不買?要知道大眾、傳媒都在看表面回報、回本期、「有無賺蝕」的時候,政府現行的年金設計也許已經在迎合大眾口味而犧生某些真正有用的產品特色。
  • 筆者在網上見到不少評論員以 81-82 歲做香港男性平均死亡年齡,然後以此說平均男士只能做到保本(因為 65-80歲收 15 年錢後才大約收回 $100萬);這點其實有個統計謬誤。需知道 81-82 歲是香港所有男性在出生時起計的平均壽命,當中包括嬰兒時期夭折、青年壯年時意外死亡、或者上回講到在海洋公園被棺材壓死的青年。但是,買得起年金的,資格是首先要活到 65 歲,所以年金的參與者已經排除了一班「拉底整體平均壽命」的早死者(統計學上這是「條件概率」 Conditional Probability 的問題)。

    所以真正相關的平均,應該以香港 65 歲在生男士的「平均餘命」去計算。根據筆者以 2014 年香港人口生命表的計算,男性平均餘命 20 年,即活到 85 歲;女性平均餘命 24 年,即活到 89 歲。如能活到這些歲數,年金投保人的個人內部回報率,應該能與整體回報 4% 更為類近。

【壽】 筋長一寸 壽長十年 筆者晨早健康習慣大解構

所謂「一日之計在於晨」,筆者最近發的幾篇「壽」篇都是早上進行的促進健康好習慣。在早上最容易建立 Routine,因為早上是一天中最少「意外」和「誘惑」的時間。


筆者通常是全家最早起床的那一位,這個習慣候是在多年前考取專業資格的時候是建立的。筆者跟大多香港人一樣經常需要超時工作,如果將讀書的時間放在一天之末,那突然需要 OT 至凌晨的話讀書大計就泡湯了。要知道「工作是公司的,專業資格是自己的」,筆者選擇先將時間貢獻給自己,每天早上六時起床,讀兩個小時才上班,那麼當天要開多久 OT 也沒關係了,反正已經完成了自己一天的事工。

說回 Morning Routine,由於其他家人仍然在睡夢之中,筆者很少機會出現因與其他家人互動而阻礙了習慣的執行。而且在一天的開始就將時間奉獻給自己,給予自己足夠的時間做好自己的「本分」,一整天都能懷著愉快的心情去面對挑戰。誠如筆者考取專業執照的時候一樣,給自己身體健康的作業在出門口前已經完成了,所以在一天餘下時間,時間管理上輕鬆一點也沒關係。

以下是筆者一早起來到出門口的 Morning Routine,長期讀者們應該不會陌生,新朋友們也請隨便參考多多指教:



當中尚未介紹的就是本篇的主角,每早10分鐘拉筋運動了。

相信讀者也有聽過「筋長一寸,壽長十年」的說法。筆者沒有詳細考究過這句話的由來,但自我理解為拉筋能訓練關節、韌帶和肌腱,增加身體的柔軟度,讓日常生活進行不同的活動,尤其是遇到突如其來的反應時,關節部位不容易受傷。

其中一個例子,又要介紹一年多前某集《恐怖醫學》了。該集講述如果觀眾在腿部直立向前彎腰,伸直雙手但手指頭沒能碰到地面的話,年老之後患腰痛的風險會大為增加。(筆者實在十分喜歡《恐怖醫學》這個節目,利用生活化的例子配以簡單的文字和解釋,向觀眾介紹不同病症的成因和預防方法、醫學新知等等;對比起香港的醫學普及節目只有醫生在錄影廠講解,生活化的例子實在容易吸收很多。ViuTV 逢星期日晚8:30。)

節目指出,腰痛的其中一個成因,是由於大腿後面的肌肉繃緊。這塊肌肉其實在我們日常生活中甚少用到,加上平時坐姿不正確的話,會處於長期收縮的狀態,使得肌肉繃緊不能收放自如。由於該肌肉一側連繫著盤骨,肌肉繃緊會導致盤骨難以轉動,結果身體在向前彎腰時不靠轉動盤骨而改用彎曲脊椎,那肯定會腰痛吧。

上述病症,根據節目所說,只要透過拉筋訓練腿後腱,重新練習轉動盤骨,症狀就能得以舒緩。至於根據筆者自身經驗⋯⋯ 哈哈,不要以為這是容易的事!既然肌肉長期繃緊不能收放,那就是說不是你今天去訓練它它就會動的。筆者有一段時間曾經接受一對一的普拉提(Pilates)訓練,其中一段時間教練集中練習筆者的就是轉動盤骨的這一組肌肉。在做一組類似仰臥起坐的練習時,那時筆者自以為轉了,殊不知教練說「你的盤骨一動也沒動,回家要多多練習『捲蝦米』和『釣魚』!」結果經過一個多月,筆者才開始感受到「轉動盤骨」是怎麼一回事,感覺身體裏面有一個長期沒用的 Module 給 Unlock 了,是一種很神奇、很有趣的體驗。

至於為什麼筋絡可以變得「柔軟」起來,有興趣的讀者將標題這句話自行 Google 的話,可以找到很多有關「牽張反射」的文章,在此不贅。

至於筆者又是如何培養出這個習慣?又為什麼無端端找了個普拉提一對一教練?本文照片已經給了足夠提示——留意到筆者腳前的高球桿嗎?其實筆者當初拉筋是為了另一個目的,就是「筋長一寸、波遠十碼」,哈哈!高爾夫球作為「鬼佬太極」,需要很好的身體的柔軟度,才能將身體化成一條皮鞭,有效將主幹、腰部肌肉的力量傳導到肩膊、上臂、下臂、手腕、進而到高球桿和高爾夫球。那讀者現在明白,為什麼世界名列前茅的女子高球手,不是肌肉型的西方人,而是柔軟型的亞洲選手吧。

筆者為了做好一項運動(高爾夫球),進而去學習另一項運動(普拉提),想起來也覺得自己有點不可思議,哈哈!但無論目的如何,保持身體柔軟度絕對是延緩衰老、減少身體受傷的關鍵,讀者不妨嘗試每天做拉筋熱身運動。


【祿】買終身儲蓄保險 30年只儲到一個東歐旅行

近日家中一位長輩接到保險公司的函件,信中指出該位長輩一份「已供斷」的儲蓄保險「保費不足」,需要老人家注資。老人家不明所以,明明多年前已經「供斷」的保單,近十數年來都不用付錢但突然間又要追欠款,遂將函件轉交筆者看過究竟。



供不斷的回魂保單?


筆者一看,發現保單的確曾經「供斷」過;但所謂的「供斷」,並不是指保單的設計是定期供款而供款期完結,而是保險代理一種常用又頗為誤導的銷售技倆:利用積存紅利支付保費。

話說長輩所買的是分紅保單,即如果保險公司在保單上賺到利潤,這利潤會以分紅方式跟保單持有人分享。保單持有人一般可以選擇將分紅以現金方式提取,或者積存在保險公司賬戶內繼續生息(Accumulation on Dividend、AOD)。聽起來很吸引,但筆者要再三強調保險公司計算利潤、跟保單持有人拆帳分紅、以及積存生息利率釐定都對投保人幾乎沒有甚麼保障,分紅只能當是「錦上添花」。

現金分紅或 AOD 紅利還有一個用途,就是用來抵銷下期的保費。而當積存在保險公司的紅利達到一定數目,根據現行假設預測,AOD 連未來利息以及未來的分紅將足以繳付保單餘下年期的保費,不少保險代理於此時就會告訴投保人保險已「供斷」,不少保單持有人便以為節省了往後數十年保費,但事實上只是自己的左袋(AOD、利息及未來紅利)付錢給自己的右袋去交保費。

但畢竟保險分紅是非保證項目,其實說得坦白一點,分紅乃是保險公司的風險緩衝,當保險公司在虧損時(所謂「虧損」是指比保險公司自己的「預期」賺得少)就可以拿分紅保單來開刀以減低「損失」。過往數年長輩的那間保險公司經營成績一般(說得正確一點是公司的盈利自信太高),加上環球持續低息,所以比起金融海嘯前紅利的分派和 AOD 利息也扣減了不少。由於當年「供斷」的判斷是建基於當年對紅利及利息的預測,當實際分派比預期低時,就自然出現「紅利不足以繳付未來保費」的情況了。

坊間不少保險代理很喜歡用這一招去賣保險,將一張終身供款的儲蓄壽險講成是 15年、20年繳,說 15、20年後紅利就足以讓保單繼續生存,所以可以用較少保費買到更大保額。這樣做的目的,當然就是想促成生意,而終身繳款的保單佣金通常又較定期繳款的要高。未來 15、20年後紅利是否真的足夠繳款?老實說,「與他何干?」

而在購買過程中,擬投保人並不一定知道紅利可以提取用來做自己喜歡的事、擬投保人也並不一定知道 AOD 積存利息較一般銀行存款及保單本身的回報為高(所以用較高的 AOD 利息交較低回報的保費著實是浪費)、更甚者擬投保人應該也不知道其實保險有不分紅的選擇……


斷保的考慮和計算


既然確定了要重新付費,老人家便開始考慮斷保,並詢問筆者意見。筆者對於斷保的考慮又是甚麼呢?

一般而言,保險最關鍵的決定在於買的一刻。如果買的時候已經考慮周全,則一般筆者不會建議斷保。這是因為在保險的價值鏈中,都是先付銷售人員(保險代理 / 經紀 / 銀行)、再付保險公司股東、最後才輪到保單持有人。這就是為甚麼在前文儲蓄保險的例子中,如果在投保最初 6、7 年斷保,投保人是保證虧損的——畢竟保險公司得先確保自己能付米飯班主(銷售佣金),再付金主(股東)和生財工具(員工),行有餘力再付投保人,所以一般來說保單斷保(尤以保單開納初期)是嚴重破壞投保人自己價值的行為。記住,保險公司的精算定價部門都是坐定粒六來開盤的,所以買保險前如果也不能確定所買的是切合自己的實際需要,有斷保的機會,那麼不如不買。

但筆者更明白,社會上更普遍的故事更像是家中長老般,買了一張甚至一大堆沒用的儲蓄保險,多年後才醒覺知道保險應該如何買,自己從前如何上了當。像家中長者的保單,今年已屆保單第 30 多個週年,給銷售人員和股東的價值早就還清了,那現在才來斷保又如何?

(P.S. 要知道何時還清了銷售人員?很簡單,當你的保險代理人開始對你不瞅不睬,又或者不斷慫恿你斷保並重新開立一張新保單,就大概是還清佣金債的時候了。那現在你知道,從這個時候你的保單價值才真正開始建立吧!)

這個時候,筆者會祭出財務分析的常用技倆:內在回報率(IRR)分析。

是否斷保的考慮,其實就是「斷保取得現在的現金價值」,跟「繼續投保,繼續交保費,換取保障和未來更大現金價值」的二元選擇題。要知道哪一個選項的價值較高,可以將繼續投保想像成為一個投資項目——利用即時斷保之所得作為起始投資,加上未來的保費,便可得到未來更大的現金價值。根據這些現金流,我們就可以算出這個「投資項目」,也就是繼續續保的內在回報率(IRR),然後再跟投保人可得到的其他投資回報比較。

以例子說明。假設:
  • 投保人現在斷保的話可以得到保證保單價值 $95,000 連積存紅利 $5,000,共銀 $100,000。
  • 如果繼續續保,則每年保費 $3,500。
  • 根據保單周年報表,投保人 5 年後可得保證保單價值 $120,000 連積存紅利 $20,000,共銀 $140,000。

首先,即時斷保所得並不需要分開保證保單價值及積存紅利兩個部份,因為兩者均是保證能提取的。積存紅利雖然來自從前不保證的部份,但一旦紅利實現了,就成為保證的一員。

現在單考慮 5 年後保證回報的部分:
  • 5年後可得保證保單價值 $120,000,並假設未來紅利及 AOD 利息為零,即 5 年後積存紅利仍是今日的 $5,000。
  • 今日投資 -$100,000 另加保費 -$3,500(負數表示現金流出),接續 4 年每年付出保費 -$3,500,第 5 年年末可保證提取金額 +$125,000。
  • 利用 Excel IRR 函數算出內在回報率為 1.32%。如此數字,不如斷保放定存?

再考慮筆者認為最進取的回報,就是保險公司在未來 5 年能如報表所示,給付所有紅利及非保證利息(注意,如果保險公司從前真的可以完全給付報表所示的所有紅利,則本篇文章根本不存在!):
  • 5年後可得保證保單價值 $120,000,以及 5 年後報表所示積存紅利 $20,000。
  • 今日投資 -$100,000 另加保費 -$3,500(負數表示現金流出),接續 4 年每年付出保費 -$3,500,第 5 年年末可享保證金額 +$140,000。
  • 利用 Excel IRR 函數算出內在回報率為 3.78%。既然非保證,何不斷保買領展?(不過筆者應該會買川河。)

注意筆者以上的計算,乃是假設了老人家其實並不再需要儲蓄保險所帶來的死亡保障,所以保費中給付同齡同額定期壽險的相對等部份其實是白付的。如果讀者很執著,認為七老八十的長者也需要死亡保障,可以自行參考筆者上篇儲蓄保險分析之中類似的方法,將保費分拆成保障和儲蓄部份,並只用儲蓄部份計算內在回報率。


筆者向老人家展示上述簡單的計算,老人家最後決定斷保,取了十數萬的保單價值跟太太來了個東歐旅行,並節省每年三數千錢的保費。老人家概嘆, 30 年前的三千元絕對不是小數目(當年一份大快活雜扒早餐也只是 $7),要省下三數千錢供這份保險也絕非簡單;本來打算為家人買份安心的保障同時又照顧自己的退休儲蓄,結果 30 年來,南柯夢醒了,只買到一個東歐旅行。今日還在考慮買儲蓄保險的年輕一輩,前車可鑑也!

【祿】稅局撳錢續集:「雙租族」「半子」慳稅大法

Tax Optimization 一門學問果真博大精深,繼去年向稅局改正撳錢後,今年填報稅表的時候又學到兩招新招,其中一招是筆者長期在用但一直理解錯誤,原來實際比想像慳得更多;另一招則很多人誤以為適用範圍狹窄但原來實際射程頗為廣泛。現在跟讀者們分享,大家填報稅表時也可以注意一下!


雙租族慳稅法


其實不一定要是雙租族,所有租樓住的租客也可以應用這個方法,但「裸租」(指沒有持有物業但租樓住人士)此等沽空樓市行為向來不是筆者所推崇的。而且應用在雙租族這一般人看似「蝕物業稅」的行為,透過這方法更有機會還原超 100% 物業稅,即「稅局幫你付物業稅之餘還有稅務回贈」!(註:此乃誇張修辭手法,關於如何正確理解稅務用詞請諮詢專業會計師或稅務人員)

容許筆者以例子說明。假設某君月入 $6萬,希望住市區兩房單位,但以自己能力在市區只能購買約 $600萬的一房單位,或是新界兩房單位。於是他實行「雙租法」,將市區一房 / 新界兩房單位放租而租入市區兩房單位自住。放租樓收 $15,000 一個月,自住樓交租 $20,000 一個月。另假設:

  • 放租樓樓宇按揭每年利息支出 $6萬,以現在利率換算即大約每月供款 $10,000。注意若單位改為自住用途,此供樓利息開支可以申請扣稅。出租的話,只有以「個人入息課稅」法評稅才可獲扣減(但以某君的入息主要來自薪金來說這不太可能);
  • 單買自住樓和「雙租法」均需交其中一份的差餉、地租、管理費,因此分析中不考慮此等開支的差異。
  • 某君除了個人基本免稅額及 MPF 免稅額外,並沒有其他免稅額。

如果某君將市區一房 / 新界兩房單位用作自住用途,他的入息稅 (以 2017/18 稅務年度稅例估算),扣除供樓利息扣減後計算如下:

例子 1A

入息$720,000
個人免稅額($132,000)
MPF 免稅額($18,000)
自住物業按揭利息免稅額($60,000)
應評稅入息$510,000
薪俸稅($30,000 稅務寬減後)$43,200

現在某君實行「雙租法」,但沒有筆者襄助提供稅務秘笈,結果稅務狀況搞得一團糟:除了要交付物業稅之外,還喪失了供樓利息免稅額,可謂雙重打擊:

例子 1B

入息$720,000
個人免稅額($132,000)
MPF 免稅額($18,000)
應評稅入息$570,000
薪俸稅($30,000 稅務寬減後)$53,400
物業收入$180,000
20% 法定免稅額($36,000)
應評稅淨值$144,000
物業稅$21,600
薪俸稅 + 物業稅$75,000(稅款比 1A 增加 $31,800)

好,現在筆者要變魔法嚕!某君需要做的,就是在租樓以及每個稅務年度開始時,跟僱主商議好將其薪金拆成兩個部分:

原薪金 $6萬 = 薪金 $4萬 + 租金付還 $2萬

注意僱主的每月支出是不變的,但某君節省的開支可大了!根據稅例,如僱主已設立並執行適當的監管程序,則評稅主任會接納該情況為「由僱主提供居所給僱員」,將居所的「租值」,而不是將「付還租金」,計入應予評稅的入息內。

上文底部劃線的部分是關鍵。

可能讀者此刻仍然是摸不著頭腦:某君物業的租值不就是 $2萬租金,不就是等於僱主的付還租金嗎?正正不是。原來「租值」一詞在稅務條例下的定義,跟我們日常的應用是有很大差異的。在稅例中,「租值」是得自僱主和相聯法團的全部入息,減去支出及開支(但不能減個人進修開支),然後根據獲提供居所的類別按以下百分比計算:

居所類別百分比
一個住宅單位/服務式住宅10%
佔酒店、旅舍或公寓的兩間房間8%
佔酒店、旅舍或公寓的一間房間4%

換句話說:
(1) 稅例上的「租值」,是跟所租入的單位的租金完全沒有關係,只跟納稅人的薪金和單位的種類有關。
(2) 就算是表中最「高級」的一般住宅單位的租值,「租值」也只佔薪金 10%!

某君在得到僱主的書面同意並在僱傭合約上清楚將薪金分拆,某君的僱主又已設立並執行適當的監管程序,並在其僱主報稅表清楚如實交代此「租金付還」的安排後,某君便可以改用以下的方式報稅:

例子 1C

入息$480,000
僱主提供居所的租值$48,000= $480,000 x 10% (*)
個人免稅額($132,000)
MPF 免稅額($18,000)
應評稅入息$378,000
薪俸稅($30,000 稅務寬減後)$20,760
物業稅(同例子 1B)$21,600
薪俸稅 + 物業稅$42,360(稅款比 1A 還要減少 $840)

(*) $48,000 << 實際租金 $240,000 = $20,000 x 12

簡單點說,只是分拆薪金一個簡單動作,某君就打掉了 $19萬多的應課稅入息;以 17% 邊際稅率計算,節省稅款有 $32,640 之多!省回來的足夠繳付物業稅和彌補失去的供樓利息免稅額之餘,還有八百多塊錢開香檳慶祝!


這個方法唯一的缺點是需要僱主配合,但由於僱主在過程中並沒有損失,所以一般僱主亦願意奉陪;如果讀者也有興趣,不妨聯絡自己公司的人事部門了解。另外留意如果租金佔原本薪金少於 11 分之 1,這個方法反而要交更多稅款。但在租金高昂的香港,除非閣下是不睡龍床睡狗竇的打工皇帝,月薪 $10萬租樓 $9千,否則這個苛刻條件應該很難踩中⋯⋯

這招就是筆者「長期在用但一直理解錯誤」的招式。筆者公司人事部每年都會主動接受「租金付還」的申請,而筆者一直沒有深究申請文件的內容,並以為內容中的「租值 10%」是指租金的部分以邊際稅率 10% 而非 17% 計算稅收。今年突然心血來潮細看稅單,才知道過往幾年省下來的稅款要比想像中的多 :)

上文的資料來源主要來自稅務局下列網頁,讀者可以重點參考例子六:
https://www.gov.hk/tc/residents/taxes/salaries/salariestax/chargeable/residence.htm


女婿新抱慳稅法


俗語說「女婿如半子」,但若這半個兒子孝順的不僅是自己的爸爸媽媽,還有老婆大人的父母,則稅局不只將這位孝婿當半子看待,還賦予等同親兒子供養父母同等的免稅額待遇!情況同樣適用於新抱孝順老爺奶奶。

沒錯,稅局對「父母」的定義是超乎一般人想像的。在稅例中,「父母」是指:
  • 你或你配偶的親生父母/領養父母/繼父母;或
  • 已故配偶的父母。

這意味著,如果年輕夫婦一個高收入(基本上盡加免稅額亦能用盡退稅上限),另一個已屆退稅上限的臨界點,可以由收入高的一方供養對方的父母,享盡 17% 邊際稅率效益。

而重點是 —— 這個不需要兩夫婦合併評稅!

筆者在發現新大陸後做了個街頭訪問,發現同事朋友間普遍不知道稅局如此廣闊的「父母」定義。這也難怪,因為不論在報稅表還是稅局提供的攻略本(即《BIR60 報稅指南》)也沒有提及此定義,筆者要找到 Online Help (見文末),實在有點「陰濕」。

知道可以供養老爺奶奶岳父岳母的,也普遍以為這是在合併評稅下方才成立。留意兩夫婦合併評稅的話,稅階只算一次,所以除非夫婦收入懸殊到其中一方連個人免稅額也未能用盡,否則一般來說合併評稅並沒有好處。

不過管他有沒有好處,稅局會自動計算合併和分開評稅下較小的稅款,所以筆者每年都勾選選項讓稅局算一次好了。反之稅局並沒有提供計算最佳「父母」免稅額安排的服務,這個部分只好親自上陣。

方法?請參考《撳錢》第一集,建立 Template 後每年更新。留意在發現新大陸後,單是一對年輕夫婦供養四大長老,理論上有 24 = 16 個組合需要考慮!留意父母是否年過 60、有否傷殘、是否同住等也會影響免稅額,不得不覺察。如果讀者有四兄弟姊妹,各自結婚,各自有自己「Shared」及「Private」的長老,每對的另一半又有各自原生家庭的分配決定,甚至開始要考慮子女免稅額⋯⋯ 那你明白為什麼稅局不提供這個服務了吧!

筆者強調,其實數學上這只是重複的計算,只要能寫出所有的組合再加上一些 Excel / 編程的技巧(沒有的話也可以用毅力搭救)總能找到數學上的最佳解答。真正的難度,是所有牽涉在內的「一致行動人士」必須對自己的收入和家庭狀況開誠報公,試問你又否願意每年 Update 你兄嫂或妹夫自己的收入準確至個位數?就算你願意,對方又否同樣願意?

類似的定義,同樣適用於祖父母。最重要的條件就是每一位受養人只可「分配」到一位供養人,即只可由一名人士申索免稅額。記住,如果從前填錯了,7 年內都可以改正,只要一個正確答案和一張 IR6074A。詳細方法同樣見《撳錢》第一集

讀者可參考稅局 Online Help,「供養父母及供養祖父母或外祖父母免稅額」一段:
https://www.gov.hk/tc/residents/taxes/salaries/allowances/allowances/allowances.htm#dpa

熱門文章