Chapter 8 Appendix

8.1 台灣REITs此次修法重點

8.1.1 基金信託雙軌制

  未來修法方向朝基金制度,也會開放現行信託制轉換至基金制。
  基金型REITs 具有四大特點:
    (1) 由不動產投資信託事業擔任管理機構有利發揮管理專業。
    (2) 簡化募集程序及確保收益支持等方式,有利基金規模持續成長,並獲取穩健的收益率。
    (3) 允許REITs進行關係人交易,利於REITs活化資產,並有利提升REITs資產配置彈性。
    (4) 分離保管及管理責任,有利權責劃分明確。

8.1.2 海外投資標的流程簡化

  金管會曾於2016年3月開放國內REITs投資海外不動產,但申請過程過於耗時繁雜,導致易於喪失好的投資標的,因此目前尚無國內 REITs投資境外不動產。

  因此藉由流程簡化,不僅有利於國內REITs前往海外不動產市場尋找報酬率較高的投資標的,更有利刺激提高配息,改善現今租金收益率表現不佳,以活絡台灣REITs市場。

8.2 各國REITs制度比較

國家 發行架構 股利率 股市占比
美國 信託、基金、公司、合夥等多種制度 4.9% 5%
日本 基金制、公司制 4.8% 2.4%
新加坡 主要為基金制 5.9% 6.4%
台灣 信託制 2% 0.2%

8.3 所有使用到的套件

library(readxl)
library(magrittr)

library(ggplot2)
library(hrbrthemes)
library(gganimate)

library(DBI)
library(RSQLite)

library(lubridate)
library(quantmod)

library(bookdown)

8.4 專題資料庫data.db建置

8.4.1 data.db簡介

data.db容納我們整個專題所需的數據,使用SQL建置。

表格名稱 說明
tr_index 我們所編製的T-REITs指數(基值為100)
m_index 大盤指數
all_index 我們所編製的T-REITs指數以及大盤指數
re 台灣REITs個股近五年報酬率(年資料)
sp 台灣REITs個股近五年日收盤價
wr 美日星台REITs資料
tr_index <- dbReadTable(con, "tr_index")
head(tr_index)
##         time    idx
## 1 2005-03-10 100.00
## 2 2005-03-11  98.09
## 3 2005-03-14  97.61
## 4 2005-03-15  96.65
## 5 2005-03-16  96.65
## 6 2005-03-17  97.13
m_index <- dbReadTable(con, "m_index")
head(m_index)
##         time  idx
## 1 2005-03-10 6193
## 2 2005-03-11 6204
## 3 2005-03-14 6156
## 4 2005-03-15 6063
## 5 2005-03-16 6072
## 6 2005-03-17 6032
all_index <- dbReadTable(con, "all_index")
head(all_index)
##         time    idx          name
## 1 2005-03-10 100.00 T-REITs Index
## 2 2005-03-11  98.09 T-REITs Index
## 3 2005-03-14  97.61 T-REITs Index
## 4 2005-03-15  96.65 T-REITs Index
## 5 2005-03-16  96.65 T-REITs Index
## 6 2005-03-17  97.13 T-REITs Index
re <- dbReadTable(con, "re")
head(re)
##   time all_return stock_id
## 1 2016  -0.005555   01001T
## 2 2017  -0.089882   01001T
## 3 2018   0.205140   01001T
## 4 2019   0.142976   01001T
## 5 2020   0.196007   01001T
## 6 2016  -0.035911   01002T
sp <- dbReadTable(con, "sp")
head(sp)
##         time stock_price stock_id
## 1 2015-01-05       13.23   01001T
## 2 2015-01-06       13.23   01001T
## 3 2015-01-07       13.23   01001T
## 4 2015-01-08       13.23   01001T
## 5 2015-01-09       13.23   01001T
## 6 2015-01-12       13.23   01001T
wr <- dbReadTable(con, "wr")
head(wr)
##   sign                                 name nation
## 1  AVB           AvalonBay Communities, Inc    USA
## 2  EQR                   Equity Residential    USA
## 3  ARE Alexandria Real Estate Equities, Inc    USA
## 4   WY                 Weyerhaeuser Company    USA
## 5    O            Realty Income Corporation    USA
## 6  EXR              Extra Space Storage Inc    USA
##   average_dividend_yield average_return total_return
## 1                 0.0326        0.07054      0.10314
## 2                 0.0328        0.08630      0.11910
## 3                 0.0272        0.17628      0.20348
## 4                 0.0405        0.05012      0.09062
## 5                 0.0426        0.03592      0.07852
## 6                 0.0346        0.26000      0.29460
##      industry market
## 1 Residential  29600
## 2 Residential  29359
## 3      Office  27123
## 4   Specialty  25646
## 5      Retail  25025
## 6  Industrial  21895

