-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathXirr Code.R
79 lines (55 loc) · 2.3 KB
/
Xirr Code.R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
library(tidyverse)
xirr <- function(dataset) {
# creating a function to calculate npv value
npv <- function(range, dataset){
for(test.rate in range) {
max.date <- max(dataset$dates)
temp <- dataset %>%
mutate(npv = amount * ((1 + test.rate/100)^(as.numeric(max.date - dates)/365))) %>%
select(npv) %>%
.[1]
if(sum(dataset$amount) > 0) {
if(sum(temp) > 0) {
min.rate <- test.rate
next
} else {
max.rate <- test.rate
break
}
} else {
if(sum(temp) < 0) {
min.rate <- test.rate
next
} else {
max.rate <- test.rate
break
}
}
}
return(list(min.rate = min.rate, max.rate = max.rate))
}
names(dataset) <- c("dates", "amount")
max.rate <- c()
min.rate <- c()
if(sum(dataset$amount) > 0) {
range <- seq(from = 0, to = 10000, by = 100)
hundreds <- npv(range, dataset)
range <- seq(from = hundreds$min.rate, to = hundreds$max.rate, by = 10)
tens <- npv(range, dataset)
range <- seq(from = tens$min.rate, to = tens$max.rate, by = 1)
ones <- npv(range, dataset)
range <- seq(from = ones$min.rate, to = ones$max.rate, by = 0.01)
decimals <- npv(range, dataset)
return(paste("XIRR is ", mean(unlist(decimals)), "%", sep = ""))
} else {
range <- seq(from = 0, to = -10000, by = -100)
hundreds <- npv(range, dataset)
range <- seq(from = hundreds$min.rate, to = hundreds$max.rate, by = -10)
tens <- npv(range, dataset)
range <- seq(from = tens$min.rate, to = tens$max.rate, by = -1)
ones <- npv(range, dataset)
range <- seq(from = ones$min.rate, to = ones$max.rate, by = -0.01)
decimals <- npv(range, dataset)
return(paste("XIRR is ", mean(unlist(decimals)), "%", sep = ""))
}
}