Skip to content

Commit

Permalink
version 0.1-1
Browse files Browse the repository at this point in the history
  • Loading branch information
Simon Trimborn authored and cran-robot committed Mar 29, 2019
0 parents commit 5942563
Show file tree
Hide file tree
Showing 30 changed files with 1,496 additions and 0 deletions.
17 changes: 17 additions & 0 deletions DESCRIPTION
@@ -0,0 +1,17 @@
Package: IndexConstruction
Type: Package
Title: Index Construction for Time Series Data
Version: 0.1-1
Date: 2019-03-25
Author: Simon Trimborn <simon.trimborn@nus.edu.sg>
Maintainer: Simon Trimborn <simon.trimborn@nus.edu.sg>
LazyLoad: yes
LazyData: true
Depends: R (>= 2.10)
Imports: KernSmooth, fGarch, lubridate, xts, RcppBDT, zoo
Description: Derivation of indexes for benchmarking purposes. The methodology of the CRyptocurrency IndeX (CRIX) family with flexible number of constituents is implemented. Also functions for market capitalization and volume weighted indexes with fixed number of constituents are available. The methodology behind the functions provided gets introduced in Trimborn and Haerdle (2018) <doi:10.1016/j.jempfin.2018.08.004>.
License: GPL (>= 3)
NeedsCompilation: no
Packaged: 2019-03-25 02:08:44 UTC; matsim
Repository: CRAN
Date/Publication: 2019-03-29 16:50:03 UTC
29 changes: 29 additions & 0 deletions MD5
@@ -0,0 +1,29 @@
21ab0e60d738da9da2f830f0fc22e476 *DESCRIPTION
d49d84e3f91092578b3969a2c87e81e9 *NAMESPACE
70aaa902c6a9eae00ad8dd72f638b2cb *R/CRIXwrappers.R
50ac1ff9cab1ca95118c4e20c49b0743 *R/IndexComp.R
d2c0a5c2616d983f0a74d05371a4dd73 *R/IndexEval.R
06d40c34574ce39df85c386684fef54c *R/IndexLoop.R
3395066b42318dc5ce9cc10236785c0c *R/IndexMemberSelection.R
89fcbf034dc1f07bc01400e652c2daa9 *R/IndexMembersUpdate.R
80434123f2a18caf5d1607ba453f4d48 *R/IndexUpdate.R
2b93d31df319888b559b67f2de351fbc *R/RelativeWeights.R
662ac8867dd97f202e83e61febae4b75 *R/SwitchDates.R
199c301086baae8c18ffc79e45d811ac *data/CryptoData.RData
7c699b51ebd02eda5b76c33225e91189 *data/datalist
b09de006b611cb84739c53cfe3771b9f *inst/CITATION
639cf1149c43a615508f02ae89c905d2 *man/CRIX.Rd
eaefd014b392e7382cdb215b24afb9b9 *man/ECRIX.Rd
bc92a6715ac0a47f8ee2e3a0ffcc83b4 *man/EFCRIX.Rd
5b32face713cbc9c7998a8e2252feb92 *man/IndexComp.Rd
6c3260f597a4091052c749b32e99680c *man/IndexMemberSelection.Rd
985c9b7c49b875444dfc5100372cc47b *man/IndexMembersUpdate.Rd
e13db512b944559c526e7289abb7ac47 *man/IndexUpdate.Rd
7f88c7c4d4fe7478296ca611572e12ca *man/LCRIX.Rd
0c7f13adbbe3c9e49ba217f59088acf0 *man/LECRIX.Rd
22380196596f2b958d7b5a6110c604ac *man/LEFCRIX.Rd
7a4b6047e2578fc5631684bf9f399653 *man/RelativeWeights.Rd
d505b7e832d2daf78593cde418a85523 *man/SwitchDates.Rd
3035265cf9fedab107be5fc912d43f0c *man/marketData.Rd
b716fe2621ad924b1574155a8d306b86 *man/priceData.Rd
2dcba450227d1ef2a5baff32f3b7b7c8 *man/volData.Rd
17 changes: 17 additions & 0 deletions NAMESPACE
@@ -0,0 +1,17 @@
## regular functions:

export("IndexComp", "SwitchDates", "IndexUpdate", "RelativeWeights", "IndexMemberSelection", "IndexMembersUpdate",
"CRIX", "ECRIX", "EFCRIX", "LCRIX", "LECRIX", "LEFCRIX"
)

# imports:

import(lubridate)
import(xts)
import(fGarch)
import(KernSmooth)