8.4.2 SQL基本指令

#path code
user_desktop <- "C:/Users/Download/"
db_path <- paste0(user_desktop, "test.db")
#connect db and R
con <- dbConnect(RSQLite::SQLite(), dbname = db_path)
#list how many talbes in db
dbListTables(con)
#list column name
dbListFields(con, name = "reits_stock")
# read all data
dbReadTable(con, "reits_stock")
# delete data
delete_statement <- "DELETE FROM reits_stock WHERE time = '2005/10/03';"
dbExecute(con, statement = delete_statement)
dbReadTable(con, name = "reits_stock")
#delete table
dbRemoveTable(con, name = "reits_stock")
dbListTables(con)
#===============================================================================
#create table
create_statement <- "
CREATE TABLE reits_stock (
 time TEXT NOT NULL,
 stock_price NUMERIC NOT NULL,
 outstanding_share INT NOT NULL,
 market_value NUMERIC NOT NULL,
 stock_id TEXT NOT NULL,
 name TEXT NOT NULL
);
"
dbExecute(con, statement = create_statement)
#Check table
dbListTables(con)
#Check colum
dbListFields(con, name = "reits_stock")

#insert data
insert_statement <- "INSERT INTO reits_stock (time, stock_price, outstanding_share, market_value, stock_id, name) VALUES ('2005/10/05', 6.198, 1393000, 8633814, '01002T', '國泰一號');"
dbExecute(con, statement = insert_statement)
dbReadTable(con, "reits_stock")

#update data
update_statement <- "UPDATE reits_stock SET time = '2005/10/06' WHERE time = '2005/10/05';"
dbExecute(con, statement = update_statement)
dbReadTable(con, name = "reits_stock")

8.4.3 插入多筆資料

`%--%` <- function(x, y)
{
  do.call(sprintf, c(list(x), y))
}

insert_data <- function(a1,a2,a3,a4,a5,a6)
{
  insert_statement <- "INSERT INTO sat (time, stock_price, outstanding_share, market_value, stock_id, name) VALUES (%s, %s, %s, %s, %s, %s);" %--% c(a1,a2,a3,a4,a5,a6)
  dbExecute(con, statement = insert_statement)
}
insert_data('"2005/10/05"','6.198', '1393000','8633814','"01002T"','"國泰一號"')
dbReadTable(con, name = "reits_stock")

8.5 如何利用R Connect publish Bookdown

  目前關於Bookdown的中文教學資料並不多,而如何publish Bookdown更是少之又少,因此我們決定分享我們publish bookdown的技巧。
  網路上大多都是使用Github,然而我們不使用Github是因為嘗試多次無法成功,所以決定另闢蹊徑。

建議已經會使用Bookdown基本功能後,準備Publish時閱讀

※所有路徑必須皆是英文

步驟一、確認所有Rmd章節(含index.Rmd)與_bookdown.yml吻合

步驟二、所有Rmd章節(不含index.Rmd)前加output: html_document,如此knit才會在_book資料夾中生成該章節的html檔,確認所有章節(含index)均於_book資料夾生成html檔。

步驟三、然後記得build book,確保每個章節連接的一致。

步驟四、 請至下方網站Rsduio Connet註冊帳號。

https://bookdown.org/connect/

步驟五、右上角Publish(藍色圖示)選擇Manage Account > Connect > Rsduio Connet

步驟六、填入https://bookdown.org/connect/ 按下Next連接

步驟七、連接完後隨便選擇任一章節knit(不要選擇編譯器右上角的pulish,會跳不到某個指定頁面)

步驟八、 knit完後右上角有一個Publish(藍色圖示),選擇Publish Document

步驟九、 選擇下方Publish finished website only
步驟十、 確認每章節(含index)html都已勾選,填入專案名稱,再點Publish,若有曾更換章節名稱記得別選到舊名稱的html檔,之後可以進入_book資料夾刪除舊名稱html檔。
步驟十一、 Deploy處可以確認是否成功。

成功輸出之後:

  • RConnect的後台可以選擇是否公開網址。
  • 如果更改章節Rmd內容可以在編譯器右上方直接選擇專案名稱Publish。
  • 如果網址裡各章節出現斷開的現象可以Build bookknit一次再Publish。
  • 中文章節名稱的html檔記得更改成英文。

以上節自個人多次嘗試後的方法,分享給各位。

