# Help Bruno 03-09-2021 # Own thoughts: Why not use k-means clustering to determine portfolio size. library(tidyverse) library(lubridate) df = readxl::read_xlsx(choose.files()) df = df %>% select(Px, Rule, `Stop Trigger`) test = df[, 1] test2 = test %>% mutate(Rule = NaN, Stop = NaN) test2[1, 2] = 1 test2[1, 3] = test2[1, 1] test2 = data.frame(Px = rnorm(2500, 100, 15), Cash = rnorm(2500, 100, 2)) temp = data.frame(test2$Px, test2$Cash) Rets = (temp[-1, ]/temp[-nrow(temp), ])-1 Brunos_rule = function(Px, Cash, start_rule, Bear, Bull){ temp = data.frame(Px, Cash) Rets = (temp[-1, ]/temp[-nrow(temp), ])-1 df = data.frame(Px) %>% mutate(Rule = NaN, Stop = NaN) df$Rule = start_rule df$Stop = df[1, 1] for(x in 2:nrow(df)){ if(df$Rule[x-1] == 1){ df$Rule[x] = if_else(df$Px[x] <= df$Stop[x-1]*(1+Bear), 0, df$Rule[x-1]) df$Stop[x] = if_else(df$Rule[x] != df$Rule[x-1], df$Px[x], max(df$Stop[x-1], df$Px[x])) } else{ df$Rule[x] = if_else(df$Px[x] > df$Stop[x-1]*(1+Bull), 1, df$Rule[x-1]) df$Stop[x] = if_else(df$Rule[x] != df$Rule[x-1], df$Px[x], min(df$Stop[x-1], df$Px[x])) } } Ans = if_else(df$Rule[-1] == 1, Rets$Px, Rets$Cash) return(Ans) } library(tictoc) tic() Brunos_rule(test2$Px, test2$Cash, 1, -0.05, 0.05) toc() bears = seq(-0.2, -0.05, 0.025) bulls = seq(0.05, 0.2, 0.025) combinations = as.data.frame(t(expand.grid(bears, bulls))) names(combinations) = paste0("Bear", rep(bears, 7), "/Bulls", rep(bulls, each = 7)) results = map_dfc(combinations, function(x){ ans = Brunos_rule(test2$Px, test2$Cash, 1, x[1], x[2]) }) example = results %>% mutate(Date = ymd("2000-01-01") + 1:2499, .before = 1) %>% gather(key = "iteration", value = "Returns", -1) ggplot(example, aes(x = Date, y = Returns, colour = iteration))+ geom_line()+ guides(color = "none")