importFrom(stats, lm, var)
importFrom(utils, tail)
importFrom(RcppBDT, getNthDayOfWeek)
importFrom(zoo, index, na.locf)
41 changes: 41 additions & 0 deletions R/CRIXwrappers.R
@@ -0,0 +1,41 @@
CRIX = function(market, price, vol = NULL, days.line) {
IndexComp(market = market, price = price, vol = vol, weighting = "market", weighting.all = "market", IC = "AIC", EvalSeq = "AllTogether", optimum = "local",
start.const = 5, steps = 5, fixed.value = NULL, base.value = 1000,
derivation.period = 1, derivation.period.ic = 3,
days.line = days.line)
}

ECRIX = function(market, price, vol = NULL, days.line) {
IndexComp(market = market, price = price, vol = vol, weighting = "market", weighting.all = "market", IC = "AIC", EvalSeq = "AllTogether", optimum = "local",
start.const = 1, steps = 1, fixed.value = NULL, base.value = 1000,
derivation.period = 1, derivation.period.ic = 3,
days.line = days.line)
}

EFCRIX = function(market, price, vol = NULL, days.line) {
IndexComp(market = market, price = price, vol = vol, weighting = "market", weighting.all = "market", IC = "AIC", EvalSeq = "AllTogether", optimum = "global",
start.const = 1, steps = 1, fixed.value = NULL, base.value = 1000,
derivation.period = 1, derivation.period.ic = 3,
days.line = days.line)
}

LCRIX = function(market, price, vol = NULL, days.line) {
IndexComp(market = market, price = price, vol = vol, weighting = "volume", weighting.all = "volume", IC = "AIC", EvalSeq = "AllTogether", optimum = "local",
start.const = 5, steps = 5, fixed.value = NULL, base.value = 1000,
derivation.period = 1, derivation.period.ic = 3,
days.line = days.line)
}

LECRIX = function(market, price, vol = NULL, days.line) {
IndexComp(market = market, price = price, vol = vol, weighting = "volume", weighting.all = "volume", IC = "AIC", EvalSeq = "AllTogether", optimum = "local",
start.const = 1, steps = 1, fixed.value = NULL, base.value = 1000,
derivation.period = 1, derivation.period.ic = 3,
days.line = days.line)
}