8.6 程式完整碼

8.6.1 T-REITs指數運算程式碼

data <- read_excel("C:/Users/Download/t-reits.xlsx", guess_max = 10000)

# NA
data[is.na(data)] <- 0

# market value
for(i in c(2:11))
{
  data[ paste0("0100", i-1, "_P*N") ] = data[i] * data[i+10]
}

# event
event <- function(day)
{
  for(i in c(22:31))
  {
    if(data[day-1, i]==0 && data[day, i]!=0)
    {
      return(TRUE)
    }
    else if(data[day-1, i]!=0 && data[day, i]==0)
    {
      return(TRUE)
    }
  }
  return(FALSE)
}

# base year
end = length(data$time)
now = data[1, "base"] = data[1, "01001_P*N"]
for(i in c(2:end))
{
  if(event(i))
  {
    today_value = sum(data[i, 22:31])
    yesterday_value = sum(data[i-1, 22:31])
    now = data[i-1, "base"] * today_value / yesterday_value
  }
  data[i, "base"] = now
}

# all stock sum
data["sum"] = 0
for(i in c(22:31))
{
  data["sum"] = data["sum"] + data[i]
}

# t-reits index
data["index"] = (data["sum"] / data["base"]) * 100

# draw
ggplot(data, aes(x = time, y = idx)) + geom_line(col = "#1E90FF") +
  labs(x = "Time", y = "Index")

8.6.2 T-REITs指數與大盤比較圖

# data
user_desktop <- "C:/Users/Download/"
db_path <- paste0(user_desktop, "database.db")
con <- dbConnect(RSQLite::SQLite(), dbname = db_path)
data <- dbReadTable(con, "all_index")

# char to datetime
data$time = ymd(data$time)

# change base
for(i in c(1:4022))
{
  data[i, "idx"] = data[i, "idx"] * 61.9253
}

# draw
ggplot(data, aes(x = time, y = idx, colour = name)) + geom_line() +
  labs(x = "Time", y = "Index")

8.6.3 台灣REITs個股走勢圖

# data
user_desktop <- "C:/Users/Download/"
db_path <- paste0(user_desktop, "database.db")
con <- dbConnect(RSQLite::SQLite(), dbname = db_path)
data <- dbReadTable(con, "sp")

# char to datetime
data$time = ymd(data$time)

# draw
par(mfrow = c(2,3))
for(i in data$stock_id %>% as.factor() %>% levels())
{
  with(subset(data, stock_id == i), 
       plot(x = time, y = stock_price, main = i, type = "l"))
}

8.6.4 台灣REITs報酬率柱狀圖

# start
user_desktop <- "C:/Users/Download/"
db_path <- paste0(user_desktop, "database.db")
con <- dbConnect(RSQLite::SQLite(), dbname = db_path)
data <- dbReadTable(con, "re")

# draw
data %>% ggplot + geom_bar(aes(x = time, y = all_return, fill = stock_id),
                         position = "dodge", stat = "identity")

8.6.5 國外資料散點圖

user_desktop <- "C:/Users/Download/"
db_path <- paste0(user_desktop, "database.db")
con <- dbConnect(RSQLite::SQLite(), dbname = db_path)

data <- dbReadTable(con, "wr")
#nation
data %>% ggplot() +
  geom_point(aes(x = `total_return`*100,y = `market`)) + 
  facet_wrap(~nation) +
  labs(x = "Return", y = "Market Cap",title = "Return & Market Cap for Nations")
#industry
data %>% ggplot() +
  geom_point(aes(x = `total_return`*100,y = `market`)) + 
  facet_wrap(~industry) +
  labs(x = "Return", y = "Market Cap",title = "Return & Market Cap for Industry")

8.6.6 動圖

# data
user_desktop <- "C:/Users/Download/"
db_path <- paste0(user_desktop, "database.db")
con <- dbConnect(RSQLite::SQLite(), dbname = db_path)
data <- dbReadTable(con, "all_index")

# char to datetime
data$time = ymd(data$time)

# change base
for(i in c(1:4022))
{
  data[i, "idx"] = data[i, "idx"] * 61.9253
}

# draw
pic <- ggplot(data, aes(x = time, y = idx, group = name, colour = name)) + 
  geom_line() +
  geom_point() +
  theme_ipsum() +
  ggtitle("T-REITs index vs. Market index                                            2005.03.10~2021.06.23") +
  labs(x = 'Time', y = 'Index') +
  transition_reveal(time)

# Save as gif
animate(pic, height = 500, width = 900, fps = 5)
anim_save("pic.gif")