[英]How can I loop through the r tvm "XIRR" function to calculate xirr for different trade strategies?
[英]Can I apply the XIRR function from tvm library for each row in my table, where the cash flows already on that row?
這是我的第一個問題,因此,如果不是一個完美的問題,我謹向您道歉。 我已經在Stack Overflow(&Google)上進行了搜索,但是找不到我想要的東西。 另外,我是R的新手,並且我自己會自己學習。
我的問題是這樣的:我正在嘗試使用tvm的XIRR函數計算表中每一行的內部收益率。 我能夠使XIRR能夠為單一現金流量工作。 這是我上班的例子。
# This is a sample that works
install.packages("tvm")
library(tvm)
x_CF <- c(-7500, 3000, 5000, 1200, 4000)
x_d <- as.Date(c("2016-01-01", "2016-02-01", "2016-04-15", "2016-08-01", "2017-03-26"))
xirr <- xirr(x_CF, x_d)
在我的特定情況下,我有一個表格,其中每個ID的每一行都填充有定期現金流量和日期。 現金流量在cf1,cf2,cf3,cf(n)列中,日期在date1,date2,date3,date(n)列中。現金流量和日期數當前為14(n = 14),但可能有所不同(例如36、60等)。 這是從我的大表中填充2行的代碼。
# This is just 2 rows of my data table where I manually write the values (the real table is much larger and is dynamically created with code)
sample_data <-
matrix(
c(
"A",
"2016-01-31", "2016-02-29", "2016-03-31","2016-04-30","2016-05-31",
1000, 10, 20, -50, -1025,
"B",
"2016-01-31", "2016-02-29", "2016-03-31","2016-04-30", "2016-05-31",
1000, -50, 20, 10, -1025),
ncol = 11, byrow = TRUE)
colnames(sample_data) <-
c("SecId",
"date1", "date2", "date3", "date4", "date5",
"cf1", "cf2", "cf3", "cf4", "cf5")
sample_data <- tbl_df(sample_data)
sample_data <-
sample_data %>% mutate_at(vars(starts_with("cf")),
funs(as.integer))
sample_data <-
sample_data %>% mutate_at(vars(starts_with("date")),
funs(as.Date))
我想使用XIRR函數讀取cf1:n和date1:n。 結果應在另一列(XIRR)中插入,計算值應為A = 0.1412532和B = 0.1458380。
這可能嗎,還是我應該研究其他功能? 謝謝!
編輯-其他詳細信息以及對“同行”答案為何無效的答復
我的實際數據是以長表格式包含超過550萬行的現金流量和日期。 之所以將它們轉換為“已棄用”表,是因為我最終想要做的是創建滾動的每月IRR計算。 我想出了如果我在每一行上建立了日期和現金流,那么我就可以避免直接將XIRR直接應用於每一行。 創建包含ID / Date的每個迭代的長表對於這種數量的數據是不現實的(我不認為)。
使用建議的代碼,現金流和日期合並為相同的ID,因此不考慮滾動期間。 我知道我的原始問題並未對此進行解釋。
此外,我的現金流缺失的期間顯示為NA(因為它們被突變為數字)。 我需要XIRR通過在有任何NA時不執行計算來處理此問題。 我認為可以在summary命令中使用is.na = TRUE進行處理。
編輯2:找到了部分解決方案
解決了這個問題之后,我能夠從上面獲取XIRR函數以處理示例數據。 這是有效的代碼,但是花費我的實際數據很長時間。
calc_xirr <- sample_data %>% rowwise() %>%
do(data.frame(., xirr = tryCatch(xirr(unlist(.[7:11]), unlist(.[2:6]),lower=0,upper=1),
error = function(e) {NA}))) %>%
select(SecId, xirr)
我收到警告消息“警告消息:bind_rows_(x,.id):不相等的因子水平:強制轉換為字符”,但計算准確。
我仍然遇到的問題是,這對於我的實際數據集來說有多慢。 它可以運行很長時間(超過6小時),但確實會產生正確的結果。 有沒有什么辦法可以使用並行處理來重寫它,也可以不逐行地重寫它,我認為這是一個循環操作並且很慢。
首先, tbl_df
似乎被棄用,請as_tibble
或as.tibble
代替。
我還更改了您的示例數據,因為從ID“ A”應用數據時遇到錯誤。 我將樣本數據定義如下。
sample_data <-
matrix(
c(
"A",
"2016-01-01",
"2016-02-01",
"2016-04-15",
"2016-08-01",
"2017-03-26",
-7500,
3000,
5000,
1200,
4000,
"B",
"2016-01-01",
"2016-02-01",
"2016-04-15",
"2016-08-01",
"2017-03-26",
-7500,
3000,
5000,
1200,
4000
),
ncol = 11,
byrow = TRUE
)
colnames(sample_data) <-
c("ID",
"date1",
"date2",
"date3",
"date4",
"date5",
"cf1",
"cf2",
"cf3",
"cf4",
"cf5")
我將代碼分為兩部分。 第一部分是整理數據,第二部分是創建所需的值。
sample_data <- tbl_df(sample_data)
sample_data <-
sample_data %>% mutate_at(vars(starts_with("cf")),
funs(as.numeric),
vars(starts_with("date")),
funs(as.Date))
sample_data_dates <-
sample_data %>% select(starts_with("date"), ID) %>% gather(key, date, -ID) %>% mutate(index = gsub("date", "", key))
sample_data_cashflows <-
sample_data %>% select(starts_with("cf"), ID) %>% gather(key, cashflow,-ID) %>% mutate(index = gsub("cf", "", key))
sample_data <-
inner_join(
sample_data_dates %>% select(-key),
sample_data_cashflows %>% select(-key),
by = c("ID", "index")
) %>% select(-index)
之后,您將獲得一個具有列名稱ID,日期和現金流量的表。 然后,您可以通過以下代碼簡單地從函數xirr計算結果值:
sample_data %>% group_by(ID) %>% summarise(xirr(cashflow,as.Date(date)))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.