LEFCRIX = function(market, price, vol = NULL, days.line) {
IndexComp(market = market, price = price, vol = vol, weighting = "volume", weighting.all = "volume", IC = "AIC", EvalSeq = "AllTogether", optimum = "global",
start.const = 1, steps = 1, fixed.value = NULL, base.value = 1000,
derivation.period = 1, derivation.period.ic = 3,
days.line = days.line)
}
219 changes: 219 additions & 0 deletions R/IndexComp.R
@@ -0,0 +1,219 @@
IndexComp = function(market, price, vol = NULL, weighting = "market", weighting.all = "market", IC = "AIC", EvalSeq = c("Sequential", "AllTogether"), optimum = c("local", "global"), start.const = 1, steps = 1, fixed.value = NULL, base.value = 1000, derivation.period = 1, derivation.period.ic = 3,
days.line) {

if (class(price)[1] != "xts" | class(market)[1] != "xts") {
stop("The data for 'price' and 'market' have to be in the format 'xts'. Please check the R library 'xts' to convert the data.")
}
if (class(vol)[1] != "xts" & is.null(vol) == FALSE) {
stop("The data for 'vol' have to be in the format 'xts'. Please check the R library 'xts' to convert the data.")
}
if ((weighting != "market" & weighting != "volume") | (weighting.all != "market" & weighting.all != "volume")) {
stop("The weighting scheme has to be either 'market' or 'volume'. Please chose either of the two options.")
}
if ((EvalSeq != "Sequential" & EvalSeq != "AllTogether")) {
stop("The evaluation scheme 'EvalSeq' has to be either 'Sequential' or 'AllTogether'. Please chose either of the two options.")
}
if ((optimum != "local" & optimum != "global")) {
stop("The optimal point 'optimum' has to be either 'local' or 'global'. Please chose either of the two options.")
}
if ((IC != "AIC" & IC != "GCV" & IC != "GFCV" & IC != "SH" & IC != "Cp" & IC != "FPE")) {
stop("The Information Criterion 'IC' has to be either 'AIC', 'GCV', 'GFCV', 'SH', 'Cp' or 'FPE'. Please chose either of the options.")
}
if ((weighting == "volume" | weighting.all == "volume") & is.null(vol)) {
stop("When weighting by trading volume is chosen, a data entry for volume is required.")
}
if (length(days.line) < derivation.period.ic*2) {
stop(paste("The number of periods to select the number of constituents for is not long enough. ", derivation.period.ic*2, " month of data are required for the derivation. Please provide a longer dataset or decrease the number of month over which the number of constituents shall be derived.", sep = ""))
}
index_periods = max(floor(derivation.period.ic / derivation.period), 1)
numb_aic1 = (length(days.line) - (derivation.period)) / derivation.period.ic
if ((numb_aic1%%1 == 0) == TRUE){
numb_aic = numb_aic1 - 1
} else {
numb_aic = floor(numb_aic1)
}

index_comp_numb = seq(start.const, dim(price)[[2]], steps)
aic_matrix = matrix(NA, nrow = numb_aic, ncol = length(index_comp_numb))
aic_compare = matrix(NA, nrow = numb_aic, ncol = length(index_comp_numb))
max_coin_numb = c()
crix = crix_all = crix_all_comp = c()
plot_diff_values = rep(list(list()), numb_aic)
cryptos_available = list()
weights_list = list()
weights_list2 = list()

### start calculation index
for (per in 1:numb_aic){
print(paste(per, " / ", numb_aic, sep = ""))

### in case no optimization is wished for, just a fixed value index
if (is.null(fixed.value)) {

### days to alter the index members for choice of optimal settings
current_lines = days.line[seq((1 + derivation.period.ic *
(per - 1)), (derivation.period.ic * per + (derivation.period + 1)),
derivation.period)] + 1
begin_line = current_lines[2]
### total market index
index_t_v_all = index.comp(market = market, price = price, vol = vol, weighting = weighting.all, index.const = "all", base.value = base.value,
index.periods = index_periods, order.derive = TRUE, current.lines.func = current_lines,
begin.line.func = begin_line, comp1 = FALSE, comp = TRUE, per = per, numb.aic = numb_aic,
crix = crix, crix.all = crix_all, crix.all.comp = crix_all_comp)
max_coin_numb[per] = max(sapply(index_t_v_all[[2]], length))

if (EvalSeq == "AllTogether") {
index_t_v_numb = index.comp(market = market, price = price, vol = vol, weighting = weighting, index.const = index_comp_numb[1], base.value = base.value,
index.periods = index_periods, order.derive = TRUE, current.lines.func = current_lines,
begin.line.func = begin_line, comp1 = FALSE, comp = TRUE, per = per, numb.aic = numb_aic,
crix = crix, crix.all = crix_all, crix.all.comp = crix_all_comp)
}

### indices with different numbers of constituents
for (per1 in 1:(length(index_comp_numb)-1)){
if (EvalSeq == "Sequential") {
index_t_v_numb = index.comp(market = market, price = price, vol = vol, weighting = weighting, index.const = index_comp_numb[per1], base.value = base.value,
index.periods = index_periods, order.derive = TRUE, current.lines.func = current_lines,
begin.line.func = begin_line, comp1 = FALSE, comp = TRUE, per = per, numb.aic = numb_aic,
crix = crix, crix.all = crix_all, crix.all.comp = crix_all_comp)
}

if (is.null(index_t_v_numb)) {break}
d = c()
p = c()
for (l in 1:length(index_t_v_numb[[2]])) {
if (l == 1) {
for (k in 1:length(index_t_v_numb[[2]])) {
if (EvalSeq == "Sequential") {
p[k] = length(which(!is.na(index_t_v_numb[[2]][[k]][(index_comp_numb[per1] + 1):index_comp_numb[per1 + 1]]) == TRUE))
} else if (EvalSeq == "AllTogether") {
p[k] = length(which(!is.na(index_t_v_numb[[2]][[k]][(index_comp_numb[1] + 1):index_comp_numb[per1 + 1]]) == TRUE))
}
}
}
if (EvalSeq == "AllTogether" && any(p != per1*steps)) {break}
if (EvalSeq == "Sequential") {
a = price[paste(current_lines[l+1]-1, "::", current_lines[l+2] - 1, sep = ""), index_t_v_numb[[2]][[l]][(index_comp_numb[per1] + 1):index_comp_numb[per1 + 1]]]
} else if (EvalSeq == "AllTogether") {
a = price[paste(current_lines[l+1]-1, "::", current_lines[l+2] - 1, sep = ""), index_t_v_numb[[2]][[l]][(index_comp_numb[1] + 1):index_comp_numb[per1 + 1]]]
}

a[a == 0] = NA
a = na.locf(a, na.rm = FALSE)
a = na.locf(a, fromLast = TRUE)
b = diff(log(a))
# this part is only relevant for sequential
if (dim(b)[[2]] < max(p)) {
while(dim(b)[[2]] < max(p)) {
b = cbind(b, 0)
}
}
#
colnames(b) = 1:dim(b)[[2]]
d = rbind(d,b[-1,])
}
if (EvalSeq == "AllTogether" && any(p != per1*steps)) {break}
if (per1 == 1) {
plot_diff_first = diff(log(c(base.value, index_t_v_all[[1]]))) - diff(log(c(base.value, index_t_v_numb[[1]])))
}
plot_diff = diff(log(c(base.value, index_t_v_all[[1]]))) - diff(log(c(base.value, index_t_v_numb[[1]])))
data_x = d
erg = lm(plot_diff ~ data_x - 1)
plot_diff_values[[per]][[per1]] = plot_diff

### evaluation of current index with an IC method
aic_compare[per, per1] = IndexEval(plot.diff = erg$residuals, index.numb = length(erg$coefficients), IC = IC, plot.diff.first = plot_diff_first)
aic_matrix[per, per1] = IndexEval(plot.diff = plot_diff, index.numb = 0, IC = IC, plot.diff.first = plot_diff_first)

if (optimum == "local" && EvalSeq == "Sequential") {
# if (per1 >= 2){
if (aic_matrix[per, per1] <= aic_compare[per, per1]){
break
}
# }
} else if (optimum == "local" && EvalSeq == "AllTogether") {
if (per1 >= 2){
if (aic_compare[per, per1-1] <= aic_compare[per, per1]){
break
}
} else if (per1 == 1) {
if (aic_matrix[per, per1] <= aic_compare[per, per1]){
break
}
}
}
}

### choice of optimal index members
if (optimum == "local" && EvalSeq == "Sequential") {
if (per1 > 1) {
index_members = index_comp_numb[per1 - 1]
} else if (per1 == 1) {
index_members = index_comp_numb[per1]
}
} else if (optimum == "local" && EvalSeq == "AllTogether") {
index_members = index_comp_numb[per1]
} else if (optimum == "global" && EvalSeq == "Sequential") { # works for Sequential and AllTogether
index_members = which.min(aic_compare[per,]) * steps
} else if (optimum == "global" && EvalSeq == "AllTogether") { # works for Sequential and AllTogether
index_members = which.min(c(aic_matrix[per, 1], aic_compare[per,])) * steps
}

### end if which controls fixed_value = NULL
} else {
index_members = fixed.value
}

### days to alter the index members for application of optimal settings
current_lines1 = days.line[seq((1 + derivation.period.ic * (per)),
(derivation.period.ic * (per + 1) + (derivation.period + 1)),
derivation.period)] + 1
begin_line1 = current_lines1[2]
### calculation of index under the chosen settings, means the chosen number of constituents
crix1 = index.comp(market = market, price = price, vol = vol, weighting = weighting, index.const = index_members, base.value = base.value,
index.periods = index_periods, order.derive = TRUE, current.lines.func = current_lines1,
begin.line.func = begin_line1, comp1 = TRUE, comp = TRUE, per = per, numb.aic = numb_aic,
crix = crix, crix.all = crix_all, crix.all.comp = crix_all_comp)

while (is.null(crix1)){
index_members = index_members - 1
crix1 = index.comp(market = market, price = price, vol = vol, weighting = weighting, index.const = index_members, base.value = base.value,
index.periods = index_periods, order.derive = TRUE, current.lines.func = current_lines1,
begin.line.func = begin_line1, comp1 = TRUE, comp = TRUE, per = per, numb.aic = numb_aic,
crix = crix, crix.all = crix_all, crix.all.comp = crix_all_comp)
}
crix2 = crix1[[1]]
weights_list[[per]] = crix1[[4]]
weights_list2[[per]] = crix1[[5]]
### total market index rebased at the total market index
crix_all2 = index.comp(market = market, price = price, vol = vol, weighting = weighting.all, index.const = "all", base.value = base.value,
index.periods = index_periods, order.derive = TRUE, current.lines.func = current_lines1,
begin.line.func = begin_line1, comp1 = TRUE, comp = FALSE, per = per, numb.aic = numb_aic,
crix = crix, crix.all = crix_all, crix.all.comp = crix_all_comp)
cryptos_available[[per]] = crix_all2[[2]]

crix_all1 = crix_all2[[1]]
### total market index rebased at the index
crix_all4 = index.comp(market = market, price = price, vol = vol, weighting = weighting.all, index.const = "all", base.value = base.value,
index.periods = index_periods, order.derive = TRUE, current.lines.func = current_lines1,
begin.line.func = begin_line1, comp1 = TRUE, comp = TRUE, per = per, numb.aic = numb_aic,
crix = crix, crix.all = crix_all, crix.all.comp = crix_all_comp)
crix_all3 = crix_all4[[1]]
if (per == 1){
crix = do.call(cbind,list(crix2))
crix_all = do.call(cbind,list(crix_all1))
crix_all_comp = do.call(cbind,list(crix_all3))
} else {
crix = rbind(crix, do.call(cbind, list(crix2)))
crix_all = rbind(crix_all, do.call(cbind, list(crix_all1)))
crix_all_comp = rbind(crix_all_comp, do.call(cbind, list(crix_all3)))
}
}

### output
list(crix, crix_all, crix_all_comp, cryptos_available, weights_list)
}




0 comments on commit 5942563

Please sign in to comment.