1
$\begingroup$

What I am looking to do is:

for a given time-series $P_t$ (which will be constructed from different timeseries itself):

$P_t$ = $\beta_1$$I_t^1$+$\beta_2$$I_t^2$+$\beta_3$$I_t^3$ $\qquad$ ($I_t^i$ are $i$ number of time-series)

I want to

$min$$\sum_t^T|$$P_t$-$\bar{P}$| where $\bar{P}$ = 1 (centered around 1)

esentially choosing the $\beta$s such that |$P_t$-$\bar{P}$| is minimized over [ t,T ].

$\endgroup$
5
  • $\begingroup$ Could you show us what you have tried so far and where the exact problem is? $\endgroup$
    – vonjd
    May 31, 2018 at 16:58
  • $\begingroup$ Are you sure you want to minimise the differences? Or rather the absolute differences? $\endgroup$ Jun 1, 2018 at 11:48
  • $\begingroup$ :+1: thanks Enrico! that is exactly what I meant $\endgroup$
    – MaxyD
    Jun 1, 2018 at 14:35
  • 1
    $\begingroup$ Never answer an "or-question" with "yes" ;-) $\endgroup$
    – vonjd
    Jun 7, 2018 at 9:06
  • $\begingroup$ Vonjd, I am sorry you couldn’t gather from context that I indeed meant to minimize the absolute differences (also changed it in the initial question) $\endgroup$
    – MaxyD
    Jun 10, 2018 at 9:24

2 Answers 2

3
$\begingroup$

A simple, though somewhat inflexible, way would be to regress $\bar{P}$ on the $I$ series only (no constant). This will minimise squared differences instead of absolute ones, though.

R example; I start with creating random data:

nobs <- 250  ## length of series
ns <- 3      ## number of I series

P <- c(1, cumprod(1 + rnorm(nobs, sd = 0.01)))
M <- sum(range(P))/2  ## midpoint of range
I <- array(rnorm((nobs)*ns, sd = 0.01),
           dim = c(nobs, ns))
I <- apply(I, 2, function(x) cumprod(1+x))
I <- rbind(1, I)

plot(P, ylim = range(P, I), type = "l",
     col = "darkgreen", lwd = 2)
abline(h = M)
for (i in 1:ns)
    lines(I[,i], col = grey(0.7))

## regression
res1 <- lm(rep(M, nrow(I)) ~ -1 + I)
lines(I %*% coef(res1),
      col = "blue", lwd = 2,
      type = "l")

An alternative way would be to use a generic solver. Here is an example with Differential Evolution, as implemented in the R package NMOF, which I maintain.

## Differential Evolution
library("NMOF")
diff_mean <- function(b, M, I)
    sum(abs(M - I %*% b))

res2 <- DEopt(diff_mean,
              list(min = rep(-1, ns),
                   max = rep(1, ns)),
              M = M, I = I)

lines(I %*% res2$xbest, 
      col = "red", lwd = 2)

The advantage of such a solver is that it is much more flexible: you may use another function to measure the similarity of the series, or add constraints.

$\endgroup$
7
  • $\begingroup$ Didn't know the package, thank you for pointing it out. $\endgroup$
    – vonjd
    Jun 7, 2018 at 9:05
  • $\begingroup$ I just changed the question slightly... It should be enough to make $\bar{P}$ a constant. However, I am unsure how to apply DEopt for a dataframe (of multiple vectors) in order to extract my betas. $\endgroup$
    – MaxyD
    Jun 11, 2018 at 15:32
  • $\begingroup$ It is unfortunate that you changed your question, as now my code example does not match it any more. But anyway: what do you mean by multiple vectors? In the example, I is already a matrix; simply overwrite M with your constant series. $\endgroup$ Jun 12, 2018 at 9:43
  • $\begingroup$ I did get the DEopt working now. However I am getting more than one solution for xbest across multiple runs even though I do think there should be one definitive solution. I already did change the min&max values. $\endgroup$
    – MaxyD
    Jun 14, 2018 at 11:33
  • $\begingroup$ DE is a stochastic method, so its solutions are, in a sense, random. However, with more iterations, this randomness should decrease and eventually disappear. So, try with an increased number of steps (nG in DEopt). See also the discussion in section 3 of ssrn.com/abstract=1140655 $\endgroup$ Jun 15, 2018 at 9:49
0
$\begingroup$

I is a t x i matrix. Each vector in I is weighted by a beta each such that diff_mean is minimized. I will center the process around 1 (M=1) and square the differences to "punish" higher deviations (and prevent netting of errors) from M:

    #Optimization
library("NMOF")
ns=dim(df)[2]
M=1
diff_mean <- function(b, M, df)
  sum((10000*(M-(df%*%b)))^2)
res <- DEopt(diff_mean,
             list(nG = 100000,
                  min = rep(-100, ns),
                  max = rep(100, ns)),
             M = M, df = df)

output=res$xbest
solution=output/output[1]

Bingo!

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.