Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 5942563
Showing
30 changed files
with
1,496 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) | ||
} | ||
|
||
|
||
|
||
|
Oops, something went wrong.