Excel 小技巧

前陣子看到網路上的美股投資 Excel 檔 [1], 覺得很厲害. 仿照它可以用來管理同仁在每個子產品線的計畫投資了多少人力. 不過, 想要把它從 Google Doc 搬到 Windows 平台,  很多厲害的指令都不能用了!!

首先是這個 D2 = if(isblank(A2),,counta(SPLIT(B2,",")))

spli_count-768x146

D2 可以將 B2 裡面的項目數算出來 (counta), 但先要用 SPLIT 把 B2 按照逗號 (,) 隔開. 不過 Office 裡面的 Excel 函數就做不到這點. 取而代之, 另外一個技術是計算逗號數再加一. 

B2=IF(ISBLANK(A2),,LEN(C2)-LEN(SUBSTITUTE(C2,",",""))+1)

它的原理是先算整個長度 LEN, 再減去字串中的逗號被取代的次數 (SUBSTITUTE). 這樣逗號的前後有空白也沒有關係.

第二個是上述的 C2, 它可以去另外一個工作表 (Portfolio) query 整張 ($B$5:$O$70) 裡面, 有沒有 B 欄的內容等於本頁的 A2 (也就是上圖中的 Apple), 有的話就取出它 O 欄的值.

C2=if(isblank(A2),,query(Portfolio!$B$5:$O$70,“select O where B='"&A2&“‘"))

我覺得這個功能超強大, 不過 Office 的 Excel 也不能用. 取而代之的, 是用

C2=VLOOKUP($B2,Portfolio!$C$5:$O$70, 13, FALSE)

用垂直方向 LOOKUP 找 B2, 找到之後, 選右方第十三欄的內容. 這看起來很矬, 但也算是堪用.

第三個技巧是, H 欄可以把所有股票中, 每個單月的配息分別加起來, 從一月到十二月. 例如:

H2 =sum(query($B$2:$E$64, “select E where B like ‘%Jan%'"))

它 query 整張 (B2:E64) 裡面 B 欄裡面找到有 Jan 這個單字的列, 將其 E 欄的內容累加起來 (sum).

然而, Office Excel 的 query 也不是這樣用的. 因此我先把 H2 的內容 ‘Jan’, 前後加上萬用字元 (*), CONCATENATE(“*",$H2,"*").

CONCATENATE(“*",$H2,"*")

SUMIF() 是條件式的函數, 第一個參數是加總的範圍為整張 (B2:B64), 第二個參數是條件式是否成立. 目前是 *Jan*, *Feb*’…這些是否存在. 第三個參數是要加總的內容.

H2 =SUMIF($B$2:$B$ˊˊ64,CONCATENATE(“*",$H2,"*"),$E$2:$E$64) 

這個作法也等效於 Google Doc.

以上供大家參考, 也避免自己忘記.

[Note]

  1. http://www.twoinvesting.com/2017/10/dividend-stock-portfolio-spreadsheet-on-google-sheets/

三支美股 ETF 的 IRR

網路上有一些關於美股 ETF 的討論, 瞄了一下有些是要花錢買會員的. 如果不花錢的就要靠 Yahoo 了, 希望它繼續做公益, 不要把網站關了.

在 Yahoo Finance [1] 可以搜尋這些 ETF, 雖然不能說資料多麼詳盡, 介面多麼好用, 至少它是相當地佛心. 剛剛抓了 VIG, VDC, NOBL 三支 ETF 的每月股價 (經過股利發放與無償配股調整後的價格), 計算各自的 IRR, 比較如下:

ETF 月份數 月 IRR 起始時間 調整股價 海嘯後低點 調整股價
NOBL ˊ61 1.739% 2013/10 38.74 N/A N/A
VDC 178 1.485% 2004/1 36.63 2009/2 38.95
VIG 150 1.242% 2006/5 38.12 2009/2 26.86

看起來 NOBL 非常之厲害.  不過這些歷史資料, 還是要分成金融海嘯前或是之後.

2008 年金融海嘯之前, NOBL 還沒出生. 另兩支 ETF 只能算小漲. 金融海嘯之後, VDC 至少沒退回起點, 而 VIG 不只是白做三年工, 還打七折. 看似 VDC 勝出, 但把 VDC 和 VIG 放在同一條起跑線, 假設大家都從 2006/5 開始算, 比較結果如下:

ETF 月份數 月 IRR
VDC 150 1.485%
VIG 150 1.57%

換言之, 扣掉 2004/1~2006/5 這個時段, VIG 也不輸 VDC. 主要是 2005 年美股比較不動. 停滯期數愈多, IRR 算出來就愈低.

至於, NOBL 雖然出生得晚. 但是它的統計資料卻歷史久遠. 從 1990~2017 年化報酬率是 27.34%, 2018 到目前為止是跌的. 比較公平的比法還是大家都對齊到 NOBL 上市的時間. 不然我查不到 1990 年 VDC, VIG 各應該值多少?

ETF 月份數 月 IRR
NOBL 61 1.739%
VDC 61 1.339%
VIG 61 1.621%

如果起跑線一樣, NOBL 還是贏過另外兩位. 所以, 以我不專業路人的觀點, NOBL 確實比較好. 這也是 <美股股息成長投資術> 這本書裡面提到的一支 ETF, 作者追日 Gucci 常常會拿自己的投資報酬率和它 PK, 或者討論它 [2]!

[Note]

  1. https://finance.yahoo.com/
  2. https://www.guccidgi.com/2017/12/dividend-stocks-vs-growth-stocks

股市大跌小筆記

上週美股跌, 導致台股跟著跌, 加上大陸跌好久了; 現在正是進場的好機會. 想到要分散風險, 中美台應該都要買一點. 買中美是因為他們是世界兩強, 買台股最大的好處是殖利率高 (但成長性差於美股). 如果不是買日股比較麻煩, 我想買 Konami 把我以前買遊戲的錢賺回來, 哈!

陸股已經跌得慘兮兮, 可能快見底了. 雖然有人說現在 all in, 以後可以賺很大. 不過截至目前為止, 有幾個台股 ETF 今年都還是正報酬 (台灣 50: 1.17%, 高股息: 0.53%, 公司治理: 1.63%, 高息低波動: 7.18%)[6]. 只賭中長期大賺, 但短期卻青筍筍也不好看. 所以陸股買到一定程度就先放緩.

[Note] 根據證交所的資料, 高息低波應該有 7.18% 的報酬, 不過如果是買元大高息低波 ETF (00713), 今年迄今報酬率是 -2.064%. 這可能是因為內扣費用或是周轉率造成的, 因為它並沒有配息, 難道追蹤誤差這麼大?

[Note 2] 國泰低波動 30 幾乎就符合證交所的漲幅.

買美股是一門大學問, 個股我只買過可口可樂和波克夏, 這兩支股票都很不錯. 雖然波克夏最近大概是蘋果吃多了, 跌勢有點像科技股, 但應該還是個好標的. 根據 Morning Star [1] 等網站 [2], 美股的 ETF 則多得令人眼花撩亂.  稍微瞄一下 VDC 裡面前三大持股都是我喜歡的, 主要持股至少到 Costco 我都還認識 [3], 目前看得很中意但還沒買到.

vdc-1

至於這次殖利率太高導致美股崩跌的十年期公債, 我也算了一下. Firstrade 上面現在有四個報價, 前三個都是 treasure notes, 第四個是 treasure bonds. 看來 treasure bonds 賣比較貴. 兩個都是十年左右才到期,  風險也一樣, 但 Treasury notes are not callable [4]. 不知道是否價位跟這個屬性有關?

us-treasure-bond-1-620x190

根據 [5], YTM 是這樣來的:

ytm-1

P = price

I = interest.  其中 coupon 是年化報酬率, I 才是真正月配 (或季配/年配) 的利息.

n = 分為 n 期, 或到到期日還有幾期?

M = mature = 到期領回的錢.

把 YTM 帶入公式, Excel 算出 coupon = 2.875 的這兩個 treasure note 的 price 比網站上低一點點 (不論假設月配或季配), 不知道是否含稅的關係?

想要直接買美債, 看來需要個好頭腦, 可能還是買美債 ETF 比較有機會. 我以前買過美元計價的抗通膨美債 ETF, 後來靠著台幣貶值才回本, 至今還沒有更聰明的想法可以出手. 而且現在台幣貶美金漲, 拿新資金去買美債, 可能有好幾年的債息 (約 2%) 要拿去填匯差, 再想想吧~~~

[REF]

  1. http://news.morningstar.com/etf/lists/ETFReturns.html
  2. https://tools.alphaarchitect.com/screener
  3. http://portfolios.morningstar.com/fund/holdings?t=VDC&region=usa&culture=en-US
  4. https://financetrain.com/us-treasury-bills-notes-and-bonds/
  5. https://publish.get.com.tw/BookPre_pdf/51MB400418-2.pdf
  6. http://www.twse.com.tw/zh/page/trading/indices/SPTLHD.html

SPIN_LOCK 小註解

最近看到一個 Kernel config 叫做 CONFIG_UNINLINE_SPIN_UNLOCK, 這 un 又 un, 真的是讓人看得眼花. 雖然說現在人強調 “減法" 的思維, 看這個名詞還是得用 “加法".

STEP 1: SPIN_LOCK [1], 多處理器共用一個資源時, 透過 SPIN_LOCK 去鎖住不讓其他人用. 自己用完後, 設為 unlock, 別人就可以用. 怎麼知道可不可以用呢? 要透過 trylock() 來判斷是否拿到資源. 如果拿不到回直接回傳 busy, 除非一直 try 否則也不會浪費資源. 真的 try 不停就要看演算了 [2].

STEP 2: INLINE_SPIN_LOCK. inline 是指會將 spin_lock() 插入程式之中. 但它也不只是當作巨集處理而已, 參考 [3] 這段話, 它會把 spin_lock() 這個函式的內容優化之後才代入. 

The point of making a function inline is to hint to the compiler that it is worth making some form of extra effort to call the function faster than it would otherwise – generally by substituting the code of the function into its caller. As well as eliminating the need for a call and return sequence, it might allow the compiler to perform certain optimizations between the bodies of both functions.

STEP 3:  INLINE_SPIN_UNLOCK. 有鎖的動作就有解鎖. 使用之前, kernel config 要先打開. 追溯到 2012 年, 當初只有 CONFIG_INLINE_SPIN_UNLOCK [4].

STEP 4:  Linus Torvalds 自己建議把原本預設開 CONFIG_INLINE_SPIN_UNLOCK, 改為預設 CONFIG_UNINLINE_SPIN_UNLOCK 未定義 [4].

-CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_UNINLINE_SPIN_UNLOCK is not set

想要 debug inline spin unlock 的人如果想要加 debug code, 開這個 config 就不會因為 inline 的作用, 使自己的 code 和原本 inline 的函式融為一體, 以致於無法正確地 debug.

預期的路人心得:  不能因為負負得正, 就把 CONFIG_UNINLINE_SPIN_UNLOCK 想成 CONFIG_INLINE_SPIN_LOCK. 哈!

[Ref]

  1. https://blog.csdn.net/u010144805/article/details/80354679
  2. https://locklessinc.com/articles/locks/
  3. http://www.greenend.org.uk/rjk/tech/inline.html
  4. http://lkml.iu.edu/hypermail/linux/kernel/1203.2/03015.html

在 Windows 上跑 Facenet 的小筆記

最近想在 Notebook 上建一個 AI 模擬的環境, 其中遇到一些關卡值得記錄下來.

在 Notebook 上建個虛擬機來跑 AI…. 畢竟 Linux 的環境比 Windows 直覺, 所以先做了這件事. Linux 軟體安裝起來相對容易, 重點在權限開對, 路徑設定可以憑直覺.

這樣很快就可以用 CPU 跑 facenet, But, 我是想要用 GPU 來跑啊!? Google 了一下發現虛擬機的 driver 不是 cuda 相容的, 必須要裝雙系統, 有原生的 Ubuntu 才可以跑. 因此又被打回 Windows 10 環境.

在 Windows 10 上面, 當然很直覺要先裝個 Python. 但這不是最佳的選擇. 應該先裝 GPU driver, 然後裝 Anaconda [1]. 原因是 Anaconda 下可以裝很多套不同版本的虛擬 Python 環境,  即使 model 只支持特定 Python 版本, 也不需要重新安裝 Python. 畢竟 Python 2.x 和 Python 3.x 就不相容了, 換來換去很麻煩.

若先裝 Python, 再裝 Anaconda, 後者會問要不要把 Anaconda 設為 Python 的預設程式? 如果選不要, 我發現很多怪現象會發生. 例如 Anaconda Navigator 搞失蹤之類的. 即使把既有的 Python 解除安裝, 在沒有重新開機之前, 純 Python 還是會在背景干擾 Anaconda Python. 所以乾脆反過來只安裝 Anaconda, 把它設為預設程式.

Step 1: 下載並安裝 Anaconda 3. 版本 4 和 5 好像是要錢的企業版.

然後在 Anaconda 底下的 envs 目錄下可以看到多個目錄, 每一個代表一種虛擬的環境. 當然這個要按照 Anaconda 的官網說明去創建, 如果不建立這底下就是空蕩蕩的. 環境做好之後, 會在 Windows 的程式集裡面看到成對的 prompt, Spyder…等等. prompt 就是命令列, Spyder 有 GUI, 而 reset 顧名思義就是把這個虛擬環境清掉重來, 在裝錯軟體的時候很好用.

anaconda

Step 2. 建立 Anaconda 下的虛擬環境, -n 的後面跟著名字, 例如我用 tensorflow-gpu 就可以來來區隔這個環境是跑 GPU 版本的. 但這只是名字而已, 真正的安裝在後面步驟. 但我後來後悔用這麼長的名字, prompt 變得很長. 此處指定了 python 的版本.

c:> conda create -n tensorflow pip python=3.6

Step 3. 啟用這個環境.

C:> activate tensorflow
 (tensorflow)C:>  # Your prompt should change

Step 4. 安裝跑 GPU 版本的 tensorflow. 這邊的 tensorflow-gpu 就是關鍵字不能改了.

(tensorflow)C:> pip install --ignore-installed --upgrade tensorflow-gpu

以上 Step 1~4 參考 Anaconda 官網 [1], 還有教人如何驗證安裝正確與否.

此外, tensorflow-gpu 往下需要 Cuda 和 Dnn 的函式庫. 參考這篇 [2] 即可. 其中, Cuda 要用第九版, CuDnn 應該用 V7 或 V7.1. 至於 GTX 顯卡的 driver 是本來就有的, 如果您是用 AMD 系列的顯卡, 這個我就沒研究.

這裡看起來很簡單, 但是陷阱也很多.  如果裝錯的話, 後續跑 tensorflow-gpu 就會報錯, 說找不到 cudart.lib, cudablas.lib….等等. 原因在於大家可能在安裝 GTX 顯卡的時候, 就在 C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v9.0\lib\x64 底下安裝了 cuda 相關的函式庫, 所以優先被執行到.

若安裝正確的話, 應該在指定的目錄 (解開 cudnn-9.0-windows10-x64-v7.zip 後手動放的那個目錄), 看到 cudnn64_7.dll. 然後把這個目錄加入 path. 網路上有很多人求救, 他們可能是把 32 bit / 64 bit 搞錯, 或已經安裝了 cudnn-9.1 但 tensorflow 只支援到 9.0 之類的, 總之痛下殺手把電腦的版本降級配合 tensorflow 就行了.  

搞定 dnn 之後, 就可以按照滿山遍野的網路教學跑 MTCNN + Facenet [3][4]. 但還是要請大家再次釐清一個觀念是: 既然我已經用 Anaconda 做虛擬環境, 一切都要在虛擬環境下執行. 也就是 envs/tensorflow-gpu (舉例)/ 而不是 Anaconda 目錄下 [3].  然後呢…facenet 是一個 module, 必須安裝到 lib/site-packages/ 底下才能執行, 光是下載 facenet copy 進去是沒用的.

Python 中安裝 module 的方法有很多種[5]. 我們只需要用到最簡單的 pip install facenet 即可. 其他的按照 [4] 應該就可以依序執行 MTCNN 和 Facenet. 這邊會踩到的雷是: Windows 系統的字型編碼會造成 facenet error, 這個外國人可能遇不到. 大約在 facenet.py 的 577 行左右, 要把原文改為我下面的這行代碼. 當然最前面要記得 import io.

# with open(rev_info_filename, “w") as text_file:
with io.open(rev_info_filename, “w", encoding="utf-8″) as text_file:

然後, 如果要 traning 自己的 database, 還有一行要改. 在 train_softmax.py 的 95 行左右, 無論換哪個 database, 它都固定去讀 data/pairs.txt, 所以我硬改一個寫死的目錄, 以便可以測 mydata.

# pairs = lfw.read_pairs(os.path.expanduser(args.lfw_pairs))
pairs = lfw.read_pairs(os.path.expanduser(‘mydata/pairs.txt’)) #Cash modified

在跑 MTCNN 的時候, 網路上很多文章都說要執行

python ~/tensorflow/facenet/src/align/align_dataset_mtcnn.py ~/tensorflow/lfw/raw ~/tensorflow/lfw/lfw_mtcnnpy_160 –image_size 160 –margin32 –random_order –gpu_memory_fraction 0.25

最後面 –gpu_memory_fraction 0.25 這個參數, 其實是 facenet 官網 [6] 跑四個 process 的關係, 跑 4 個當然每個人用 1/4 (0.25) 囉. 如果只跑一個 process, 加上這行唯一的好處是記憶體比較不會爆掉.

以上是跑 tensorflow 主線任務的紀錄. 支線上任務則是曾經試圖跑 mxnet + opencv 的版本, 結果第一路打通就沒繼續奮鬥了.

Step 1. 下載 opencv V.3.4.1

https://opencv.org/opencv-3-4-1.html 選 https://github.com/opencv/opencv/tree/3.4.1

Step 2. 解開 opencv 發現要 cmake.

Step 3. 下載 Visual Studio Community 2017

Step 4. 在 Visual studio 的 “工具" 裡面選 “擴充功能與更新", 選 cmake 下載, 安裝.

在 “工具" 選 “取得工具與功能", 選 “工具負載" 裡的 “其他工具組"  的 “使用 c++ 進行 Linux 開發", 選 “Web 與雲端" 的 “Python 開發".

Step 5. 下載 cmake, 在 https://cmake.org/download/  選 cmake-3.12.1-win64-x64.msi

要選產生 GUI 比較方便.

Step 6. 在 Cmake GUI 選 source code 位置, Build binary 位置, 選 Configure, 跑一段時間, 選 Generate 產生 build file. 選 Open Project 帶起 Visual Studio. [7]. 

cmake-1-768x661

Step 7. 在 Visual Studio build 這個 project. 參考 [8]  作一些修改. 但它的版本比較舊, 在我的平台上要把 VC10 改為 VC15, x86 改為 x64. opencv 改為 opencv 和 opencv2.

Step 8. 編成功後, 會在 c:\opencv\build\release\bin\debug (舉例) 看到一堆檔案, 這樣就成功了. 其中 opencv_interactive-calibrationd 跑起來會自動抓 NB 前鏡頭的畫面, 看了會很有感. 上面截圖時, 我把 binary 位置選在 c:\opencv\build, 但裡面本來就有檔案了, 再放自己編出的檔案會糊成一團, 故第二次我把 target 改到 c:\opencv\build\release.

Step 9. 安裝 mxnet

這個網頁可以自訂要下載哪一種 mxnet 的版本, 相當地人性化. 我選了

mxnet-1-768x372

https://mxnet.apache.org/install/index.html?platform=Windows&language=Python&processor=GPU

Step 10. 建議安裝 Anacoda — 請參考前面說的.

Step 11. 升級 mxnet 以支援 GPU

pip install mxnet-cu92

Step 12. 調整路徑

不調整路徑的話, 直接 load mxnet 版本的 facenet 會出現找不到 module 的錯誤. 事實上, 採用 Tensor flow 版本的人也是一直再狂問為何找不到 tensorflow module. 這些都是路徑的問題.

正常安裝完的 module 都會放在 pythonxxx 下面的 Lib/site-packages.

[Note]

  1. https://www.tensorflow.org/install/install_windows
  2. http://blog.nex3z.com/2017/04/18/%E5%9C%A8-windows-%E5%B9%B3%E5%8F%B0%E5%AE%89%E8%A3%85-nvidia-gpu-%E5%8A%A0%E9%80%9F%E7%9A%84-tensorflow/
  3. https://blog.csdn.net/xiangxianghehe/article/details/72809600
  4. https://blog.csdn.net/chzylucky/article/details/79680986
  5. https://packaging.python.org/tutorials/installing-packages/
  6. https://github.com/davidsandberg/facenet/wiki/Classifier-training-of-inception-resnet-v1
  7. http://gclxry.com/use-cmake-on-windows/
  8. http://monkeycoding.com/?p=516